https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109945
--- Comment #30 from Arthur O'Dwyer <arthur.j.odwyer at gmail dot com> --- I think I understand jwakely's argument at this point, and it's consistent and teachable. https://eel.is/c++draft/class.temporary#3.sentence-1 says: > When an object of class type X is passed to or returned from a function, if X > has at least one eligible copy or move constructor, each such constructor is > trivial, and the destructor of X is either trivial or deleted, > implementations are permitted to create a temporary object to hold the > function parameter or result object. It says "implementations are permitted"; this means that an implementation (GCC) can create such a temporary *whenever* permitted, and then re-optimize the codegen under the As-If Rule to eliminate the trivial move. That still ends the lifetime of the original object. `global` points to that original object, which is out-of-lifetime, so dereferencing `global` is UB. (Yes, even if its value happens to _compare_ equal to some other pointer that's still in-lifetime: this is "pointer provenance" as I see and understand it.) So, in order for me to call this `Widget` example a "bug," I'd have to find a `Widget` that doesn't meet [class.temporary]/3's conditions. That is, it would have to be a type that does NOT have eligible copy or move constructors; or has at least one NON-trivial eligible copy or move constructor; or has a NON-deleted NON-trivial destructor. Then the implementation (GCC) would NOT be permitted to create a temporary and the argument wouldn't hold anymore. And indeed, I cannot find such a `Widget`! Every example I've tried so far matches jwakely's explanation. For example: https://godbolt.org/z/rT6Mv537e struct X { X(); X(X&, int=0); X(const X&) = default; int i = 1; int a[4]; }; This `X` has a non-trivial eligible copy constructor, so it doesn't meet [class.temporary]/3's conditions, and GCC treats it the same at -O1 and -O2. If you delete the characters `=0`, then that constructor is no longer a copy constructor, so `X` DOES meet [class.temporary]/3 and GCC treats it differently at -O1 and -O2 (which is fine because now the program has UB, as jwakely says). GCC is not misbehaving in this example. Here's another example (still matching jwakely's argument perfectly: GCC is not misbehaving) -- this one exploits [special]/6 to play with whether the non-trivial copy ctor is "eligible" -- https://godbolt.org/z/PWT85n5xb I'm satisfied with the explanation -- and GCC seems to be implementing it correctly AFAICT -- so I think it would be reasonable to close this bug as INVALID. On the other hand, if anyone wants to argue that the current behavior is technically correct but super confusing to working programmers, I wouldn't argue against them, either. ;)