https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101061
--- Comment #12 from rguenther at suse dot de <rguenther at suse dot de> --- On Wed, 16 Jun 2021, alexander.gr...@tu-dresden.de wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101061 > > Alexander Grund <alexander.gr...@tu-dresden.de> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Version|8.4.0 |8.5.0 > Known to fail| |8.3.0, 8.4.0, 8.5.0 > Known to work| |9.1.0 > > --- Comment #10 from Alexander Grund <alexander.gr...@tu-dresden.de> --- > > My suspicion is, that GCC loads the value of slot2 before constructing the > > object > > I have just confirmed that: memsetting the whole region with a magic value > shows exactly that: Where a new value should be created and then returned, > then > the memset-value is returned instead. When the map already has an entry for > the > key (i.e. no new value created) then the existing value (i.e. the correct one) > is returned. > > Question now: Is the in-place construction UB and just happens to "normally" > work or is that an optimizer bug that was fixed or gone latent? And how to > proceed to further narrow this down? I think what can be clearly said is that in-place construction of a union member and then accessing the constructed object via another union member (aka do type punning via unions) is not supported even if the later access has the union visible in the access (because the in-place construction does not). For simple cases if everything is inlined GCC usually plays nice and does what-you-mean in case it can see must-aliases, thus *(int *)x = 1; *(float *)x = 0.f; return *(int *)x; is, even if technically UB, _not_ "miscompiled" ("miscompiled" it would optimize to return 1).