This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to use __attribute__((__may_alias__))


I really appreciate your efforts.

I have a working version, using a union in a way that I think is incorrect, but this is the same concept I used last time I fixed one of these issues.

Everything I've tried so far with __attribute__((__may_alias__)) has failed. I'd really like to know how to make that work.

Working code:

union { DAT* pp; std::size_t dummy; } no_strict_alias;
no_strict_alias.pp =foo();
reinterpret_cast<DAT_PTR*>(&no_strict_alias.pp)->bar(x);

Notice that dummy is never used. Notice that the reinterpret_cast is essentially unchanged (from the version that doesn't work). The union is just doing what I would have expected the attribute to do, marking pp as an object for which strict aliasing optimizations should not be used.

The last time I fixed one of these, I didn't try as hard to get the attribute to work before giving up. For very different reasons in the previous case, I also couldn't use a union correctly and in that case there were multiple reinterpret_casts, such that the misused union wasn't involved at all in the read side. (The value was written through a reinterpret_cast to the union and read through an unrelated reinterpret_cast in distant code that was brought together only by compiler inlining.).

Ian Lance Taylor wrote:
When you can't use a union, another option is memcpy.
That's a pretty ugly choice.
The may_alias attribute should be on the type to which things point.  SO
you want something like

typedef DAT __attribute__ ((__may_alias__)) DAT_ALIAS;

and then use DAT_ALIAS*.
I tried that, even though it makes no sense to me (it protects the wrong level of indirection). It didn't work.

The three levels of indirection here:

0) The DAT object: That is always a DAT object, no change in interpretation.

1) pp: That is sometimes a DAT* and sometimes a DAT_PTR. That is the heart of the problem.

2) &pp: That is reinterpreted from a DAT** to a DAT_PTR*

I would think the attribute should apply to the level whose type actually changes, which is level 1 in this case, as in the working union code where I have a DAT* in the union, not a DAT.

In my sample code, foo() is a method that returns a DAT*. bar() is a member function in the class DAT_PTR, not the class DAT.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]