http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57958
Bug ID: 57958 Summary: Incorrect code generation in lambda with argument of type reference to template class Product: gcc Version: 4.7.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tudorb at fb dot com Created attachment 30538 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30538&action=edit Source file that exhibits broken behavior gcc (tested in 4.6.2 and 4.7.1) generates incorrect code for the "fn" lambda, resulting in an extraneous destructor call. Compiler with -O0 (this is reduced from a more complex example involving shared_ptr which exhibited the bug with -O3 as well). Source attached. The bug remains without #include <cstdio> and without the call to printf, which are there just for exposition. x86_64 disassembly (from gcc 4.7.1): Dump of assembler code for function operator()(Foo<Data> const&) const: 0x00000000004006ec <+0>: push %rbp 0x00000000004006ed <+1>: mov %rsp,%rbp 0x00000000004006f0 <+4>: sub $0x30,%rsp 0x00000000004006f4 <+8>: mov %rdi,-0x18(%rbp) 0x00000000004006f8 <+12>: mov %rsi,-0x20(%rbp) 0x00000000004006fc <+16>: mov %rdx,-0x28(%rbp) => 0x0000000000400700 <+20>: mov -0x28(%rbp),%rdx 0x0000000000400704 <+24>: lea -0x1(%rbp),%rax 0x0000000000400708 <+28>: mov %rdx,%rsi 0x000000000040070b <+31>: mov %rax,%rdi 0x000000000040070e <+34>: callq 0x400794 <Foo<Data>::Foo(Foo<Data> const&)> 0x0000000000400713 <+39>: lea -0x1(%rbp),%rax 0x0000000000400717 <+43>: mov %rax,%rdi 0x000000000040071a <+46>: callq 0x4007b2 <Foo<Data>::~Foo()> 0x000000000040071f <+51>: leaveq 0x0000000000400720 <+52>: retq End of assembler dump. The bug only happens if Foo is a template. If Foo is not a template, the code is correct: Dump of assembler code for function operator()(Foo const&) const: 0x00000000004006ec <+0>: push %rbp 0x00000000004006ed <+1>: mov %rsp,%rbp 0x00000000004006f0 <+4>: sub $0x20,%rsp 0x00000000004006f4 <+8>: mov %rdi,-0x8(%rbp) 0x00000000004006f8 <+12>: mov %rsi,-0x10(%rbp) 0x00000000004006fc <+16>: mov %rdx,-0x18(%rbp) => 0x0000000000400700 <+20>: mov -0x18(%rbp),%rdx 0x0000000000400704 <+24>: mov -0x8(%rbp),%rax 0x0000000000400708 <+28>: mov %rdx,%rsi 0x000000000040070b <+31>: mov %rax,%rdi 0x000000000040070e <+34>: callq 0x4007a6 <Foo::Foo(Foo const&)> 0x0000000000400713 <+39>: mov -0x8(%rbp),%rax 0x0000000000400717 <+43>: leaveq 0x0000000000400718 <+44>: retq End of assembler dump.