[clang] 7eae8c6 - Don't update the vptr at the start of the destructor of a final class.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 8 19:59:51 PDT 2021
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
More information about the cfe-commits
mailing list