// https://godbolt.org/z/hx7h7v struct Base { virtual int f() { return 1; } }; namespace { struct Derived1 : public Base { int f() override { return 2; } }; struct Derived2 : public Base {}; } int leaf_class1(Base *p) { return ((Derived1*)p)->f(); } // devirtualized by GCC, because PrivateDerived is provably a leaf int leaf_class2(Base *p) { return ((Derived2*)p)->f(); } // not devirtualized by GCC -- this smells like a missed-optimization bug ==== GCC 4.9 started to be able to devirtualize things in the compiler, based on translation-unit-wide (but still compiler-time) information. GCC 4.9.0 is able to devirtualize the call in `leaf_class1`. This is awesome! However, both GCC 4.9 and GCC trunk fail to apply the exact same optimization to `leaf_class2`. The only difference between `Derived1` and `Derived2` is that `Derived1::f` is declared directly in `Derived1` whereas `Derived2::f` is technically a member of `Base`. That shouldn't matter at all to the devirtualization logic. But apparently it does. ==== Barely possibly related missed-devirtualization bugs: #47316, #60674, #89924, #94243.