@@ -5451,10 +5451,31 @@ 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 *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+ }
54545476 // Constructors implicitly reference the base and member
54555477 // destructors.
5456- MarkBaseAndMemberDestructorsReferenced(Constructor->getLocation(),
5457- Constructor->getParent());
5478+ MarkBaseAndMemberDestructorsReferenced(Location, Constructor->getParent());
54585479 }
54595480
54605481 return HadError;
@@ -5759,6 +5780,42 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
57595780 DiagnoseUninitializedFields(*this, Constructor);
57605781}
57615782
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+
57625819void
57635820Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
57645821 CXXRecordDecl *ClassDecl) {
@@ -5774,39 +5831,7 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
57745831
57755832 // Non-static data members.
57765833 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);
58105835 }
58115836
58125837 // We only potentially invoke the destructors of potentially constructed
0 commit comments