Bug 57958

Summary: Incorrect code generation in lambda with argument of type reference to template class
Product: gcc Reporter: Tudor Bosman <tudorb>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: dtemirbulatov, dushistov
Priority: P2 Keywords: c++-lambda, wrong-code
Version: 4.7.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: 4.8.1, 4.9.0 Last reconfirmed: 2013-07-23 00:00:00
Bug Depends on:    
Bug Blocks: 54367    
Attachments: Source file that exhibits broken behavior
Source file that exhibits broken behavior

Description Tudor Bosman 2013-07-23 01:54:40 UTC
Created attachment 30538 [details]
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.
Comment 1 Tudor Bosman 2013-07-23 01:57:10 UTC
Created attachment 30539 [details]
Source file that exhibits broken behavior
Comment 2 Tudor Bosman 2013-07-23 02:09:28 UTC
g++ -v output (ignore the weird paths):

Using built-in specs.
COLLECT_GCC=l/f/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/bin/g++
COLLECT_LTO_WRAPPER=/mnt/gvfs/third-party/1ebd27fa7983fc50f525eb890ae74ebbb9336a72/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/bin/../libexec/gcc/x86_64-redhat-linux-gnu/4.7.1/lto-wrapper
Target: x86_64-redhat-linux-gnu
Configured with: /home/engshare/third-party/src/gcc/gcc-4.7.1/gcc-4.7.1/configure --build=x86_64-redhat-linux-gnu --host=x86_64-redhat-linux-gnu --target=x86_64-redhat-linux-gnu --prefix=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc --exec-prefix=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc --bindir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/bin --sbindir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/sbin --sysconfdir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/etc --datadir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/share --includedir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/include --libdir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/lib --libexecdir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/libexec --localstatedir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/var --sharedstatedir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/com --mandir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/share/man --infodir=/home/engshare/third-party/centos5.2-native/gcc/gcc-4.7.1/cc6c9dc/share/info --with-gmp=/home/engshare/third-party/centos5.2-native/gmp/gmp-5.0.1/da39a3e --with-mpfr=/home/engshare/third-party/centos5.2-native/mpfr/mpfr-3.0.0/c68f0aa --with-mpc=/home/engshare/third-party/centos5.2-native/mpc/mpc-0.8.2/18cfc0e --with-ppl=/home/engshare/third-party/centos5.2-native/ppl/ppl-0.10/c68f0aa --with-cloog=/home/engshare/third-party/centos5.2-native/cloog/cloog-0.15.7/ab7be4d --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,fortran --disable-libgcj --enable-linker-build-id --with-gnu-as --with-gnu-ld --with-host-libstdcxx='-L/usr/lib/gcc/x86_64-redhat-linux/4.1.2 -lstdc++' --disable-multilib --enable-libstdcxx-time
Thread model: posix
gcc version 4.7.1 (GCC)
Comment 3 dinar 2014-04-23 20:11:22 UTC
fixed on trunk with revision 209721
Comment 4 dinar 2014-04-24 18:52:01 UTC
Author: dinar
Date: Thu Apr 24 18:51:29 2014
New Revision: 209757

URL: http://gcc.gnu.org/viewcvs?rev=209757&root=gcc&view=rev
Log:
add recored to gcc/testsuite/ChangeLog for PR c++/57958

Modified:
    trunk/MAINTAINERS
    trunk/gcc/testsuite/ChangeLog