https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113821
Bug ID: 113821 Summary: Missed optimization for final classes: expensive check for result of dynamic cast Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: janschultke at googlemail dot com Target Milestone: --- Code to reproduce (https://godbolt.org/z/48cabYT78) =================================================== struct Base { virtual ~Base() = default; }; struct Derived final : Base {}; bool is_derived(Base& a) { return dynamic_cast<Derived*>(&a); } Expected output (clang) ======================= is_derived(Base&): lea rax, [rip + vtable for Derived+16] cmp qword ptr [rdi], rax sete al ret Actual output (GCC) =================== is_derived(Base&): sub rsp, 8 xor ecx, ecx mov edx, OFFSET FLAT:typeinfo for Derived mov esi, OFFSET FLAT:typeinfo for Base call __dynamic_cast test rax, rax setne al add rsp, 8 ret Explanation =========== For final classes, checking for success of dynamic_cast is equivalent to checking whether the vtable pointer equals that of the destination type. GCC is overly pessimistic by calling __dynamic_cast, which is much more expensive, I'd imagine. Clang emits the same kind of pessimistic code only when Derived is not final.