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); }