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

--- Comment #30 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Andrew Downing from comment #29)
> So I think this sort of equivalent example in C shows what's going wrong in
> the C++ example. https://godbolt.org/z/ZMz4Cp
> 
> gcc knows that if the object mem points to is modified inside pun() its
> effective type will change to the type of the value that is assigned because
> the object mem points to has no declared type. If the argument to pun has a
> declared type, the code doesn't work, like in the c++ example.

As said earlier the issue is that pun() is completely elided and GCC
doesn't see anything else than a simple pointer cast of its argument
at the caller side (after inlining).

> So for this c++ example https://godbolt.org/z/NeAJ5d could a solution be for
> gcc to treat placement new as if it were a modifying access and as if it's
> parameter had no declared type. So it would change the effective type of d
> in f1 to uint64_t, or at least insert IL instructions to simulate that?

The main issue with placement new is that it is not necessary to use
placement new!  In C++, for POD (or some bigger set of) types you can
simply start using storage in a new type, no need for a placement new.
This is why GCC treats _every_ _store_ as possibly altering the dynamic
type of the stored to object.  So everything is fine - until all stores
[possibly altering the dynamic type] are optimized away.

So with your argument we'd have to insert extra magic instructions at
_every_ store and we'd have to keep those (while we could elide the
actual stores).  While in the high-level IL this might be feasible
things get tricky in RTL land where we'd have the choice to either
not do TBAA anymore or also represent these "fake" memory state
affecting instructions.

In the end I'd rather not venture there but indeed that removing of
stores has proven an issue in the past (PR93946 for example).

Reply via email to