https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92054
Bug ID: 92054 Summary: `final` does not cause devirtualization of nested calls Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: antoshkka at gmail dot com Target Milestone: --- Consider the example: struct A { virtual int f() { return 0; } virtual int g() { return f() + 40; } }; struct B2 final : A { int f() override { return 42; } }; int test(B2& b) { return b.g(); } GCC-10 generates the assembly that does a fair vptr call. However, `B2` is final, so any call to the virtual functions of `A` end up with a call to the same function in `B2`. So `B2::g()` should inline the `A::g()` and get optimized to: int test(B2& b) { return B2::f() + 40; } Which is just 82, because `B2::f()` always returns 42. Godbolt playground: https://godbolt.org/z/PJ4nL-