@@ -7381,7 +7381,7 @@ hasSuitableMoveAssignmentOperatorForRelocation(Sema &SemaRef, CXXRecordDecl *D,
73817381// type C selects an assignment operator function that is a direct member of C
73827382// and is neither user-provided nor deleted, and C has a destructor that is
73837383// neither user-provided nor deleted.
7384- static bool isDefaultMovable(Sema &SemaRef, CXXRecordDecl *D) {
7384+ static bool isDefaultMovable(Sema &SemaRef, CXXRecordDecl *D, CXXDestructorDecl* Dtr ) {
73857385 if (!hasSuitableConstructorForRelocation(SemaRef, D,
73867386 /*AllowUserDefined=*/false))
73877387 return false;
@@ -7390,7 +7390,6 @@ static bool isDefaultMovable(Sema &SemaRef, CXXRecordDecl *D) {
73907390 SemaRef, D, /*AllowUserDefined=*/false))
73917391 return false;
73927392
7393- const auto *Dtr = D->getDestructor();
73947393 if (!Dtr)
73957394 return true;
73967395
@@ -7426,9 +7425,7 @@ static bool isEligibleForTrivialRelocation(Sema &SemaRef, CXXRecordDecl *D) {
74267425 SemaRef.getASTContext()))
74277426 return false;
74287427 }
7429-
7430- // ...has a deleted destructor
7431- return !D->hasDeletedDestructor();
7428+ return true;
74327429}
74337430
74347431// [C++26][class.prop]
@@ -7452,9 +7449,7 @@ static bool isEligibleForReplacement(Sema &SemaRef, CXXRecordDecl *D) {
74527449 if (!Field->getType().isReplaceableType(SemaRef.getASTContext()))
74537450 return false;
74547451 }
7455-
7456- // it has a deleted destructor.
7457- return !D->hasDeletedDestructor();
7452+ return true;
74587453}
74597454
74607455void Sema::CheckCXX2CRelocatableAndReplaceable(CXXRecordDecl *D) {
@@ -7466,6 +7461,7 @@ void Sema::CheckCXX2CRelocatableAndReplaceable(CXXRecordDecl *D) {
74667461 bool MarkedCXX2CReplaceable = D->hasAttr<ReplaceableAttr>();
74677462 bool MarkedTriviallyRelocatable = D->hasAttr<TriviallyRelocatableAttr>();
74687463
7464+
74697465 // This is part of "eligible for replacement", however we defer it
74707466 // to avoid extraneous computations.
74717467 auto HasSuitableSMP = [&] {
@@ -7484,9 +7480,15 @@ void Sema::CheckCXX2CRelocatableAndReplaceable(CXXRecordDecl *D) {
74847480 return *Is;
74857481 };
74867482
7483+ auto GetDestructor = [&, Dtr = static_cast<CXXDestructorDecl*>(nullptr)]() mutable {
7484+ if(!Dtr)
7485+ Dtr = D->getDestructor();
7486+ return Dtr;
7487+ };
7488+
74877489 auto IsDefaultMovable = [&, Is = std::optional<bool>{}]() mutable {
74887490 if (!Is.has_value())
7489- Is = isDefaultMovable(*this, D);
7491+ Is = isDefaultMovable(*this, D, GetDestructor() );
74907492 return *Is;
74917493 };
74927494
@@ -7498,6 +7500,9 @@ void Sema::CheckCXX2CRelocatableAndReplaceable(CXXRecordDecl *D) {
74987500 if (!isEligibleForTrivialRelocation(*this, D))
74997501 return false;
75007502
7503+ if(auto* Dtr = GetDestructor(); Dtr && Dtr->isDeleted())
7504+ return false;
7505+
75017506 // has the trivially_relocatable_if_eligible class-property-specifier,
75027507 if (MarkedTriviallyRelocatable)
75037508 return true;
@@ -7520,6 +7525,9 @@ void Sema::CheckCXX2CRelocatableAndReplaceable(CXXRecordDecl *D) {
75207525 if (!isEligibleForReplacement(*this, D))
75217526 return false;
75227527
7528+ if(auto* Dtr = GetDestructor(); Dtr && Dtr->isDeleted())
7529+ return false;
7530+
75237531 // has the replaceable_if_eligible class-property-specifier
75247532 if (MarkedCXX2CReplaceable)
75257533 return HasSuitableSMP();
0 commit comments