[clang] [Sema] Instantiate destructors for initialized members (PR #128866)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 5 06:29:51 PST 2025
================
@@ -5283,6 +5283,102 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,
return false;
}
+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());
+
+ const RecordType *RT = FieldType->getAs<RecordType>();
+ if (!RT)
+ return;
+
+ CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+ if (FieldClassDecl->isInvalidDecl())
+ return;
+ if (FieldClassDecl->hasIrrelevantDestructor())
+ return;
+ // The destructor for an implicit anonymous union member is never invoked.
+ if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
+ return;
+
+ CXXDestructorDecl *Dtor = S.LookupDestructor(FieldClassDecl);
+ // Dtor might still be missing, e.g because it's invalid.
+ 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 RecordType *, 8> DirectVirtualBases;
+
+ // Bases.
+ for (const auto &Base : ClassDecl->bases()) {
+ const RecordType *RT = Base.getType()->getAs<RecordType>();
+ if (!RT)
+ continue;
+
+ // Remember direct virtual bases.
+ if (Base.isVirtual()) {
+ if (!VisitVirtualBases)
+ continue;
+ DirectVirtualBases.insert(RT);
+ }
+
+ CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+ // If our base class is invalid, we probably can't get its dtor anyway.
+ if (BaseClassDecl->isInvalidDecl())
----------------
erichkeane wrote:
Everything from type->`DiagnoseUseofDecl` seems to be the same as in the function above. I'd prefer we extract THAT into at least a static function and just call it from the other two.
https://github.com/llvm/llvm-project/pull/128866
More information about the cfe-commits
mailing list