The following code segfaults at runtime when we call fun2. Compiled with "g++-4.7 -std=c++11 -o main main.cpp" Code: struct Foo { void doit() { } }; template<typename T> void oops(Foo &foo, const T &) { auto fun = [&] () mutable { foo.doit(); }; auto fun2 = [=]() { fun(); }; fun2(); } int main() { Foo foo; oops(foo, 1); } Note: if we make it non-templated function, we get a compiler error which correctly detects the mutable/non-mutable disparity. main.cpp:11:13: error: passing ‘const oops(Foo&, const int&)::<lambda()>’ as ‘this’ argument of ‘oops(Foo&, const int&)::<lambda()>’ discards qualifiers [-fpermissive]
I can reproduce this on GCC 4.8 (rev 185382], and g++ 4.6.3. Adding -O makes the issue go away (as the whole program is optimized to "return 0;"). From the assembler dump the segv appears to happen when the compiler is generating a "this" pointer for the inner lambda: void oops<int>(Foo&, int const&)::{lambda()#1}::_FUN(): pushq %rbp movq %rsp, %rbp >>> movl $0, %edi call void oops<int>(Foo&, int const&)::{lambda()#1}::operator()() popq %rbp ret [this output can also be seen at http://url.godbolt.org/mdjvf ]
Confirmed, I think the code should be rejected.
Author: jason Date: Sun Mar 17 02:35:18 2013 New Revision: 196729 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196729 Log: PR c++/56447 PR c++/55532 * pt.c (instantiate_class_template_1): Instantiate lambda capture list here. (tsubst_copy_and_build): Not here. Added: trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv8.C trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-mutable2.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c
Fixed for 4.8.1.