Given the following code: #define VIRTUAL virtual //#define VIRTUAL // use this to 'fix' the code #include <iostream> using namespace std; struct VirtualBase{}; struct Bar : public VIRTUAL VirtualBase { template< typename castT >explicit Bar( castT const& cast ); }; template< > Bar::Bar( int const & cast ) { cout << "Called Bar::Bar( int )!" << endl; } template< typename T > struct Hello : public VIRTUAL VirtualBase { Hello( int i ); }; template< > Hello< char >::Hello( int i ) { cout << "Called Hello::Hello( int )!" << endl; } template< typename T > struct Foo : public VIRTUAL VirtualBase { template< typename castT > Foo( castT const& cast ); template< typename T1 > void func( T1 ); }; template< > template< > Foo< char >::Foo( int const & cast ) { cout << "Called Foo::Foo( int )!" << endl; } int main() { Foo< char > fooChar( 42 ); Bar barChar( 42 ); Hello< char > helloChar( 42 ); return 0; } compiled with: g++ -v -save-temps main.cpp gives the following output Es werden eingebaute Spezifikationen verwendet. Ziel: i386-redhat-linux Konfiguriert mit: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,java,f95,ada --enable-java-awt=gtk --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --host=i386-redhat-linux Thread-Modell: posix gcc-Version 4.0.2 20051125 (Red Hat 4.0.2-8) /usr/libexec/gcc/i386-redhat-linux/4.0.2/cc1plus -E -quiet -v -D_GNU_SOURCE main.cpp -fpch-preprocess -o main.ii nicht vorhandenes Verzeichnis »/usr/lib/gcc/i386-redhat-linux/4.0.2/../../../../i386-redhat-linux/include« wird ignoriert #include "..." - Suche beginnt hier: #include <...> - Suche beginnt hier: /usr/lib/gcc/i386-redhat-linux/4.0.2/../../../../include/c++/4.0.2 /usr/lib/gcc/i386-redhat-linux/4.0.2/../../../../include/c++/4.0.2/i386-redhat-linux /usr/lib/gcc/i386-redhat-linux/4.0.2/../../../../include/c++/4.0.2/backward /usr/local/include /usr/lib/gcc/i386-redhat-linux/4.0.2/include /usr/include Ende der Suchliste. /usr/libexec/gcc/i386-redhat-linux/4.0.2/cc1plus -fpreprocessed main.ii -quiet -dumpbase main.cpp -auxbase main -version -o main.s GNU C++ version 4.0.2 20051125 (Red Hat 4.0.2-8) (i386-redhat-linux) compiled by GNU C version 4.0.2 20051125 (Red Hat 4.0.2-8). GGC-Heuristik: --param ggc-min-expand=99 --param ggc-min-heapsize=129465 main.cpp:18: Fehler: Template-ID »Bar<>« für »Bar::Bar(const int&)« passt zu keiner Templatedeklaration main.cpp:18: Fehler: ungültige Funktionsdeklaration main.cpp:55: Fehler: Template-ID »Foo<>« für »Foo<char>::Foo(const int&)« passt zu keiner Templatedeklaration main.cpp:55: Fehler: ungültige Funktionsdeklaration ======================================== The problem can be fixed, by putting the comment to the other #define at the beginning. I reproduced this on WinXP - gcc-3.4.2, Linux FC4 with gcc-4.0.0 and 4.0.2 However MSVC 7.1 + 8.0 and Comeau accept the code.
Related to PR 9050.
Confirmed, though this doesn't seem to have anything to do with PR 9050. Here's a shorter testcase: -------------- struct B{}; struct Bar : virtual B { template <typename T> Bar( T const& cast ); }; template <> Bar::Bar( int const & cast ) {} template <typename T> struct Foo : virtual B { template <typename T1> Foo( T1 const& cast ); }; template< > template< > Foo< char >::Foo( int const & cast ) {} --------------------- g/x> /home/bangerth/bin/gcc-4.1-pre/bin/c++ -c x.cc x.cc:7: error: template-id ‘Bar<>’ for ‘Bar::Bar(const int&)’ does not match any template declaration x.cc:7: error: invalid function declaration x.cc:15: error: template-id ‘Foo<>’ for ‘Foo<char>::Foo(const int&)’ does not match any template declaration x.cc:15: error: invalid function declaration The thing that makes me think that this has nothing to do with 9050 is that if the inheritance is made non-virtual, then the bug goes away. That's certainly odd behavior -- this is a bug in semantic analysis, not in the parser! This used to work in 2.95, so is a regression of rejects-valid kind. W.
Will not be fixed in 4.1.1; adjust target milestone to 4.1.2.
The problem here is that we are not skipping artificial arguments (other than the "this" pointer) when trying to match the specialization. The additional parameters for constructors for classes with virtual bases are therefore confusing the compiler.
Won't fix in GCC-4.0.x Adjusting milestone.
Subject: Bug 26988 Author: mmitchel Date: Sun Feb 11 20:15:13 2007 New Revision: 121822 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=121822 Log: PR c++/26988 * pt.c (determine_specialization): Use skip_artificial_parms_for. (fn_type_unificiation): Likewise. (get_bindings): Likewise. PR c++/26988 * g++.dg/template/spec34.C: New test Added: trunk/gcc/testsuite/g++.dg/template/spec34.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 26988 Author: mmitchel Date: Sun Feb 11 21:40:56 2007 New Revision: 121826 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=121826 Log: PR c++/26988 * pt.c (determine_specialization): Use skip_artificial_parms_for. (fn_type_unificiation): Likewise. (get_bindings): Likewise. PR c++/26988 * g++.dg/template/spec34.C: New test Added: branches/gcc-4_2-branch/gcc/testsuite/g++.dg/template/spec34.C Modified: branches/gcc-4_2-branch/gcc/cp/ChangeLog branches/gcc-4_2-branch/gcc/cp/pt.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog
Fixed in 4.2.0, 4.3.0.
Closing 4.1 branch.