In the following code (condensed from a real example where Fnord was boost::intrusive_ptr), the call to the Fnord constructor in function make_fnord only succeeds because Aubergine is derived from Base. But GCC doesn't "know" that Aubergine is derived from Base until after it's seen make_fnord. (And make_fnord itself isn't templated in any way, so this isn't a delayed-instantiation thing, although similar examples where Fnord isn't templated do successfully produce an error.) GCC 2.95.3 gave an error on this code, but GCC 4.1.2, 4.2.3, and 4.3.0 accept it (even with -fno-unit-at-a-time). Shouldn't it be an error?
template <class T> class Fnord { public: explicit Fnord(T* p) { intrusive_ptr_add_ref(p); } }; class Base { }; void intrusive_ptr_add_ref(Base*); class Aubergine; Fnord<Aubergine> make_fnord(Aubergine *p) { return Fnord<Aubergine>(p); } class Aubergine: public Base { }; GCC 2.95.3's error: wtf.cpp: In method `Fnord<Aubergine>::Fnord(Aubergine *)': wtf.cpp:18: instantiated from here wtf.cpp:5: type `Base' is not a base type for type `Aubergine' gcc -v on the 4.3.0 which fails to give an error: Using built-in specs. Target: x86_64-linux Configured with: ../gcc-4.3.0/configure --prefix=/usr --enable-shared --enable-languages=c,c++ --enable-threads --enable-__cxa_atexit --with-system-zlib --disable-multilib x86_64-linux Thread model: posix gcc version 4.3.0 (GCC) -- Summary: GCC uses inheritance information it doesn't yet know Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: peter at empeg dot com GCC build triplet: x86_64-linux-gnu GCC host triplet: x86_64-linux-gnu GCC target triplet: x86_64-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35799