https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64653
Bug ID: 64653 Summary: Incomplete emission of D1/D2 destructors when optimising -- link failure with gold Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: thiago at kde dot org Created attachment 34470 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34470&action=edit Test project When the attached project is built with GCC 5 (x86-64, SVN build from 219682) and linked with gold, the linker exits with: /usr/bin/ld.gold: error: src2.o: requires dynamic R_X86_64_PC32 reloc against '_ZN5QListI7QStringED1Ev' which may overflow at runtime; recompile with -fPIC src2.cpp:3: warning: relocation refers to discarded section In other words: the linker wants to use a symbol that is present in the same .o file itself, but it has discarded that section. Since now the symbol is out-of-library, it prints an error about the relocation. It appears that the issue is highly dependent on optimisations applied to src1.cpp, which is why I am also attaching the generated assembly by my version of GCC. If I compare that generated assembly with the one generated by GCC 4.9, the following diff stands out: --- src1-4.9.s 2015-01-17 17:31:02.254643092 -0800 +++ src1-5.0.s 2015-01-17 17:30:50.795714657 -0800 @@ -38,9 +38,6 @@ .LCOLDE0: .section .text._ZN5QListI7QStringED2Ev,"axG",@progbits,_ZN5QListI7QStringED5Ev,comdat .LHOTE0: - .weak _ZN5QListI7QStringED1Ev - .hidden _ZN5QListI7QStringED1Ev - .set _ZN5QListI7QStringED1Ev,_ZN5QListI7QStringED2Ev .section .text.unlikely,"ax",@progbits In other words, the compiler failed to emit the symbol for the D1 destructor in src1.o. In this file, GCC emitted calls to the "D2" destructor only. If we look at src2.o, the compiler emitted a call to the "D1" destructor, not to "D2". It did emit the correct section with the "D1" symbol, but gold discarded this section, as it chose the one from src1.o. The regular ld.bfd does not seem to have a problem. It's not apparent to me why GCC chose D1 over D2 or vice-versa. This class has no base, let alone a virtual base, so both destructors are identical. Clang 3.5 and 3.6 emit only the "D2" destructor; it doesn't seem to emit D1 at all, not even as an alias, in either source file. I expected the same problem to occur if I compiled src1 with clang and src2 with GCC, but there was no linker error. The only other difference was that Clang did not emit the D5 symbol. ICC emits both and calls "D1" in src1.o (under -O0) and emits D1 only in src2.o, calling it. D5 is also missing.