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.

Reply via email to