[clang] [clang] Avoid triggering vtable instantiation for C++23 constexpr dtor (PR #102605)

via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 9 06:01:34 PDT 2024


================
@@ -7042,12 +7042,38 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
       }
     }
 
+    bool EffectivelyConstexprDestructor = true;
+    // Avoid triggering vtable instantiation due to a dtor that is not
+    // "effectively constexpr" for better compatibility.
+    if (isa<CXXDestructorDecl>(M)) {
+      auto Check = [](QualType T, auto &&Check) -> bool {
+        const CXXRecordDecl *RD =
+            T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
+        if (!RD || !RD->isCompleteDefinition())
+          return true;
+
+        if (!RD->hasConstexprDestructor())
+          return false;
+
+        for (const CXXBaseSpecifier &B : RD->bases())
+          if (!Check(B.getType(), Check))
+            return false;
+        for (const FieldDecl *FD : RD->fields())
+          if (!Check(FD->getType(), Check))
+            return false;
+        return true;
+      };
+      EffectivelyConstexprDestructor =
+          Check(QualType(Record->getTypeForDecl(), 0), Check);
+    }
+
     // Define defaulted constexpr virtual functions that override a base class
     // function right away.
     // FIXME: We can defer doing this until the vtable is marked as used.
     if (CSM != CXXSpecialMemberKind::Invalid && !M->isDeleted() &&
         M->isDefaulted() && M->isConstexpr() && M->size_overridden_methods())
-      DefineDefaultedFunction(*this, M, M->getLocation());
+      if (EffectivelyConstexprDestructor)
+        DefineDefaultedFunction(*this, M, M->getLocation());
----------------
cor3ntin wrote:

you can merge the two if statements

https://github.com/llvm/llvm-project/pull/102605


More information about the cfe-commits mailing list