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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
   Last reconfirmed|2018-05-03 00:00:00         |2019-2-26

--- Comment #34 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Honza, could you take another look at this reduced version please?

__attribute__((weak)) void f() { }

template <typename T>
struct Base
{
  virtual void virt() = 0;
  void do_virt() { virt(); }
};

template <typename T>
struct Derived : Base<T>
{
  void virt() {}
};

template <typename T>
struct Wrap
{
  T* p = nullptr;

  virtual void indirect_virt()
  {
#ifdef FIX
    p->virt();          // OK
#else
    p->do_virt();       // link error
#endif
  }
};

template <const char*>
struct Template
{
};

constexpr char str[] = "";

struct I
{
  I() { f(); }
  Wrap<Derived<Template<str>>> l;
};

int main(){new I();}


This is valid C++, but when compiled with -O1 -fdevirtualize it fails with:

l.cc:13:8: warning: ‘void Derived<T>::virt() [with T = Template<(& str)>]’ used
but never defined
   void virt() {}
        ^~~~
/usr/bin/ld: /tmp/ccYAFtTY.o: in function `Wrap<Derived<Template<&str> >
>::indirect_virt()':
l.cc:(.text+0x57): undefined reference to `Derived<Template<&str> >::virt()'
collect2: error: ld returned 1 exit status

If compiled with -DFIX it links OK.

Even though the Template<(&str)> template argument is completely unused, it
compiles fine if Derived<int> is used instead, or
Derived<AnotherTemplate<int>>. It only fails when using a template that has a
pointer for its template parameter.

Reply via email to