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

Reply via email to