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