@@ -95,6 +95,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
95
95
HasDefaultedDefaultConstructor(false ),
96
96
DefaultedDefaultConstructorIsConstexpr(true ),
97
97
HasConstexprDefaultConstructor(false ),
98
+ DefaultedDestructorIsConstexpr(true ),
98
99
HasNonLiteralTypeFieldsOrBases(false ), ComputedVisibleConversions(false ),
99
100
UserProvidedDefaultConstructor(false ), DeclaredSpecialMembers(0 ),
100
101
ImplicitCopyConstructorCanHaveConstParamForVBase(true ),
@@ -325,10 +326,12 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
325
326
data ().IsStandardLayout = false ;
326
327
data ().IsCXX11StandardLayout = false ;
327
328
328
- // C++11 [dcl.constexpr]p4:
329
- // In the definition of a constexpr constructor [...]
330
- // -- the class shall not have any virtual base classes
329
+ // C++20 [dcl.constexpr]p3:
330
+ // In the definition of a constexpr function [...]
331
+ // -- if the function is a constructor or destructor,
332
+ // its class shall not have any virtual base classes
331
333
data ().DefaultedDefaultConstructorIsConstexpr = false ;
334
+ data ().DefaultedDestructorIsConstexpr = false ;
332
335
333
336
// C++1z [class.copy]p8:
334
337
// The implicitly-declared copy constructor for a class X will have
@@ -520,6 +523,19 @@ void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
520
523
data ().NeedOverloadResolutionForMoveConstructor = true ;
521
524
data ().NeedOverloadResolutionForDestructor = true ;
522
525
}
526
+
527
+ // C++2a [dcl.constexpr]p4:
528
+ // The definition of a constexpr destructor [shall] satisfy the
529
+ // following requirement:
530
+ // -- for every subobject of class type or (possibly multi-dimensional)
531
+ // array thereof, that class type shall have a constexpr destructor
532
+ if (!Subobj->hasConstexprDestructor ())
533
+ data ().DefaultedDestructorIsConstexpr = false ;
534
+ }
535
+
536
+ bool CXXRecordDecl::hasConstexprDestructor () const {
537
+ auto *Dtor = getDestructor ();
538
+ return Dtor ? Dtor->isConstexpr () : defaultedDestructorIsConstexpr ();
523
539
}
524
540
525
541
bool CXXRecordDecl::hasAnyDependentBases () const {
@@ -2571,20 +2587,19 @@ CXXDestructorDecl *
2571
2587
CXXDestructorDecl::CreateDeserialized (ASTContext &C, unsigned ID) {
2572
2588
return new (C, ID)
2573
2589
CXXDestructorDecl (C, nullptr , SourceLocation (), DeclarationNameInfo (),
2574
- QualType (), nullptr , false , false );
2590
+ QualType (), nullptr , false , false , CSK_unspecified );
2575
2591
}
2576
2592
2577
- CXXDestructorDecl *
2578
- CXXDestructorDecl::Create (ASTContext &C, CXXRecordDecl *RD,
2579
- SourceLocation StartLoc,
2580
- const DeclarationNameInfo &NameInfo,
2581
- QualType T, TypeSourceInfo *TInfo,
2582
- bool isInline, bool isImplicitlyDeclared) {
2593
+ CXXDestructorDecl *CXXDestructorDecl::Create (
2594
+ ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
2595
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2596
+ bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind) {
2583
2597
assert (NameInfo.getName ().getNameKind ()
2584
2598
== DeclarationName::CXXDestructorName &&
2585
2599
" Name must refer to a destructor" );
2586
- return new (C, RD) CXXDestructorDecl (C, RD, StartLoc, NameInfo, T, TInfo,
2587
- isInline, isImplicitlyDeclared);
2600
+ return new (C, RD)
2601
+ CXXDestructorDecl (C, RD, StartLoc, NameInfo, T, TInfo, isInline,
2602
+ isImplicitlyDeclared, ConstexprKind);
2588
2603
}
2589
2604
2590
2605
void CXXDestructorDecl::setOperatorDelete (FunctionDecl *OD, Expr *ThisArg) {
0 commit comments