https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95349
--- Comment #38 from Andrew Downing <andrew2085 at gmail dot com> --- > int *p; > int x; > if (<condition>) > p = &x; > else > p = malloc (4); > memcpy (p, q, 4); > > there is a single memcpy call and the standard says that both the dynamic > type transfers (from q) and that it does not (to x). I would say just that, that it both does and doesn't transfer the effective type. Meaning that you need to be conservative during optimization and consider p to alias both int and whatever type q is. > Note the C++ standard makes the placement new optional. Do you say that > your example is incorrect with the placement new elided? I'm not sure what you mean about the first part about it being optional. It depends what you mean by elided. I wouldn't expect any code to be generated for it either way, but I would expect the compiler to now consider the object at that address as having a different type regardless. If we pretend for a second that GCC is using pre C++20 rules for memcpy and not messing with the effective/dynamic type for the destination, then isn't this example still not going to work if GCC is treating placement new in this case as doing nothing? In f1 after s1 is called, d is still a double, and u is a pointer to uint64_t, so pointing u at d and accessing *u is still going to be UB right? I would expect d = 3.14159 to still be optimized out, because why would a store to a double affect a load from a uint64_t? I can't see how this could work in every situation unless the compiler keeps track of the type of d changing from double -> uint64_t, so it knows that stores to it when it was a double could affect loads from a uint64_t after it's type changed to uint64_t. In a more complex scenario where placement new was used conditionally with many different types, the compiler would have to consider pointers to any of those types as aliasing d afterwards. I can think of some situations where the compiler would have a very hard time proving that the address of some object didn't make it's way to a placement new somewhere else in the program. This does seem very difficult to do correctly without being very conservative and disabling a lot of optimizations, or having pretty advanced static analysis.