https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82352
Bug ID: 82352 Summary: link error 'defined in discarded section' Product: gcc Version: 7.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: holger.hopp at sap dot com Target Milestone: --- I'm getting linker error `...' referenced in section `...' of ..: defined in discarded section `...' of ... with gcc-7 compiled code, that do not appear with gcc-5 or gcc-6. Source: typedef long unsigned int size_t; class A { public : typedef enum { Zero = 0, One = 1 } tA; A(tA a) { m_a = a; } private : tA m_a; }; class B { public : void *operator new(size_t t) { return (void*)(42); }; }; class C { public: virtual void ffff () = 0; }; class D { public : virtual void g() = 0; virtual void h() = 0; }; template<class T> class IIII: public T, public D { public: void ffff() { if (!m_i2) throw A(A::One); }; void h() { if (m_i2) throw A(A::Zero); } protected: virtual void g() { if (m_i1 !=0) throw A(A::Zero); }; private : int m_i1; void *m_i2; }; class E { private: size_t m_e; static const size_t Max; public: E& i(size_t a, size_t b, size_t c) { if ((a > Max) || (c > Max)) throw A(A::Zero ); if (a + b > m_e) throw A(A::One ); return (*this); } inline E& j(const E &s) { return i(0,0,s.m_e); } }; class F : public C { }; class G : public C { }; class HHHH : public B, public F, public G { }; void k() { HHHH *p = new IIII<HHHH>(); } void l() { E e1, e2; e1.j(e2); } Reproduce: $ g++ -O2 -o t1.o -c t1.cpp && echo ok && objdump -t t1.o | grep ffffEv.part ok 0000000000000000 l d .text.unlikely._ZN4IIIII4HHHHE4ffffEv.part.2 0000000000000000 .text.unlikely._ZN4IIIII4HHHHE4ffffEv.part.2 0000000000000000 l F .text.unlikely._ZN4IIIII4HHHHE4ffffEv.part.2 0000000000000023 _ZN4IIIII4HHHHE4ffffEv.part.2 This symbol is causing the linker problem. Maybe this is already sufficient for you. You may get the final linker error as follows: Slightly change source t1.cpp to t2.cpp: - remove function g() (twice!) - rename k() and l() by k2() and l2(2), respectively. $ g++ -O2 -o t2.o -c t2.cpp && echo ok && objdump -t t2.o | grep ffffEv.part ok 0000000000000000 l d .text.unlikely._ZN4IIIII4HHHHE4ffffEv.part.1 0000000000000000 .text.unlikely._ZN4IIIII4HHHHE4ffffEv.part.1 0000000000000000 l F .text.unlikely._ZN4IIIII4HHHHE4ffffEv.part.1 0000000000000023 _ZN4IIIII4HHHHE4ffffEv.part.1 Symbol is named ...part.1 instead of ...part.2 in this case. $ echo "int main() { return 0; }" | gcc -x c -c - -o main.o $ g++ -o main main.o t1.o t2.o `_ZN4IIIII4HHHHE4ffffEv.part.1' referenced in section `.text.unlikely' of t2.o: defined in discarded section `.text.unlikely._ZN4IIIII4HHHHE4ffffEv.part.1[_ZN4IIIII4HHHHE4ffffEv]' of t2.o collect2: error: ld returned 1 exit status Following works: (1) gcc-5 and gcc-6 (2) gcc-7 with -O1 (3) marking ffff() with __attribute__((used)) (found in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65199) (4) patch binutils in file bfd/elflink.c, function _bfd_elf_default_action_discarded: remove the COMPLAIN flag Nevertheless, it is probably a bug on gcc side, as in similar old bug 49665 with same linker error.