[Bug tree-optimization/64601] Missed PRE on std::vector move assignment

glisse at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sat Jan 17 13:04:00 GMT 2015


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64601

Marc Glisse <glisse at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #9 from Marc Glisse <glisse at gcc dot gnu.org> ---
(In reply to Marc Glisse from comment #8)
> The transformation is triggered by dereferences, and compares the types of
> objects, not pointers, so it isn't obvious that the issues you were
> describing apply to it.

It looks like they still do apply. I was just lucky that the folding was done
in an order where nothing bad happened in the tests. Your example

 int *p = &((struct A *)&b)->i;
 *p = 0;

becomes *(int*)&b=0, which is fine. But in a different order, what I wanted
could give: (*(struct A *)&b).i=0 (access b as an A) which would be wrong for
TBAA. Although I don't see the point of writing that kind of code instead of:

 int *p = (int*)((char*)&b + offsetof(A, i));

So basically, a struct A * as an argument of a function doesn't carry any more
information than a void* :-( It is only if we can see an actual VAR_DECL or
similar that we may be able to reconstruct the access, but then we don't often
need to...

It is strange that [basic.lval] (or 6.5 Expressions in C99) is so lenient.
[class.mem] is a little bit more restrictive but still not much.

There is a little bit of divergence on function f below:

void f(struct A *a){ *&a->i=0; }
void g(struct A *a){ int*p=&a->i;*p=0; }
void h(struct A *a){ a->i=0; }

gcc, intel and oracle handle f like h, while clang is more conservative and
handles it like g (I actually tested on a function taking 2 std::pair<int,int>
by reference if a.first and b.second could alias).

Ok, I am starting to understand vaguely what C/C++ are saying about type
aliasing. I am horrified (this is a huge abstraction penalty), but at least I
am less confused. I'll close this PR as INVALID (the trick about the same
clobbering value is already in several other PRs, no need to keep this one as
well) (if you want to remove some current unsafe transformations, it would
probably be less confusing to open a different PR).

I wonder how feasible it would be to define a dialect where any non-zero struct
A* really points to a struct A... (we already have void* and char* for
"untyped" pointers)



More information about the Gcc-bugs mailing list