[Bug tree-optimization/101061] tree-vrp misoptimization on skylake+ using union-based aliasing

rguenther at suse dot de gcc-bugzilla@gcc.gnu.org
Wed Jun 16 11:10:12 GMT 2021


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

--- Comment #14 from rguenther at suse dot de <rguenther at suse dot de> ---
On Wed, 16 Jun 2021, alexander.grund@tu-dresden.de wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101061
> 
> --- Comment #13 from Alexander Grund <alexander.grund@tu-dresden.de> ---
> > But what you can see is that the resulting pointer is used for the initialization and not the placement address as literally written in source.
> 
> So I assume it was supposed to be "Y::Y (D_6557, 1);" ?
> 
> > I'm not sure how one can solve this issue with using placement new
> > but are unions not sufficiently restricted so that copy assignment
> > should work (and activate the appropriate union member)?  Thus
> > 
> >   slot->mutable_value = pair<const K, V>(k, v);
> 
> The problem is not the copy, the problem is that the value may contain any kind
> of data, think e.g. a pair of strings. And at the initial point (i.e. first
> emplace) the slot is a casted pointer into uninitialized data. I.e. the above
> would be an assignment into an object which does not exist. And (especially)
> for such non-trivial types this would break.
> 
> I think it will work for trivial types though, although it is UB due to
> lifetime rules: You can't use an object (here: assign to) which has not started
> its lifetime yet.

I see.  I would need to read up what kind of restrictions recent C++
standards place on union members, but in C a store to a non-active
union member makes that active and IIRC for tradidional POD data types
the same should hold true for C++, even w/o requiring an explicit
placement new.

> However e.g. pair has custom copy and regular constructors so I think it will
> run into the issue you mentioned: The ctor will access the object via the
> this-pointer and not via the full union-thing and hence might misoptimise later
> 
> This would mean that in conclusion the use case of putting std::pairs in an
> union and accessing them via aliasing is unsupported by (at least) GCC. Is that
> correct?

Without restricting the set of C++ features used, yes.  Even
accessing the data via union.memb.getX (); would involve a 'this'
pointer and thus break things.  std::pair is probably a special-case
that might work since you use pair.first rather than a method though ;)

You can see this type-punning via unions exception was invented
for C ;)


More information about the Gcc-bugs mailing list