[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