Skip to content

Commit 5e5184a

Browse files
committed
Instantiate initialized field destructors
1 parent 3f64899 commit 5e5184a

File tree

2 files changed

+55
-35
lines changed

2 files changed

+55
-35
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5432,6 +5432,8 @@ class Sema final : public SemaBase {
54325432
void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
54335433
CXXRecordDecl *Record);
54345434

5435+
void MarkFieldDestructorReferenced(SourceLocation Loc, FieldDecl *Field);
5436+
54355437
/// Mark destructors of virtual bases of this class referenced. In the Itanium
54365438
/// C++ ABI, this is done when emitting a destructor for any non-abstract
54375439
/// class. In the Microsoft C++ ABI, this is done any time a class's

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 53 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5451,10 +5451,23 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
54515451
NumInitializers * sizeof(CXXCtorInitializer*));
54525452
Constructor->setCtorInitializers(baseOrMemberInitializers);
54535453

5454+
SourceLocation Location = Constructor->getLocation();
5455+
5456+
for (CXXCtorInitializer *Initializer : Info.AllToInit) {
5457+
FieldDecl *Field = Initializer->getAnyMember();
5458+
if (!Field)
5459+
continue;
5460+
5461+
RecordDecl *FieldRecordDecl = Field->getParent();
5462+
if (!FieldRecordDecl->isUnion() ||
5463+
!FieldRecordDecl->isAnonymousStructOrUnion())
5464+
continue;
5465+
5466+
MarkFieldDestructorReferenced(Location, Field);
5467+
}
54545468
// Constructors implicitly reference the base and member
54555469
// destructors.
5456-
MarkBaseAndMemberDestructorsReferenced(Constructor->getLocation(),
5457-
Constructor->getParent());
5470+
MarkBaseAndMemberDestructorsReferenced(Location, Constructor->getParent());
54585471
}
54595472

54605473
return HadError;
@@ -5759,6 +5772,43 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
57595772
DiagnoseUninitializedFields(*this, Constructor);
57605773
}
57615774

5775+
5776+
void Sema::MarkFieldDestructorReferenced(SourceLocation Location,
5777+
FieldDecl *Field) {
5778+
if (Field->isInvalidDecl())
5779+
return;
5780+
5781+
// Don't destroy incomplete or zero-length arrays.
5782+
if (isIncompleteOrZeroLengthArrayType(Context, Field->getType()))
5783+
return;
5784+
5785+
QualType FieldType = Context.getBaseElementType(Field->getType());
5786+
5787+
const RecordType *RT = FieldType->getAs<RecordType>();
5788+
if (!RT)
5789+
return;
5790+
5791+
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5792+
if (FieldClassDecl->isInvalidDecl())
5793+
return;
5794+
if (FieldClassDecl->hasIrrelevantDestructor())
5795+
return;
5796+
// The destructor for an implicit anonymous union member is never invoked.
5797+
if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
5798+
return;
5799+
5800+
CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl);
5801+
// Dtor might still be missing, e.g because it's invalid.
5802+
if (!Dtor)
5803+
return;
5804+
CheckDestructorAccess(Field->getLocation(), Dtor,
5805+
PDiag(diag::err_access_dtor_field)
5806+
<< Field->getDeclName() << FieldType);
5807+
5808+
MarkFunctionReferenced(Location, Dtor);
5809+
DiagnoseUseOfDecl(Dtor, Location);
5810+
}
5811+
57625812
void
57635813
Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
57645814
CXXRecordDecl *ClassDecl) {
@@ -5774,39 +5824,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
57745824

57755825
// Non-static data members.
57765826
for (auto *Field : ClassDecl->fields()) {
5777-
if (Field->isInvalidDecl())
5778-
continue;
5779-
5780-
// Don't destroy incomplete or zero-length arrays.
5781-
if (isIncompleteOrZeroLengthArrayType(Context, Field->getType()))
5782-
continue;
5783-
5784-
QualType FieldType = Context.getBaseElementType(Field->getType());
5785-
5786-
const RecordType* RT = FieldType->getAs<RecordType>();
5787-
if (!RT)
5788-
continue;
5789-
5790-
CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5791-
if (FieldClassDecl->isInvalidDecl())
5792-
continue;
5793-
if (FieldClassDecl->hasIrrelevantDestructor())
5794-
continue;
5795-
// The destructor for an implicit anonymous union member is never invoked.
5796-
if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
5797-
continue;
5798-
5799-
CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl);
5800-
// Dtor might still be missing, e.g because it's invalid.
5801-
if (!Dtor)
5802-
continue;
5803-
CheckDestructorAccess(Field->getLocation(), Dtor,
5804-
PDiag(diag::err_access_dtor_field)
5805-
<< Field->getDeclName()
5806-
<< FieldType);
5807-
5808-
MarkFunctionReferenced(Location, Dtor);
5809-
DiagnoseUseOfDecl(Dtor, Location);
5827+
MarkFieldDestructorReferenced(Location, Field);
58105828
}
58115829

58125830
// We only potentially invoke the destructors of potentially constructed

0 commit comments

Comments
 (0)