@@ -5450,10 +5450,31 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
5450
5450
NumInitializers * sizeof(CXXCtorInitializer*));
5451
5451
Constructor->setCtorInitializers(baseOrMemberInitializers);
5452
5452
5453
+ SourceLocation Location = Constructor->getLocation();
5454
+
5455
+ for (CXXCtorInitializer *Initializer : Info.AllToInit) {
5456
+ FieldDecl *Field = Initializer->getAnyMember();
5457
+ if (!Field)
5458
+ continue;
5459
+
5460
+ RecordDecl *Parent = Field->getParent();
5461
+
5462
+ while (Parent) {
5463
+ if (Parent->isUnion()) {
5464
+ MarkFieldDestructorReferenced(Location, Field);
5465
+ break;
5466
+ }
5467
+
5468
+ if (!Parent->isAnonymousStructOrUnion() || Parent == ClassDecl) {
5469
+ break;
5470
+ }
5471
+
5472
+ Parent = cast<RecordDecl>(Parent->getDeclContext());
5473
+ }
5474
+ }
5453
5475
// Constructors implicitly reference the base and member
5454
5476
// destructors.
5455
- MarkBaseAndMemberDestructorsReferenced(Constructor->getLocation(),
5456
- Constructor->getParent());
5477
+ MarkBaseAndMemberDestructorsReferenced(Location, Constructor->getParent());
5457
5478
}
5458
5479
5459
5480
return HadError;
@@ -5758,6 +5779,42 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
5758
5779
DiagnoseUninitializedFields(*this, Constructor);
5759
5780
}
5760
5781
5782
+ void Sema::MarkFieldDestructorReferenced(SourceLocation Location,
5783
+ FieldDecl *Field) {
5784
+ if (Field->isInvalidDecl())
5785
+ return;
5786
+
5787
+ // Don't destroy incomplete or zero-length arrays.
5788
+ if (isIncompleteOrZeroLengthArrayType(Context, Field->getType()))
5789
+ return;
5790
+
5791
+ QualType FieldType = Context.getBaseElementType(Field->getType());
5792
+
5793
+ const RecordType *RT = FieldType->getAs<RecordType>();
5794
+ if (!RT)
5795
+ return;
5796
+
5797
+ CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5798
+ if (FieldClassDecl->isInvalidDecl())
5799
+ return;
5800
+ if (FieldClassDecl->hasIrrelevantDestructor())
5801
+ return;
5802
+ // The destructor for an implicit anonymous union member is never invoked.
5803
+ if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
5804
+ return;
5805
+
5806
+ CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl);
5807
+ // Dtor might still be missing, e.g because it's invalid.
5808
+ if (!Dtor)
5809
+ return;
5810
+ CheckDestructorAccess(Field->getLocation(), Dtor,
5811
+ PDiag(diag::err_access_dtor_field)
5812
+ << Field->getDeclName() << FieldType);
5813
+
5814
+ MarkFunctionReferenced(Location, Dtor);
5815
+ DiagnoseUseOfDecl(Dtor, Location);
5816
+ }
5817
+
5761
5818
void
5762
5819
Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
5763
5820
CXXRecordDecl *ClassDecl) {
@@ -5773,39 +5830,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
5773
5830
5774
5831
// Non-static data members.
5775
5832
for (auto *Field : ClassDecl->fields()) {
5776
- if (Field->isInvalidDecl())
5777
- continue;
5778
-
5779
- // Don't destroy incomplete or zero-length arrays.
5780
- if (isIncompleteOrZeroLengthArrayType(Context, Field->getType()))
5781
- continue;
5782
-
5783
- QualType FieldType = Context.getBaseElementType(Field->getType());
5784
-
5785
- const RecordType* RT = FieldType->getAs<RecordType>();
5786
- if (!RT)
5787
- continue;
5788
-
5789
- CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5790
- if (FieldClassDecl->isInvalidDecl())
5791
- continue;
5792
- if (FieldClassDecl->hasIrrelevantDestructor())
5793
- continue;
5794
- // The destructor for an implicit anonymous union member is never invoked.
5795
- if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
5796
- continue;
5797
-
5798
- CXXDestructorDecl *Dtor = LookupDestructor(FieldClassDecl);
5799
- // Dtor might still be missing, e.g because it's invalid.
5800
- if (!Dtor)
5801
- continue;
5802
- CheckDestructorAccess(Field->getLocation(), Dtor,
5803
- PDiag(diag::err_access_dtor_field)
5804
- << Field->getDeclName()
5805
- << FieldType);
5806
-
5807
- MarkFunctionReferenced(Location, Dtor);
5808
- DiagnoseUseOfDecl(Dtor, Location);
5833
+ MarkFieldDestructorReferenced(Location, Field);
5809
5834
}
5810
5835
5811
5836
// We only potentially invoke the destructors of potentially constructed
0 commit comments