@@ -5289,6 +5289,102 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,
5289
5289
return false;
5290
5290
}
5291
5291
5292
+ static void MarkFieldDestructorReferenced(Sema &S, SourceLocation Location,
5293
+ FieldDecl *Field) {
5294
+ if (Field->isInvalidDecl())
5295
+ return;
5296
+
5297
+ // Don't destroy incomplete or zero-length arrays.
5298
+ if (isIncompleteOrZeroLengthArrayType(S.Context, Field->getType()))
5299
+ return;
5300
+
5301
+ QualType FieldType = S.Context.getBaseElementType(Field->getType());
5302
+
5303
+ const RecordType *RT = FieldType->getAs<RecordType>();
5304
+ if (!RT)
5305
+ return;
5306
+
5307
+ CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5308
+ if (FieldClassDecl->isInvalidDecl())
5309
+ return;
5310
+ if (FieldClassDecl->hasIrrelevantDestructor())
5311
+ return;
5312
+ // The destructor for an implicit anonymous union member is never invoked.
5313
+ if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
5314
+ return;
5315
+
5316
+ CXXDestructorDecl *Dtor = S.LookupDestructor(FieldClassDecl);
5317
+ // Dtor might still be missing, e.g because it's invalid.
5318
+ if (!Dtor)
5319
+ return;
5320
+ S.CheckDestructorAccess(Field->getLocation(), Dtor,
5321
+ S.PDiag(diag::err_access_dtor_field)
5322
+ << Field->getDeclName() << FieldType);
5323
+
5324
+ S.MarkFunctionReferenced(Location, Dtor);
5325
+ S.DiagnoseUseOfDecl(Dtor, Location);
5326
+ }
5327
+
5328
+ static void MarkBaseDestructorsReferenced(Sema &S, SourceLocation Location,
5329
+ CXXRecordDecl *ClassDecl) {
5330
+ if (ClassDecl->isDependentContext())
5331
+ return;
5332
+
5333
+ // We only potentially invoke the destructors of potentially constructed
5334
+ // subobjects.
5335
+ bool VisitVirtualBases = !ClassDecl->isAbstract();
5336
+
5337
+ // If the destructor exists and has already been marked used in the MS ABI,
5338
+ // then virtual base destructors have already been checked and marked used.
5339
+ // Skip checking them again to avoid duplicate diagnostics.
5340
+ if (S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
5341
+ CXXDestructorDecl *Dtor = ClassDecl->getDestructor();
5342
+ if (Dtor && Dtor->isUsed())
5343
+ VisitVirtualBases = false;
5344
+ }
5345
+
5346
+ llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
5347
+
5348
+ // Bases.
5349
+ for (const auto &Base : ClassDecl->bases()) {
5350
+ const RecordType *RT = Base.getType()->getAs<RecordType>();
5351
+ if (!RT)
5352
+ continue;
5353
+
5354
+ // Remember direct virtual bases.
5355
+ if (Base.isVirtual()) {
5356
+ if (!VisitVirtualBases)
5357
+ continue;
5358
+ DirectVirtualBases.insert(RT);
5359
+ }
5360
+
5361
+ CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5362
+ // If our base class is invalid, we probably can't get its dtor anyway.
5363
+ if (BaseClassDecl->isInvalidDecl())
5364
+ continue;
5365
+ if (BaseClassDecl->hasIrrelevantDestructor())
5366
+ continue;
5367
+
5368
+ CXXDestructorDecl *Dtor = S.LookupDestructor(BaseClassDecl);
5369
+ // Dtor might still be missing, e.g because it's invalid.
5370
+ if (!Dtor)
5371
+ continue;
5372
+
5373
+ // FIXME: caret should be on the start of the class name
5374
+ S.CheckDestructorAccess(Base.getBeginLoc(), Dtor,
5375
+ S.PDiag(diag::err_access_dtor_base)
5376
+ << Base.getType() << Base.getSourceRange(),
5377
+ S.Context.getTypeDeclType(ClassDecl));
5378
+
5379
+ S.MarkFunctionReferenced(Location, Dtor);
5380
+ S.DiagnoseUseOfDecl(Dtor, Location);
5381
+ }
5382
+
5383
+ if (VisitVirtualBases)
5384
+ S.MarkVirtualBaseDestructorsReferenced(Location, ClassDecl,
5385
+ &DirectVirtualBases);
5386
+ }
5387
+
5292
5388
bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
5293
5389
ArrayRef<CXXCtorInitializer *> Initializers) {
5294
5390
if (Constructor->isDependentContext()) {
@@ -5471,10 +5567,10 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
5471
5567
// potentially constructed subobject of class type is potentially
5472
5568
// invoked
5473
5569
// ([class.dtor]).
5474
- MarkFieldDestructorReferenced(Location, Field);
5570
+ MarkFieldDestructorReferenced(*this, Location, Field);
5475
5571
}
5476
5572
5477
- MarkBaseDestructorsReferenced(Location, Constructor->getParent());
5573
+ MarkBaseDestructorsReferenced(*this, Location, Constructor->getParent());
5478
5574
}
5479
5575
5480
5576
return HadError;
@@ -5779,102 +5875,6 @@ void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
5779
5875
DiagnoseUninitializedFields(*this, Constructor);
5780
5876
}
5781
5877
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
-
5818
- void Sema::MarkBaseDestructorsReferenced(SourceLocation Location,
5819
- CXXRecordDecl *ClassDecl) {
5820
- if (ClassDecl->isDependentContext())
5821
- return;
5822
-
5823
- // We only potentially invoke the destructors of potentially constructed
5824
- // subobjects.
5825
- bool VisitVirtualBases = !ClassDecl->isAbstract();
5826
-
5827
- // If the destructor exists and has already been marked used in the MS ABI,
5828
- // then virtual base destructors have already been checked and marked used.
5829
- // Skip checking them again to avoid duplicate diagnostics.
5830
- if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
5831
- CXXDestructorDecl *Dtor = ClassDecl->getDestructor();
5832
- if (Dtor && Dtor->isUsed())
5833
- VisitVirtualBases = false;
5834
- }
5835
-
5836
- llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
5837
-
5838
- // Bases.
5839
- for (const auto &Base : ClassDecl->bases()) {
5840
- const RecordType *RT = Base.getType()->getAs<RecordType>();
5841
- if (!RT)
5842
- continue;
5843
-
5844
- // Remember direct virtual bases.
5845
- if (Base.isVirtual()) {
5846
- if (!VisitVirtualBases)
5847
- continue;
5848
- DirectVirtualBases.insert(RT);
5849
- }
5850
-
5851
- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5852
- // If our base class is invalid, we probably can't get its dtor anyway.
5853
- if (BaseClassDecl->isInvalidDecl())
5854
- continue;
5855
- if (BaseClassDecl->hasIrrelevantDestructor())
5856
- continue;
5857
-
5858
- CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
5859
- // Dtor might still be missing, e.g because it's invalid.
5860
- if (!Dtor)
5861
- continue;
5862
-
5863
- // FIXME: caret should be on the start of the class name
5864
- CheckDestructorAccess(Base.getBeginLoc(), Dtor,
5865
- PDiag(diag::err_access_dtor_base)
5866
- << Base.getType() << Base.getSourceRange(),
5867
- Context.getTypeDeclType(ClassDecl));
5868
-
5869
- MarkFunctionReferenced(Location, Dtor);
5870
- DiagnoseUseOfDecl(Dtor, Location);
5871
- }
5872
-
5873
- if (VisitVirtualBases)
5874
- MarkVirtualBaseDestructorsReferenced(Location, ClassDecl,
5875
- &DirectVirtualBases);
5876
- }
5877
-
5878
5878
void Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
5879
5879
CXXRecordDecl *ClassDecl) {
5880
5880
// Ignore dependent contexts. Also ignore unions, since their members never
@@ -5889,10 +5889,10 @@ void Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
5889
5889
5890
5890
// Non-static data members.
5891
5891
for (auto *Field : ClassDecl->fields()) {
5892
- MarkFieldDestructorReferenced(Location, Field);
5892
+ MarkFieldDestructorReferenced(*this, Location, Field);
5893
5893
}
5894
5894
5895
- MarkBaseDestructorsReferenced(Location, ClassDecl);
5895
+ MarkBaseDestructorsReferenced(*this, Location, ClassDecl);
5896
5896
}
5897
5897
5898
5898
void Sema::MarkVirtualBaseDestructorsReferenced(
0 commit comments