@@ -5286,6 +5286,17 @@ Sema::SetDelegatingInitializer(CXXConstructorDecl *Constructor,
5286
5286
return false;
5287
5287
}
5288
5288
5289
+ static CXXDestructorDecl *LookupDestructorIfRelevant(Sema &S,
5290
+ CXXRecordDecl *Class) {
5291
+ if (Class->isInvalidDecl())
5292
+ return nullptr;
5293
+ if (Class->hasIrrelevantDestructor())
5294
+ return nullptr;
5295
+
5296
+ // Dtor might still be missing, e.g because it's invalid.
5297
+ return S.LookupDestructor(Class);
5298
+ }
5299
+
5289
5300
static void MarkFieldDestructorReferenced(Sema &S, SourceLocation Location,
5290
5301
FieldDecl *Field) {
5291
5302
if (Field->isInvalidDecl())
@@ -5297,23 +5308,18 @@ static void MarkFieldDestructorReferenced(Sema &S, SourceLocation Location,
5297
5308
5298
5309
QualType FieldType = S.Context.getBaseElementType(Field->getType());
5299
5310
5300
- const RecordType *RT = FieldType->getAs<RecordType> ();
5301
- if (!RT )
5311
+ auto *FieldClassDecl = FieldType->getAsCXXRecordDecl ();
5312
+ if (!FieldClassDecl )
5302
5313
return;
5303
5314
5304
- CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5305
- if (FieldClassDecl->isInvalidDecl())
5306
- return;
5307
- if (FieldClassDecl->hasIrrelevantDestructor())
5308
- return;
5309
5315
// The destructor for an implicit anonymous union member is never invoked.
5310
5316
if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
5311
5317
return;
5312
5318
5313
- CXXDestructorDecl *Dtor = S.LookupDestructor(FieldClassDecl);
5314
- // Dtor might still be missing, e.g because it's invalid.
5319
+ auto *Dtor = LookupDestructorIfRelevant(S, FieldClassDecl);
5315
5320
if (!Dtor)
5316
5321
return;
5322
+
5317
5323
S.CheckDestructorAccess(Field->getLocation(), Dtor,
5318
5324
S.PDiag(diag::err_access_dtor_field)
5319
5325
<< Field->getDeclName() << FieldType);
@@ -5340,30 +5346,22 @@ static void MarkBaseDestructorsReferenced(Sema &S, SourceLocation Location,
5340
5346
VisitVirtualBases = false;
5341
5347
}
5342
5348
5343
- llvm::SmallPtrSet<const RecordType *, 8> DirectVirtualBases;
5349
+ llvm::SmallPtrSet<const CXXRecordDecl *, 8> DirectVirtualBases;
5344
5350
5345
5351
// Bases.
5346
5352
for (const auto &Base : ClassDecl->bases()) {
5347
- const RecordType *RT = Base.getType()->getAs<RecordType> ();
5348
- if (!RT )
5353
+ auto *BaseClassDecl = Base.getType()->getAsCXXRecordDecl ();
5354
+ if (!BaseClassDecl )
5349
5355
continue;
5350
5356
5351
5357
// Remember direct virtual bases.
5352
5358
if (Base.isVirtual()) {
5353
5359
if (!VisitVirtualBases)
5354
5360
continue;
5355
- DirectVirtualBases.insert(RT );
5361
+ DirectVirtualBases.insert(BaseClassDecl );
5356
5362
}
5357
5363
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.
5364
+ auto *Dtor = LookupDestructorIfRelevant(S, BaseClassDecl);
5367
5365
if (!Dtor)
5368
5366
continue;
5369
5367
@@ -5562,8 +5560,7 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
5562
5560
// C++ [class.base.init]p12:
5563
5561
// In a non-delegating constructor, the destructor for each
5564
5562
// potentially constructed subobject of class type is potentially
5565
- // invoked
5566
- // ([class.dtor]).
5563
+ // invoked.
5567
5564
MarkFieldDestructorReferenced(*this, Location, Field);
5568
5565
}
5569
5566
@@ -5894,27 +5891,21 @@ void Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
5894
5891
5895
5892
void Sema::MarkVirtualBaseDestructorsReferenced(
5896
5893
SourceLocation Location, CXXRecordDecl *ClassDecl,
5897
- llvm::SmallPtrSetImpl<const RecordType *> *DirectVirtualBases) {
5894
+ llvm::SmallPtrSetImpl<const CXXRecordDecl *> *DirectVirtualBases) {
5898
5895
// Virtual bases.
5899
5896
for (const auto &VBase : ClassDecl->vbases()) {
5900
- // Bases are always records in a well-formed non-dependent class.
5901
- const RecordType *RT = VBase.getType()->castAs<RecordType>();
5902
-
5903
- // Ignore already visited direct virtual bases.
5904
- if (DirectVirtualBases && DirectVirtualBases->count(RT))
5897
+ auto *BaseClassDecl = VBase.getType()->getAsCXXRecordDecl();
5898
+ if (!BaseClassDecl)
5905
5899
continue;
5906
5900
5907
- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(RT->getDecl());
5908
- // If our base class is invalid, we probably can't get its dtor anyway.
5909
- if (BaseClassDecl->isInvalidDecl())
5910
- continue;
5911
- if (BaseClassDecl->hasIrrelevantDestructor())
5901
+ // Ignore already visited direct virtual bases.
5902
+ if (DirectVirtualBases && DirectVirtualBases->count(BaseClassDecl))
5912
5903
continue;
5913
5904
5914
- CXXDestructorDecl *Dtor = LookupDestructor(BaseClassDecl);
5915
- // Dtor might still be missing, e.g because it's invalid.
5905
+ auto *Dtor = LookupDestructorIfRelevant(*this, BaseClassDecl);
5916
5906
if (!Dtor)
5917
5907
continue;
5908
+
5918
5909
if (CheckDestructorAccess(
5919
5910
ClassDecl->getLocation(), Dtor,
5920
5911
PDiag(diag::err_access_dtor_vbase)
0 commit comments