@@ -1715,6 +1715,8 @@ static bool CheckLiteralType(Sema &SemaRef, Sema::CheckConstexprKind Kind,
17151715static bool CheckConstexprDestructorSubobjects(Sema &SemaRef,
17161716 const CXXDestructorDecl *DD,
17171717 Sema::CheckConstexprKind Kind) {
1718+ assert(!SemaRef.getLangOpts().CPlusPlus23 &&
1719+ "this check is obsolete for C++23");
17181720 auto Check = [&](SourceLocation Loc, QualType T, const FieldDecl *FD) {
17191721 const CXXRecordDecl *RD =
17201722 T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
@@ -1746,6 +1748,8 @@ static bool CheckConstexprDestructorSubobjects(Sema &SemaRef,
17461748static bool CheckConstexprParameterTypes(Sema &SemaRef,
17471749 const FunctionDecl *FD,
17481750 Sema::CheckConstexprKind Kind) {
1751+ assert(!SemaRef.getLangOpts().CPlusPlus23 &&
1752+ "this check is obsolete for C++23");
17491753 unsigned ArgIndex = 0;
17501754 const auto *FT = FD->getType()->castAs<FunctionProtoType>();
17511755 for (FunctionProtoType::param_type_iterator i = FT->param_type_begin(),
@@ -1767,6 +1771,8 @@ static bool CheckConstexprParameterTypes(Sema &SemaRef,
17671771/// true. If not, produce a suitable diagnostic and return false.
17681772static bool CheckConstexprReturnType(Sema &SemaRef, const FunctionDecl *FD,
17691773 Sema::CheckConstexprKind Kind) {
1774+ assert(!SemaRef.getLangOpts().CPlusPlus23 &&
1775+ "this check is obsolete for C++23");
17701776 if (CheckLiteralType(SemaRef, Kind, FD->getLocation(), FD->getReturnType(),
17711777 diag::err_constexpr_non_literal_return,
17721778 FD->isConsteval()))
@@ -1856,25 +1862,28 @@ bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD,
18561862 }
18571863 }
18581864
1859- // - its return type shall be a literal type;
1860- if (!CheckConstexprReturnType(*this, NewFD, Kind))
1865+ // - its return type shall be a literal type; (removed in C++23)
1866+ if (!getLangOpts().CPlusPlus23 &&
1867+ !CheckConstexprReturnType(*this, NewFD, Kind))
18611868 return false;
18621869 }
18631870
18641871 if (auto *Dtor = dyn_cast<CXXDestructorDecl>(NewFD)) {
18651872 // A destructor can be constexpr only if the defaulted destructor could be;
18661873 // we don't need to check the members and bases if we already know they all
1867- // have constexpr destructors.
1868- if (!Dtor->getParent()->defaultedDestructorIsConstexpr()) {
1874+ // have constexpr destructors. (removed in C++23)
1875+ if (!getLangOpts().CPlusPlus23 &&
1876+ !Dtor->getParent()->defaultedDestructorIsConstexpr()) {
18691877 if (Kind == CheckConstexprKind::CheckValid)
18701878 return false;
18711879 if (!CheckConstexprDestructorSubobjects(*this, Dtor, Kind))
18721880 return false;
18731881 }
18741882 }
18751883
1876- // - each of its parameter types shall be a literal type;
1877- if (!CheckConstexprParameterTypes(*this, NewFD, Kind))
1884+ // - each of its parameter types shall be a literal type; (removed in C++23)
1885+ if (!getLangOpts().CPlusPlus23 &&
1886+ !CheckConstexprParameterTypes(*this, NewFD, Kind))
18781887 return false;
18791888
18801889 Stmt *Body = NewFD->getBody();
@@ -2457,7 +2466,8 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
24572466 // function", so is not checked in CheckValid mode.
24582467 SmallVector<PartialDiagnosticAt, 8> Diags;
24592468 if (Kind == Sema::CheckConstexprKind::Diagnose &&
2460- !Expr::isPotentialConstantExpr(Dcl, Diags)) {
2469+ !Expr::isPotentialConstantExpr(Dcl, Diags) &&
2470+ !SemaRef.getLangOpts().CPlusPlus23) {
24612471 SemaRef.Diag(Dcl->getLocation(),
24622472 diag::ext_constexpr_function_never_constant_expr)
24632473 << isa<CXXConstructorDecl>(Dcl) << Dcl->isConsteval()
@@ -7535,21 +7545,23 @@ static bool defaultedSpecialMemberIsConstexpr(
75357545
75367546 // C++1y [class.copy]p26:
75377547 // -- [the class] is a literal type, and
7538- if (!Ctor && !ClassDecl->isLiteral())
7548+ if (!Ctor && !ClassDecl->isLiteral() && !S.getLangOpts().CPlusPlus23 )
75397549 return false;
75407550
75417551 // -- every constructor involved in initializing [...] base class
75427552 // sub-objects shall be a constexpr constructor;
75437553 // -- the assignment operator selected to copy/move each direct base
75447554 // class is a constexpr function, and
7545- for (const auto &B : ClassDecl->bases()) {
7546- const RecordType *BaseType = B.getType()->getAs<RecordType>();
7547- if (!BaseType)
7548- continue;
7549- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
7550- if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, 0, ConstArg,
7551- InheritedCtor, Inherited))
7552- return false;
7555+ if (!S.getLangOpts().CPlusPlus23) {
7556+ for (const auto &B : ClassDecl->bases()) {
7557+ const RecordType *BaseType = B.getType()->getAs<RecordType>();
7558+ if (!BaseType)
7559+ continue;
7560+ CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
7561+ if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, 0, ConstArg,
7562+ InheritedCtor, Inherited))
7563+ return false;
7564+ }
75537565 }
75547566
75557567 // -- every constructor involved in initializing non-static data members
@@ -7559,20 +7571,22 @@ static bool defaultedSpecialMemberIsConstexpr(
75597571 // -- for each non-static data member of X that is of class type (or array
75607572 // thereof), the assignment operator selected to copy/move that member is
75617573 // a constexpr function
7562- for (const auto *F : ClassDecl->fields()) {
7563- if (F->isInvalidDecl())
7564- continue;
7565- if (CSM == Sema::CXXDefaultConstructor && F->hasInClassInitializer())
7566- continue;
7567- QualType BaseType = S.Context.getBaseElementType(F->getType());
7568- if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
7569- CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
7570- if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM,
7571- BaseType.getCVRQualifiers(),
7572- ConstArg && !F->isMutable()))
7574+ if (!S.getLangOpts().CPlusPlus23) {
7575+ for (const auto *F : ClassDecl->fields()) {
7576+ if (F->isInvalidDecl())
7577+ continue;
7578+ if (CSM == Sema::CXXDefaultConstructor && F->hasInClassInitializer())
7579+ continue;
7580+ QualType BaseType = S.Context.getBaseElementType(F->getType());
7581+ if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
7582+ CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
7583+ if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM,
7584+ BaseType.getCVRQualifiers(),
7585+ ConstArg && !F->isMutable()))
7586+ return false;
7587+ } else if (CSM == Sema::CXXDefaultConstructor) {
75737588 return false;
7574- } else if (CSM == Sema::CXXDefaultConstructor) {
7575- return false;
7589+ }
75767590 }
75777591 }
75787592
@@ -7858,18 +7872,17 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
78587872 MD->isConstexpr() && !Constexpr &&
78597873 MD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) {
78607874 if (!MD->isConsteval() && RD->getNumVBases()) {
7861- Diag(MD->getBeginLoc(), diag::err_incorrect_defaulted_constexpr_with_vb)
7875+ Diag(MD->getBeginLoc(),
7876+ diag::err_incorrect_defaulted_constexpr_with_vb)
78627877 << CSM;
78637878 for (const auto &I : RD->vbases())
78647879 Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here);
78657880 } else {
7866- Diag(MD->getBeginLoc(), MD->isConsteval()
7867- ? diag::err_incorrect_defaulted_consteval
7868- : diag::err_incorrect_defaulted_constexpr)
7869- << CSM;
7881+ Diag(MD->getBeginLoc(), diag::err_incorrect_defaulted_constexpr)
7882+ << CSM << MD->isConsteval();
78707883 }
7871- // FIXME: Explain why the special member can't be constexpr.
7872- HadError = true;
7884+ HadError = true;
7885+ // FIXME: Explain why the special member can't be constexpr.
78737886 }
78747887
78757888 if (First) {
@@ -9101,13 +9114,11 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
91019114 // - if the function is a constructor or destructor, its class does not
91029115 // have any virtual base classes.
91039116 if (FD->isConstexpr()) {
9104- if (CheckConstexprReturnType(*this, FD, CheckConstexprKind::Diagnose) &&
9117+ if (!getLangOpts().CPlusPlus23 &&
9118+ CheckConstexprReturnType(*this, FD, CheckConstexprKind::Diagnose) &&
91059119 CheckConstexprParameterTypes(*this, FD, CheckConstexprKind::Diagnose) &&
91069120 !Info.Constexpr) {
9107- Diag(FD->getBeginLoc(),
9108- getLangOpts().CPlusPlus23
9109- ? diag::warn_cxx23_compat_defaulted_comparison_constexpr_mismatch
9110- : diag::ext_defaulted_comparison_constexpr_mismatch)
9121+ Diag(FD->getBeginLoc(), diag::err_defaulted_comparison_constexpr_mismatch)
91119122 << FD->isImplicit() << (int)DCK << FD->isConsteval();
91129123 DefaultedComparisonAnalyzer(*this, RD, FD, DCK,
91139124 DefaultedComparisonAnalyzer::ExplainConstexpr)
0 commit comments