Would you please try moving the definition of the virtual destructor out of the header (into some cpp file). This is practically a bad idea as it bloats each object file that uses the header with RTTI and can lead to unexpected results when using dynamic_cast or exceptions. ------------------ Best regards, lh_mouse 2016-06-15 ------------------------------------------------------------- 发件人:Dave Gittins <dave.gittins@xxxxxxxxx> 发送日期:2016-06-15 20:29 收件人:gcc-help@xxxxxxxxxxx 抄送: 主题:Bogus unresolved references to vtable when building with lto Hi, I have a program that unexpectedly hit a linker error when building on x86_64 Linux with ld / gcc 6 and using LTO. Sorry but I have not managed to extract a sensible test case so far due to the large size (and sensitivity) of the code base. I am still trying to chop it down without losing the result. Meanwhile I'll describe the setup and hope someone can help me. * the main program builds with LTO and aggressive optimisation * it links against a library libfoo, built elsewhere with gcc but without LTO * foo.h contains: class Foo { virtual ~Foo() {}; virtual blah() = 0; }; * libfoo.a contains the vtable for Foo in multiple object files (using comdat groups) * classes that inherit from Foo are used in the program Result: 1. with gcc 5.2 using -flto -O3: OK 2. with gcc 6.1 using -O3 (no LTO): OK 3. with gcc 6.1 using -flto -O3 -fno-strict-aliasing: OK 4. with gcc 6.1 using -flto -O3: linker error: unresolved reference to vtable for Foo I am not very familiar with the inner workings of LTO, but re-running the link step with --save-temps and looking at the output files, I can see one difference between cases 3 and 4: in case 3 the vtable symbol is present in a .s file for the target (e.g. _ZTVN3FooE seems to be defined) but in the failing case 4 it is called _ZTVN3FooE.lto_priv.7288. In both cases, the lm.res file contains something like this: lm.res:194 857f97bd35affadb PREVAILING_DEF _ZTVN3FooE lm.res:9895 38fe32bfc94fb92d PREEMPTED_IR _ZTVN3FooE lm.res:461 979b2bacd9a23781 PREEMPTED_IR _ZTVN3FooE lm.res:403 d7cb462ac76ae78f PREEMPTED_IR _ZTVN3FooE lm.res:1625 1c237136eccb8e22 PREEMPTED_IR _ZTVN3FooE lm.res:194 dc12ecd964eef823 PREEMPTED_IR _ZTVN3FooE lm.res:194 b0ceb27c32d02e6b PREEMPTED_IR _ZTVN3FooE lm.res:194 f7293254f09d2c44 PREEMPTED_IR _ZTVN3FooE lm.res:9490 fa5a2b6c2738a867 PREEMPTED_IR _ZTVN3FooE I also added this as a comment on this bug report but now I am not sure if it's really directly related: https://sourceware.org/bugzilla/show_bug.cgi?id=19842 I think the LTO script is telling the linker that it will provide this symbol, and then providing it as a global symbol in the working case, but then in the failing case it is making it local, or something like that? I assume the optimiser came to some relevant conclusion about the required visibility of the vtable...? Any help appreciated. Dave