https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106864
Andrew Pinski <pinskia at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |missed-optimization --- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> --- I think this is just a missed optimization really. Because GCC does the right thing inside the inner most lambda and it is considered as a constexpr there still. But the inner lambda L has a capture still. You can see the missed optimization via: void bad() { constexpr int x = 123; auto Outer = [&] [[gnu::noipa]] () { auto L = [=] [[gnu::noipa]] () { for (int i = 0; i < x; ++i) { asm("":::"memory"); } }; //static_assert(sizeof(L) == 1); // fails asm("":::"memory"); L(); }; Outer(); static_assert(sizeof(Outer) == 1); // fails } And look at the assembly for `bad()::{lambda()#1}::operator()() const` which does the store before calling `bad()::{lambda()#1}::operator()() const::{lambda()#1}::operator()() const` But `bad()::{lambda()#1}::operator()() const::{lambda()#1}::operator()() const` uses 123 always. Even at -O2 and such.