https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69445
Bug ID: 69445 Summary: Fail to devirtualize call to base class function even though derived class type is 'final' Product: gcc Version: 6.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- G++ should devirtualize both calls in func(const C&): struct Base { virtual void foo() const = 0; virtual void bar() const {} }; struct C final : Base { void foo() const { } }; void func(const C & c) { c.bar(); c.foo(); } We take advantage of the fact that C is final and so C::foo() can't be overriden, but don't apply the same logic to Base::bar(). With -O3 Clang optimises func to an empty function but with G++ the x86_64 code is: Base::bar() const: rep ret func(C const&): movq (%rdi), %rax movq 8(%rax), %rax cmpq Base::bar() const, %rax jne .L5 rep ret .L5: jmp *%rax