https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93246
--- Comment #5 from Richard Biener <rguenth at gcc dot gnu.org> --- Note that the 'using' make it work is another wrong-code issue I think. But clearly somehow the TYPE_TYPELESS_STORAGE handling is responsible here (it works with 'short' padding for example). More reduced: template <typename = void> struct Optional { auto is_present() const { return inner.present; } auto set_present() { if (not is_present()) inner.present = true; } struct InnerType { bool present = false; char padding[1] = {0}; }; using inner_t = InnerType; //InnerType inner = {}; // this works as expected! inner_t inner = {}; // this doesn't! }; template <typename WrappedType> struct Wrapper { auto operator-> () { return value; } WrappedType *value; }; void __attribute__((noipa)) foo(Optional<>& x) {} int main() { Optional<> buf{}; foo(buf); Wrapper<Optional<>> wo = {&buf}; wo->set_present(); auto x = wo->is_present(); if (!x) __builtin_abort (); }