https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90992
--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> --- If we inline the relevant code it reveals that t here are actually additional warning lines that are being suppressed in system headers: using size_t = decltype(sizeof(0)); void* operator new(size_t, void* p) { return p; } struct allocator { template<typename T, typename... Args> void construct(T* p, Args... args) noexcept(noexcept(::new((void*)p) T(args...))) { ::new((void*)p) T(args...); } template<typename T> void destroy(T* p) noexcept(noexcept(p->~T())) { p->~T(); } }; class NotNoexcept { public: NotNoexcept() noexcept(false) {} ~NotNoexcept() noexcept(false) {} }; class Automatic { public: Automatic(int bla) noexcept(false) : Bla(bla) {}; private: int Bla; NotNoexcept Dummy; }; int main() { alignas(Automatic) unsigned char buf[sizeof(Automatic)]; allocator a; a.construct((Automatic*)buf, 42); a.destroy((Automatic*)buf); } 90992.cc: In instantiation of 'void allocator::construct(T*, Args ...) [with T = Automatic; Args = {int}]': 90992.cc:37:34: required from here 90992.cc:8:5: warning: noexcept-expression evaluates to 'false' because of a call to 'void* operator new(size_t, void*)' [-Wnoexcept] 8 | construct(T* p, Args... args) | ^~~~~~~~~ 90992.cc:2:7: warning: but 'void* operator new(size_t, void*)' does not throw; perhaps it should be declared 'noexcept' [-Wnoexcept] 2 | void* operator new(size_t, void* p) { return p; } | ^~~~~~~~ 90992.cc:14:5: warning: noexcept-expression evaluates to 'false' because of a call to 'Automatic::~Automatic()' [-Wnoexcept] 14 | destroy(T* p) | ^~~~~~~ 90992.cc:25:7: warning: but 'Automatic::~Automatic()' does not throw; perhaps it should be declared 'noexcept' [-Wnoexcept] 25 | class Automatic { | ^~~~~~~~~ The first first line is being suppressed, but the second is not. This isn't a front-end regression as it's always done this, but it gets triggered by new changes in libstdc++ since GCC 9.1