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.

Reply via email to