https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115413
Bug ID: 115413 Summary: Missing optimization: devirtualize the call in "if(typeid(*a)==typeid(A)) a->f();" structure Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: user202729 at protonmail dot com Target Milestone: --- Created attachment 58397 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=58397&action=edit Code to reproduce the example where gcc devirtualizes the call. As mentioned in the title. I think code of the form if(typeid(*a)==typeid(A)) a->f(); where `f` is a virtual function in `A` can be optimized to eliminate the virtualization. (Of course in practice it won't gain much performance because `type_info` comparison involves a string comparison which is slow, but if the `else` branch is `__builtin_unreachable()` it could potentially result in a performance gain.) As pointed out in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115410 , however, the address of `a->f` may not be the same as `A::f` if `a` comes from a shared library, however gcc already does that optimization in some cases e.g. A a = create_object(); a.f(); where `create_object` is loaded with `dlopen()`, then the address of `a.f` will actually be different from `A::f`, nevertheless gcc optimizes it to call `A::f` anyway. Because of ODR, the behavior must be identical. Example: in the linked file, compile with g++ -fPIC -shared -o libshared.so shared_lib.cpp -Wno-pmf-conversions g++ test4.cpp -ldl -Wno-pmf-conversions ./a.out then the 4 addresses will not be identical. (Note that the program technically invokes undefined behavior by referencing the address of `(void*)(&MyClass::hello)` which I believe violate ODR; nevertheless, it just serves to show which copy of `hello()` actually gets called.)