On Wed, 2021-05-12 at 23:54 +0800, 陈云星 via Gcc-help wrote: > In my test, class B inherent class A and B implements virtual function > “get_c” of class A; > > Because of there is only one sub-class of B ( which is A) > > LTO compile was expected to devirtualize virtual function call “get_c” > > However use gcc-9.3 to compile and link, the result was negative: > > ## build command > g++ -flto -c a.cc <http://a.cc/> -O2 > g++ -flto -c b.cc <http://b.cc/> -O2 > g++ -flto -c c.cc <http://c.cc/> -O2 > g++ -flto -c m.cc <http://m.cc/> -O2 > g++ -flto a.o b.o c.o m.o > > ## disassembly a.out > Objdump -d -C a.out > > 0000000000400610 <A::s(char*)>: > 400610: 48 8b 07 mov (%rdi),%rax > 400613: 53 push %rbx > 400614: 48 89 f3 mov %rsi,%rbx > 400617: ff 10 callq *(%rax) > 400619: 48 85 db test %rbx,%rbx > 40061c: 74 07 je 400625 <A::s(char*)+0x15> > 40061e: 0f be 13 movsbl (%rbx),%edx > 400621: 5b pop %rbx > 400622: 01 d0 add %edx,%eax > 400624: c3 retq > 400625: 83 c0 01 add $0x1,%eax > 400628: 5b pop %rbx > 400629: c3 retq > 40062a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) > > At " 400617: ff 10 callq *(%rax)” > which call by virtual function dispatch > > > // file a.h > #ifndef INCLUDE_A > #define INCLUDE_A > class A { > protected: > virtual int get_c() = 0; > public: > int s(char* a); > }; > #endif > > // file a.cc <http://a.cc/> > #include "a.h" > int __attribute__((noinline)) A::s(char* a) { > int c = get_c(); > if (a == 0) { > return c + 1; > } > return c + a[0]; > } > > // file b.h > #include "a.h" > class B : public A { > public: > B(int b, int c) : bbb(b), ccc(c) {} > protected: > virtual int get_c() { > return bbb == 0 ? ccc : ccc + bbb; > } > private: > int bbb; > int ccc; > }; > > // file b.cc <http://b.cc/> > #include “b.h" > > // file c. <http://c.cc/>h > #include "a.h" > class C { > public: > C(A &a): a(a) {} > int ss(char* b); > private: > A &a; > }; > > // file c.cc <http://c.cc/> > #include "c.h" > int __attribute__ ((noinline)) C::ss(char* b) { > return a.s(b); > } > > // file m.cc <http://m.cc/> > #include "b.h" > #include "c.h" > int main(int argc, char** argv) > { > B b(argc, argc+1); > C c(b); > return c.ss(*argv); > } I think it's https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47316. -- Xi Ruoyao <xry111@xxxxxxxxxxxxxxxx> School of Aerospace Science and Technology, Xidian University