https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78873
Bug ID: 78873 Summary: Virtual call after conversion to base class pointer is not devirtualized Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ambrop7 at gmail dot com Target Milestone: --- The following test case shows the issue. The generated code for TestDevirtualization<Impl> could perform a direct call to Impl::Foo but it performs a call via the vtable. #include <stdio.h> struct Iface { virtual void Foo() = 0; }; struct Impl : public Iface { __attribute__ ((noinline)) void Foo() override final { printf("Impl::Foo\n"); } }; template <typename Type> __attribute__ ((noinline)) void TestDevirtualuzation(Type *obj) { static_cast<Iface *>(obj)->Foo(); } int main() { Impl impl; TestDevirtualuzation(&impl); return 0; } I have heard arguments that optimizing this would not be legal, with the following test case which supposedly might be valid: struct Liar : Iface { void Foo() {} }; Impl impl; TestDevirtualuzation(reinterpret_cast<Liar*>(&impl)); But I think it is not valid; the result of the reinterpret_cast does not point to a Liar object, so the static_cast done in TestDevirtualuzation *should* be invalid. I couldn't find a clear statement in the standard about this though.