https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114643
Bug ID: 114643 Summary: Call to a template function emitted but without the code for the template function itself Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: abbeyj+gcc at gmail dot com Target Milestone: --- When building the following example, a linker error is produced. ``` void foo(); template <class> class DynArray { public: virtual void SetAlloc(unsigned); int *m_pElems; unsigned m_nNumElems; unsigned m_nNumAlloc; long m_nChunkSize; }; void *DoRealloc(void *, long); template <class T> void DynArray<T>::SetAlloc(unsigned new_size) { if (m_nChunkSize) new_size = m_nChunkSize * m_nChunkSize - 1 / m_nChunkSize; else if (m_nNumAlloc) if (new_size > m_nNumAlloc / 2) new_size = new_size > m_nNumAlloc + 1 ? new_size : m_nNumAlloc * 1.5 + 1; if (m_nNumElems && m_nNumAlloc && (new_size || m_pElems)) m_pElems = (T *)DoRealloc(m_pElems, 0); } struct object { DynArray<int> d; void f(int size); }; template <typename T> void deser(int size, T &x) { x.SetAlloc(0); if (size) { x.SetAlloc(size); foo(); } } void object::f(int size) { deser(size, d); } ``` Build with: $ g++ -fPIC -O3 -Wall -Werror -fvisibility=hidden reloc.cxx -shared Output: > /usr/bin/ld: /tmp/ccLaKma6.o: relocation R_X86_64_PC32 against undefined > symbol `_ZN8DynArrayIiE8SetAllocEj' can not be used when making a shared > object; recompile with -fPIC > /usr/bin/ld: final link failed: Bad value > collect2: error: ld returned 1 exit status The symbol in the above error message demangles to `DynArray<int>::SetAlloc(unsigned int)`. The error message suggests to compile with `-fPIC` but this is already being compiled with `-fPIC`. The issue seems to be that GCC emits a call to `DynArray<int>::SetAlloc` but doesn't emit code for `DynArray<int>::SetAlloc` itself. The reproducer was minimized with the help of C-Reduce. Very minor changes to the code result in the problem not reproducing anymore. This is the smallest that I could manage to get it. Godbolt link: https://godbolt.org/z/1Ynz1Khac This appears to have started sometime around GCC 8.1 and still happens on the trunk version that's currently available on Godbolt.