@@ -1715,8 +1715,6 @@ 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");
17201718 auto Check = [&](SourceLocation Loc, QualType T, const FieldDecl *FD) {
17211719 const CXXRecordDecl *RD =
17221720 T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
@@ -1748,8 +1746,6 @@ static bool CheckConstexprDestructorSubobjects(Sema &SemaRef,
17481746static bool CheckConstexprParameterTypes(Sema &SemaRef,
17491747 const FunctionDecl *FD,
17501748 Sema::CheckConstexprKind Kind) {
1751- assert(!SemaRef.getLangOpts().CPlusPlus23 &&
1752- "this check is obsolete for C++23");
17531749 unsigned ArgIndex = 0;
17541750 const auto *FT = FD->getType()->castAs<FunctionProtoType>();
17551751 for (FunctionProtoType::param_type_iterator i = FT->param_type_begin(),
@@ -1771,8 +1767,6 @@ static bool CheckConstexprParameterTypes(Sema &SemaRef,
17711767/// true. If not, produce a suitable diagnostic and return false.
17721768static bool CheckConstexprReturnType(Sema &SemaRef, const FunctionDecl *FD,
17731769 Sema::CheckConstexprKind Kind) {
1774- assert(!SemaRef.getLangOpts().CPlusPlus23 &&
1775- "this check is obsolete for C++23");
17761770 if (CheckLiteralType(SemaRef, Kind, FD->getLocation(), FD->getReturnType(),
17771771 diag::err_constexpr_non_literal_return,
17781772 FD->isConsteval()))
@@ -1862,28 +1856,25 @@ bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD,
18621856 }
18631857 }
18641858
1865- // - its return type shall be a literal type; (removed in C++23)
1866- if (!getLangOpts().CPlusPlus23 &&
1867- !CheckConstexprReturnType(*this, NewFD, Kind))
1859+ // - its return type shall be a literal type;
1860+ if (!CheckConstexprReturnType(*this, NewFD, Kind))
18681861 return false;
18691862 }
18701863
18711864 if (auto *Dtor = dyn_cast<CXXDestructorDecl>(NewFD)) {
18721865 // A destructor can be constexpr only if the defaulted destructor could be;
18731866 // we don't need to check the members and bases if we already know they all
1874- // have constexpr destructors. (removed in C++23)
1875- if (!getLangOpts().CPlusPlus23 &&
1876- !Dtor->getParent()->defaultedDestructorIsConstexpr()) {
1867+ // have constexpr destructors.
1868+ if (!Dtor->getParent()->defaultedDestructorIsConstexpr()) {
18771869 if (Kind == CheckConstexprKind::CheckValid)
18781870 return false;
18791871 if (!CheckConstexprDestructorSubobjects(*this, Dtor, Kind))
18801872 return false;
18811873 }
18821874 }
18831875
1884- // - each of its parameter types shall be a literal type; (removed in C++23)
1885- if (!getLangOpts().CPlusPlus23 &&
1886- !CheckConstexprParameterTypes(*this, NewFD, Kind))
1876+ // - each of its parameter types shall be a literal type;
1877+ if (!CheckConstexprParameterTypes(*this, NewFD, Kind))
18871878 return false;
18881879
18891880 Stmt *Body = NewFD->getBody();
@@ -2466,8 +2457,7 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
24662457 // function", so is not checked in CheckValid mode.
24672458 SmallVector<PartialDiagnosticAt, 8> Diags;
24682459 if (Kind == Sema::CheckConstexprKind::Diagnose &&
2469- !Expr::isPotentialConstantExpr(Dcl, Diags) &&
2470- !SemaRef.getLangOpts().CPlusPlus23) {
2460+ !Expr::isPotentialConstantExpr(Dcl, Diags)) {
24712461 SemaRef.Diag(Dcl->getLocation(),
24722462 diag::ext_constexpr_function_never_constant_expr)
24732463 << isa<CXXConstructorDecl>(Dcl) << Dcl->isConsteval()
@@ -7545,23 +7535,21 @@ static bool defaultedSpecialMemberIsConstexpr(
75457535
75467536 // C++1y [class.copy]p26:
75477537 // -- [the class] is a literal type, and
7548- if (!Ctor && !ClassDecl->isLiteral() && !S.getLangOpts().CPlusPlus23 )
7538+ if (!Ctor && !ClassDecl->isLiteral())
75497539 return false;
75507540
75517541 // -- every constructor involved in initializing [...] base class
75527542 // sub-objects shall be a constexpr constructor;
75537543 // -- the assignment operator selected to copy/move each direct base
75547544 // class is a constexpr function, and
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- }
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;
75657553 }
75667554
75677555 // -- every constructor involved in initializing non-static data members
@@ -7571,22 +7559,20 @@ static bool defaultedSpecialMemberIsConstexpr(
75717559 // -- for each non-static data member of X that is of class type (or array
75727560 // thereof), the assignment operator selected to copy/move that member is
75737561 // a constexpr function
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) {
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()))
75887573 return false;
7589- }
7574+ } else if (CSM == Sema::CXXDefaultConstructor) {
7575+ return false;
75907576 }
75917577 }
75927578
@@ -7872,17 +7858,18 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
78727858 MD->isConstexpr() && !Constexpr &&
78737859 MD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) {
78747860 if (!MD->isConsteval() && RD->getNumVBases()) {
7875- Diag(MD->getBeginLoc(),
7876- diag::err_incorrect_defaulted_constexpr_with_vb)
7861+ Diag(MD->getBeginLoc(), diag::err_incorrect_defaulted_constexpr_with_vb)
78777862 << CSM;
78787863 for (const auto &I : RD->vbases())
78797864 Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here);
78807865 } else {
7881- Diag(MD->getBeginLoc(), diag::err_incorrect_defaulted_constexpr)
7882- << CSM << MD->isConsteval();
7866+ Diag(MD->getBeginLoc(), MD->isConsteval()
7867+ ? diag::err_incorrect_defaulted_consteval
7868+ : diag::err_incorrect_defaulted_constexpr)
7869+ << CSM;
78837870 }
7884- HadError = true;
7885- // FIXME: Explain why the special member can't be constexpr.
7871+ // FIXME: Explain why the special member can't be constexpr.
7872+ HadError = true;
78867873 }
78877874
78887875 if (First) {
@@ -9114,11 +9101,13 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
91149101 // - if the function is a constructor or destructor, its class does not
91159102 // have any virtual base classes.
91169103 if (FD->isConstexpr()) {
9117- if (!getLangOpts().CPlusPlus23 &&
9118- CheckConstexprReturnType(*this, FD, CheckConstexprKind::Diagnose) &&
9104+ if (CheckConstexprReturnType(*this, FD, CheckConstexprKind::Diagnose) &&
91199105 CheckConstexprParameterTypes(*this, FD, CheckConstexprKind::Diagnose) &&
91209106 !Info.Constexpr) {
9121- Diag(FD->getBeginLoc(), diag::err_defaulted_comparison_constexpr_mismatch)
9107+ Diag(FD->getBeginLoc(),
9108+ getLangOpts().CPlusPlus23
9109+ ? diag::warn_cxx23_compat_defaulted_comparison_constexpr_mismatch
9110+ : diag::ext_defaulted_comparison_constexpr_mismatch)
91229111 << FD->isImplicit() << (int)DCK << FD->isConsteval();
91239112 DefaultedComparisonAnalyzer(*this, RD, FD, DCK,
91249113 DefaultedComparisonAnalyzer::ExplainConstexpr)
0 commit comments