Bug 55532 - Runtime segfault calling mutable lambda wrapped in a non-mutable lambda within a template function
Summary: Runtime segfault calling mutable lambda wrapped in a non-mutable lambda withi...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.2
: P3 normal
Target Milestone: 4.8.1
Assignee: Jason Merrill
URL:
Keywords: accepts-invalid, c++-lambda
Depends on:
Blocks: lambdas
  Show dependency treegraph
 
Reported: 2012-11-29 19:39 UTC by Alexander Kramnik
Modified: 2022-03-11 00:32 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-12-06 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander Kramnik 2012-11-29 19:39:10 UTC
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]
Comment 1 Matt Godbolt 2012-11-29 20:03:47 UTC
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 ]
Comment 2 Jonathan Wakely 2012-12-06 15:54:18 UTC
Confirmed, I think the code should be rejected.
Comment 3 Jason Merrill 2013-03-17 02:35:35 UTC
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
Comment 4 Jason Merrill 2013-03-23 19:21:55 UTC
Fixed for 4.8.1.