[Bug other/82352] New: link error 'defined in discarded section'
holger.hopp at sap dot com
gcc-bugzilla@gcc.gnu.org
Thu Sep 28 16:07:00 GMT 2017
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.
More information about the Gcc-bugs
mailing list