https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80635
--- Comment #15 from Martin Sebor <msebor at gcc dot gnu.org> --- I think the following smaller test case independent of libstdc++ captures the same issue as the bigger test case in comment #4. Again, declaring f() noexcept avoids the warning (but it's not a solution in general). Zero initializing A::i first and then setting it to the result of f() also avoids the warning and seems like more viable solution/workaround until GCC gets smarter about exceptions. $ cat pr80635.C && gcc -O2 -S -Wall pr80635.C void* operator new (__SIZE_TYPE__, void *p) { return p; } int f (); int x; struct A { int i; A (): i (f ()) { } ~A () { x = i; } }; struct B { B (); ~B (); }; template <class T> struct C { C (): t (), b () { } ~C () { if (b) t.~T (); } void f () { new (&t) T (); b = true; } union { T t; char x[sizeof (T)]; }; bool b; }; void g () { C<A> c1; C<B> c2; c1.f (); c2.f (); } pr80635.C: In function ‘void g()’: pr80635.C:9:13: warning: ‘c1.A::i’ may be used uninitialized in this function [-Wmaybe-uninitialized] 9 | ~A () { x = i; } | ~~^~~ pr80635.C:37:8: note: ‘c1.A::i’ was declared here 37 | C<A> c1; | ^~