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