This is the mail archive of the gcc-bugs@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]

[Bug target/79671] [7 Regression] mapnik miscompilation on armv7hl since r235622


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

--- Comment #68 from Michael Matz <matz at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #65)
> It accesses b, but it doesn't access the object stored in b's char[N] member
> via placement new.

Okay, let's go with this.  So the copying of the union is then defined
(as a memcpy equivalent).  Then there's still the question if the following
sequences are valid:

// assume T1 and T2 are some types and new is trivial placement new
union U {T1 a; char b[sizeof T2];} x,y;
new (x.b) T2();              // 1
y = x;                       // 2
T2 t;
memcpy(&t, y.b, sizeof T2);  // 3
t;                           // 4
y.a;                         // 5

We have said that (2) is valid, obviously (3) in isolation is valid as well,
but it influences the validity of (4).  (5) is invalid as it's not the
active member of the union y (which is instead b).

(4) is valid if y.b contained a T2, which is only the case if (2) transferred
the dynamic type from x.b _and_ (1) was valid to start with and dynamically
typed x.b to be of type T2.

So, it all boils down to if (1) is valid and types x.b to T2, even though it
has a different declared type.  For C we say it's not, because char[] is
asymmetric: you can access all types via a char*, but you can't change the
dynamic type of a declared char array to contain arbitrary other things (well,
the ME memory model does cater for this and makes it valid, even though it's
invalid in C).

I guess you're arguing that (1) is valid in C++ and that then due to 3.9/3
and 12.8/29 also (2) and (4) are.  I guess it can be defined to be so, but
I wonder what the type of 'x' is after (1)?  It can't be T2, because clearly
x.b is valid even if T2 doesn't contain a member 'b'.  So it must stay a union,
but in order to transfer the type T2 in (2) it must also contain T2, so is it
the type 'union {T1 a; char b[sizeof T2]; T2 <unnamed>;}' then (conceptually)?
Messy :)

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