https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635
--- Comment #41 from Jason Merrill <jason at gcc dot gnu.org> --- (In reply to Jason Merrill from comment #38) > This is better: Complete revised testcase: #ifdef USE_STD #include <optional> using std::optional; #else using size_t = decltype(sizeof(1)); inline void *operator new (size_t, void *p) { return p; } template<typename T> struct optional { optional () : m_dummy (), live (false) {} void emplace () { new (&m_item) T (); live = true; } ~optional () { if (live) m_item.~T (); } union { struct {} m_dummy; T m_item; }; bool live; }; #endif extern int get (); extern void set (int); struct A { A () : m (get ()) {} ~A () { set (m); } int m; }; struct B { B (); ~B (); }; void func () { optional<A> maybe_a; optional<B> maybe_b; maybe_a.emplace (); maybe_b.emplace (); }