[clang] [Sema] Instantiate destructors for initialized members (PR #128866)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 6 06:22:32 PST 2025
================
@@ -5283,6 +5283,102 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,
return false;
}
+static CXXDestructorDecl *LookupDestructorIfRelevant(Sema &S,
+ CXXRecordDecl *Class) {
+ if (Class->isInvalidDecl())
+ return nullptr;
+ if (Class->hasIrrelevantDestructor())
+ return nullptr;
+
+ // Dtor might still be missing, e.g because it's invalid.
+ return S.LookupDestructor(Class);
+}
+
+static void MarkFieldDestructorReferenced(Sema &S, SourceLocation Location,
+ FieldDecl *Field) {
+ if (Field->isInvalidDecl())
+ return;
+
+ // Don't destroy incomplete or zero-length arrays.
+ if (isIncompleteOrZeroLengthArrayType(S.Context, Field->getType()))
+ return;
+
+ QualType FieldType = S.Context.getBaseElementType(Field->getType());
+
+ auto *FieldClassDecl = FieldType->getAsCXXRecordDecl();
+ if (!FieldClassDecl)
+ return;
+
+ // The destructor for an implicit anonymous union member is never invoked.
+ if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
+ return;
+
+ auto *Dtor = LookupDestructorIfRelevant(S, FieldClassDecl);
+ if (!Dtor)
+ return;
+
+ S.CheckDestructorAccess(Field->getLocation(), Dtor,
+ S.PDiag(diag::err_access_dtor_field)
+ << Field->getDeclName() << FieldType);
+
+ S.MarkFunctionReferenced(Location, Dtor);
+ S.DiagnoseUseOfDecl(Dtor, Location);
+}
+
+static void MarkBaseDestructorsReferenced(Sema &S, SourceLocation Location,
+ CXXRecordDecl *ClassDecl) {
+ if (ClassDecl->isDependentContext())
+ return;
+
+ // We only potentially invoke the destructors of potentially constructed
+ // subobjects.
+ bool VisitVirtualBases = !ClassDecl->isAbstract();
+
+ // If the destructor exists and has already been marked used in the MS ABI,
+ // then virtual base destructors have already been checked and marked used.
+ // Skip checking them again to avoid duplicate diagnostics.
+ if (S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+ CXXDestructorDecl *Dtor = ClassDecl->getDestructor();
+ if (Dtor && Dtor->isUsed())
+ VisitVirtualBases = false;
+ }
+
+ llvm::SmallPtrSet<const CXXRecordDecl *, 8> DirectVirtualBases;
+
+ // Bases.
+ for (const auto &Base : ClassDecl->bases()) {
+ const auto *RT = Base.getType()->getAs<RecordType>();
+ if (!RT)
+ continue;
+
+ auto *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
----------------
erichkeane wrote:
```suggestion
auto *BaseClassDecl = Base.getType()->getAsCXXRecordDecl();```
https://github.com/llvm/llvm-project/pull/128866
More information about the cfe-commits
mailing list