https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88164
Bug ID: 88164 Summary: Copy initialization of function argument not performed inside lambda when the argument is a constexpr block scope variable. Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- In the code bellow the copy constructor of "a" should be called: struct A { int x=12; constexpr A(){} A(const A& x); }; int f(A); // This function should not compile // And the generated code does not call the copy constructor of A int test() { constexpr A a{}; auto lambda = []{ return f(a); // Unexpected: does not call the copy constructor, // should not compile: a should be explicitly captured }; return lambda(); } The the call to the copy constructor does not appear in the generated assembly: test(): subq $24, %rsp leaq 12(%rsp), %rdi movl $12, 12(%rsp) call f(A) addq $24, %rsp ret While without the lambda: int test_expect_assembly(){ constexpr A a{}; return f(a); } the copy constructor is called: test_expect_assembly(): subq $24, %rsp leaq 8(%rsp), %rsi leaq 12(%rsp), %rdi movl $12, 8(%rsp) call A::A(A const&) leaq 12(%rsp), %rdi call f(A) addq $24, %rsp ret This unexpected copy constructor elision only happens for function arguments construction. The code below produces the expected assembly and GCC requires the explicit capture of "a": int test_copy_initialization() { constexpr A a{}; auto lambda = [&a]{ // a must be captured A b=a; return a.x; }; return lambda(); } Moreover there is a related bug when the variable has global scope, the copy constructor is called, nevertheless GCC should not implicitly captures the variable because the variable is ODR used. The capture should be explicit, the code below should not compile: constexpr A n_a{}; int test_ns() { auto lambda = []{ return f(n_a);// call the copy constructor so odr use n_a // Unexpected: n_a should be explictly captured }; return lambda(); }