Author: Richard Smith Date: 2021-10-08T19:59:42-07:00 New Revision: 7eae8c6e62b2a91e71aade19324b9d2242bcb4ab
URL: https://github.com/llvm/llvm-project/commit/7eae8c6e62b2a91e71aade19324b9d2242bcb4ab DIFF: https://github.com/llvm/llvm-project/commit/7eae8c6e62b2a91e71aade19324b9d2242bcb4ab.diff LOG: Don't update the vptr at the start of the destructor of a final class. In this case, we know statically that we're destroying the most-derived class, so the vptr must already point to the current class and never needs to be updated. Added: Modified: clang/lib/CodeGen/CGClass.cpp clang/test/CodeGenCXX/destructors.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 828dd7147da5..0df64d4d5d26 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1424,6 +1424,11 @@ static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, if (!ClassDecl->isDynamicClass()) return true; + // For a final class, the vtable pointer is known to already point to the + // class's vtable. + if (ClassDecl->isEffectivelyFinal()) + return true; + if (!Dtor->hasTrivialBody()) return false; diff --git a/clang/test/CodeGenCXX/destructors.cpp b/clang/test/CodeGenCXX/destructors.cpp index 4bd633928b6e..d2f1a47a5691 100644 --- a/clang/test/CodeGenCXX/destructors.cpp +++ b/clang/test/CodeGenCXX/destructors.cpp @@ -529,4 +529,38 @@ namespace test11 { } } + +namespace final_dtor { + struct A { + virtual void f(); + // CHECK6-LABEL: define {{.*}} @_ZN10final_dtor1AD2Ev( + // CHECK6: store {{.*}} @_ZTV + // CHECK6-LABEL: {{^}}} + virtual ~A() { f(); } + }; + struct B : A { + // CHECK6-LABEL: define {{.*}} @_ZN10final_dtor1BD2Ev( + // CHECK6: store {{.*}} @_ZTV + // CHECK6-LABEL: {{^}}} + virtual ~B() { f(); } + }; + struct C final : A { + // CHECK6-LABEL: define {{.*}} @_ZN10final_dtor1CD2Ev( + // CHECK6-NOT: store {{.*}} @_ZTV + // CHECK6-LABEL: {{^}}} + virtual ~C() { f(); } + }; + struct D : A { + // CHECK6-LABEL: define {{.*}} @_ZN10final_dtor1DD2Ev( + // CHECK6-NOT: store {{.*}} @_ZTV + // CHECK6-LABEL: {{^}}} + virtual ~D() final { f(); } + }; + void use() { + {A a;} + {B b;} + {C c;} + {D d;} + } +} #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits