http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53831
Bug #: 53831 Summary: Inline virtuals missing in LTO symtab Classification: Unclassified Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: lto AssignedTo: unassig...@gcc.gnu.org ReportedBy: tetra2...@gmail.com The attached sample program works fine when compiled without LTO: $ make clean all but fails if I specify -flto: $ make USE_LTO=1 clean all libdummy.a: could not read symbols: Bad value collect2: error: ld returned 1 exit status make: *** [test.exe] Error 1 The error is caused by a mismatch in libdummy.a's ordinary symtab: $ arm-linux-androideabi-nm libdummy.a impl.o: ... 00000000 W _ZN1C1fEv 00000000 T _ZN1C1gEv 00000000 D _ZTV1C ... and it's LTO symtab: $ arm-linux-androideabi-objdump -hts impl.o ... Contents of section .gnu.lto_.symtab.1306600d0972f21a: 0000 5f5a4e31 43316745 76000000 00000000 _ZN1C1gEv....... 0010 00000000 00a10000 005f5a54 56314300 ........._ZTV1C. 0020 00000000 00000000 000000b5 000000 ............... Contents of section .gnu.lto_.opts: ... Note that _ZN1C1fEv (which is mangled name for inline virtual C::f()) is missing in LTO symtab. This later causes linker to go mad in elf_link_add_archive_symbols() when trying to link in impl.o more than once (element->archive_pass > 0). It seems that C::f() is filtered out in produce_symtab in lto-streamer-out.c: if (DECL_COMDAT (node->symbol.decl) && cgraph_comdat_can_be_unshared_p (node)) continue; because C::f() is (erroneously) considered to be COMDAT. I've tested the code with TOT binutils and gcc. I had to include multiple file program because otherwise bug would fail to manifest.