https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118856
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Oh, the lack of the allocator calls is due to constexpr and those doing nothing at all. I wonder why it isn't being optimized out for the pre- r15-7481 case. And why do the ~allocator calls remain even if they are equally constexpr and do nothing at all. Anyway, here is a full self-contained testcase which shows the lack of proper cleanup nesting: int a, b, c, d; struct A { A () { ++a; ++d; }; ~A () { --a; ++d; }; }; struct B { B (const A & = A {}) { ++b; ++d; }; ~B () { --b; ++d; }; }; struct C { C (const B &, const A & = A {}) { ++c; ++d; throw 42; }; ~C () { --c; ++d; }; int *begin () { return nullptr; }; int *end () { return nullptr; }; }; void foo () { for (auto &i : C { B {} }) ; } int main () { try { foo (); __builtin_abort (); } catch (int x) { if (x != 42 || a || b || c != 1 || d != 7) __builtin_abort (); } } This works with r15-7480 -O2 -std=c++20 and -O2 -std=c++23 and with current trunk with -O2 -std=c++20 but aborts with -O2 -std=c++23.