this is a regression as not happening in 4.6.2 and 4.7.1 I personally think that the template methods SHOULD be declared inline if included in multiple sources… anyhow since it was discussed at length in PR53780 and PR53768 and got attention from developers I promised to reduce and post cat inlT.cc #include <algorithm> template<typename T> struct Foo { virtual int bar(int,int); int k; }; // int ebar(int,int) __attribute__ ((visibility ("default"))); template<typename T> int Foo<T>::bar(int i, int j) { auto ebar = [](int a, int b) { return a+b;}; static int a=i; if (i>0) k = ebar(i,j); if (j>0) k = ebar(j,i); if (i>0) k = ebar(j,i); if (k>0) k = ebar(i,j); return (a==i) ? i : j; } struct A1 { Foo<float> * foo; }; int __attribute__ ((visibility ("default"))) hello1 (int i, int j) { A1 a; return a.foo->bar(i,j);} [vocms123] ~/public/ctest/bugs48 $ cat inlT2.cc #include <algorithm> template<typename T> struct Foo { virtual int bar(int,int); int k; }; // int ebar(int,int) __attribute__ ((visibility ("default"))); template<typename T> int Foo<T>::bar(int i, int j) { auto ebar = [](int a, int b) { return a+b;}; static int a=i; if (i>0) k = ebar(i,j); if (j>0) k = ebar(j,i); if (i>0) k = ebar(j,i); if (k>0) k = ebar(i,j); return (a==i) ? i : j; } struct A2 { Foo<float> * foo; }; int __attribute__ ((visibility ("default"))) hello2 (int i, int j) { A2 a; return a.foo->bar(i,j);} [vocms123] ~/public/ctest/bugs48 $ cat buildInlT c++ -std=gnu++11 -O2 -fvisibility-inlines-hidden -fvisibility=hidden -flto -c inlT.cc -fPIC c++ -std=gnu++11 -O2 -fvisibility-inlines-hidden -fvisibility=hidden -flto -c inlT2.cc -fPIC c++ -std=gnu++11 -O2 -fvisibility-inlines-hidden -fvisibility=hidden -flto -shared inlT.o inlT2.o -fPIC -o inlT.so source buildInlT /afs/cern.ch/user/i/innocent/w3/gcc47slc5/bin/ld: error: inlT2.o: multiple definition of 'Foo<float>::bar(int, int)::{lambda(int, int)#1}::_FUN(int, int)' /afs/cern.ch/user/i/innocent/w3/gcc47slc5/bin/ld: inlT.o: previous definition here /afs/cern.ch/user/i/innocent/w3/gcc47slc5/bin/ld: error: inlT2.o: multiple definition of 'Foo<float>::bar(int, int)::{lambda(int, int)#1}::operator int (*)(int, int)() const' /afs/cern.ch/user/i/innocent/w3/gcc47slc5/bin/ld: inlT.o: previous definition here collect2: error: ld returned 1 exit status also with simpler cat buildInlT0 c++ -std=gnu++11 -O2 -c inlT.cc -fPIC c++ -std=gnu++11 -O2 -c inlT2.cc -fPIC c++ -std=gnu++11 -O2 -shared inlT.o inlT2.o -fPIC -o inlT.so source buildInlT0 /afs/cern.ch/user/i/innocent/w3/gcc47slc5/bin/ld: error: inlT2.o: multiple definition of 'Foo<float>::bar(int, int)::{lambda(int, int)#1}::_FUN(int, int)' /afs/cern.ch/user/i/innocent/w3/gcc47slc5/bin/ld: inlT.o: previous definition here /afs/cern.ch/user/i/innocent/w3/gcc47slc5/bin/ld: error: inlT2.o: multiple definition of 'Foo<float>::bar(int, int)::{lambda(int, int)#1}::operator int (*)(int, int)() const' /afs/cern.ch/user/i/innocent/w3/gcc47slc5/bin/ld: inlT.o: previous definition here c++ -v Using built-in specs. COLLECT_GCC=c++ COLLECT_LTO_WRAPPER=/afs/cern.ch/user/i/innocent/w3/gcc47slc5/libexec/gcc/x86_64-unknown-linux-gnu/4.7.2/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../gcc-4.7/configure --enable-languages=c,c++,fortran --disable-multilib --enable-gold=yes --disable-nls --enable-lto --with-mpc=/afs/cern.ch/cms/slc5_amd64_gcc470/external/gcc/4.7.0 --with-gmp=/afs/cern.ch/cms/slc5_amd64_gcc470/external/gcc/4.7.0 --with-mpfr=/afs/cern.ch/cms/slc5_amd64_gcc470/external/gcc/4.7.0 --prefix=/afs/cern.ch/user/i/innocent/w3/gcc47slc5 --with-build-time-tools=/build/ge/new-binutils/a/slc5_amd64_gcc470/external/gcc/4.7.0-cms/bin Thread model: posix gcc version 4.7.2 20120629 (prerelease) [gcc-4_7-branch revision 189081] (GCC) [vocms123] ~/public/ctest/bugs48 $ ld -v GNU gold (GNU Binutils 2.22.52.20120515) 1.11
to clarify: in compiles and links correctly provided that template<typename T> inline int Foo<T>::bar(int i, int j) or if instead of the lambda "bar" invokes the external "ebar"
It is caused by revision 188117: http://gcc.gnu.org/ml/gcc-cvs/2012-06/msg00027.html
This is PR 53675
Author: jason Date: Mon Jul 2 19:14:34 2012 New Revision: 189175 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=189175 Log: PR c++/53821 * semantics.c (maybe_add_lambda_conv_op): Don't set DECL_INTERFACE_KNOWN. Added: trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template6.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/semantics.c trunk/gcc/testsuite/ChangeLog
Author: jason Date: Mon Jul 2 19:14:58 2012 New Revision: 189176 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=189176 Log: PR c++/53821 * semantics.c (maybe_add_lambda_conv_op): Don't set DECL_INTERFACE_KNOWN. Added: branches/gcc-4_7-branch/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-template6.C Modified: branches/gcc-4_7-branch/gcc/cp/ChangeLog branches/gcc-4_7-branch/gcc/cp/semantics.c branches/gcc-4_7-branch/gcc/testsuite/ChangeLog
Fixed.
I'm still wandering, more in general, if there is a semantic difference between template<typename T> int Foo<T>::bar(int i, int j) { … } and template<typename T> inline int Foo<T>::bar(int i, int j) { … }
*** Bug 53675 has been marked as a duplicate of this bug. ***
The only difference is the hint to the compiler that you want the function to be inlined.
Author: jason Date: Thu Dec 6 14:37:13 2012 New Revision: 194251 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194251 Log: PR c++/55015 PR c++/53821 * semantics.c (maybe_add_lambda_conv_op): Revert earlier change. * decl.c (start_preparsed_function): Make local class methods comdat in templates, too. Added: trunk/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv6.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/decl.c trunk/gcc/cp/semantics.c
Author: jason Date: Thu Dec 6 14:39:52 2012 New Revision: 194253 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=194253 Log: PR c++/55015 PR c++/53821 * semantics.c (maybe_add_lambda_conv_op): Revert earlier change. * decl.c (start_preparsed_function): Make local class methods comdat in templates, too. Added: branches/gcc-4_7-branch/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-conv6.C Modified: branches/gcc-4_7-branch/gcc/cp/ChangeLog branches/gcc-4_7-branch/gcc/cp/decl.c branches/gcc-4_7-branch/gcc/cp/semantics.c