[Bug c++/95158] New: Templates + Diamond Inheritance + Final = Pure Virtual Function Call

sudgylacmoe at gmail dot com gcc-bugzilla@gcc.gnu.org
Fri May 15 22:59:22 GMT 2020


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95158

            Bug ID: 95158
           Summary: Templates + Diamond Inheritance + Final = Pure Virtual
                    Function Call
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sudgylacmoe at gmail dot com
  Target Milestone: ---

With this code:

class Base {
    public:
        virtual void foo()=0;
};

template <typename T>
class MiddleA : virtual public Base {
    public:
        virtual void foo() override {}
};

class MiddleB : virtual public Base {};

template <typename T>
class Derived final : public MiddleA<T>, public MiddleB {
    public:
        void bar()
        {
            this->foo();
        }
};

int main()
{
    auto a = Derived<void>();
    a.bar(); // Instantiate the template
}

Compiling it with gcc 10.1 with just "g++ test.cpp" (and many other ways to
compile, such as optimization levels and warnings) causes gcc to try to call
Base::foo(), a pure virtual function:

/usr/bin/ld: /tmp/cce0CW5N.o: in function `Derived<void>::bar()':
test.cpp:(.text._ZN7DerivedIvE3barEv[_ZN7DerivedIvE3barEv]+0x14): undefined
reference to `Base::foo()'
collect2: error: ld returned 1 exit status

Trying a few different versions, with gcc 9.3 and before this code compiles
correctly.  On any other compiler I tried (the most recent versions of clang,
msvc and icc on godbolt) it compiled fine.  Removing the template from either
MiddleA or Derived fixes it, removing the inheriting from MiddleB fixes it, and
removing final from Derived fixes it.  If a definition of Base::foo() is added,
the code compiles and calls it.  A workaround is to call MiddleA::foo()
directly.

Output of g++ -v:

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib
--libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=https://bugs.archlinux.org/
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --with-isl
--with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit
--enable-cet=auto --enable-checking=release --enable-clocale=gnu
--enable-default-pie --enable-default-ssp --enable-gnu-indirect-function
--enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id
--enable-lto --enable-multilib --enable-plugin --enable-shared
--enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-libunwind-exceptions --disable-werror
gdc_include_dir=/usr/include/dlang/gdc
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.1.0 (GCC)


More information about the Gcc-bugs mailing list