@@ -1715,8 +1715,6 @@ static bool CheckLiteralType(Sema &SemaRef, Sema::CheckConstexprKind Kind,
1715
1715
static bool CheckConstexprDestructorSubobjects(Sema &SemaRef,
1716
1716
const CXXDestructorDecl *DD,
1717
1717
Sema::CheckConstexprKind Kind) {
1718
- assert(!SemaRef.getLangOpts().CPlusPlus23 &&
1719
- "this check is obsolete for C++23");
1720
1718
auto Check = [&](SourceLocation Loc, QualType T, const FieldDecl *FD) {
1721
1719
const CXXRecordDecl *RD =
1722
1720
T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
@@ -1748,8 +1746,6 @@ static bool CheckConstexprDestructorSubobjects(Sema &SemaRef,
1748
1746
static bool CheckConstexprParameterTypes(Sema &SemaRef,
1749
1747
const FunctionDecl *FD,
1750
1748
Sema::CheckConstexprKind Kind) {
1751
- assert(!SemaRef.getLangOpts().CPlusPlus23 &&
1752
- "this check is obsolete for C++23");
1753
1749
unsigned ArgIndex = 0;
1754
1750
const auto *FT = FD->getType()->castAs<FunctionProtoType>();
1755
1751
for (FunctionProtoType::param_type_iterator i = FT->param_type_begin(),
@@ -1771,8 +1767,6 @@ static bool CheckConstexprParameterTypes(Sema &SemaRef,
1771
1767
/// true. If not, produce a suitable diagnostic and return false.
1772
1768
static bool CheckConstexprReturnType(Sema &SemaRef, const FunctionDecl *FD,
1773
1769
Sema::CheckConstexprKind Kind) {
1774
- assert(!SemaRef.getLangOpts().CPlusPlus23 &&
1775
- "this check is obsolete for C++23");
1776
1770
if (CheckLiteralType(SemaRef, Kind, FD->getLocation(), FD->getReturnType(),
1777
1771
diag::err_constexpr_non_literal_return,
1778
1772
FD->isConsteval()))
@@ -1862,28 +1856,25 @@ bool Sema::CheckConstexprFunctionDefinition(const FunctionDecl *NewFD,
1862
1856
}
1863
1857
}
1864
1858
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))
1868
1861
return false;
1869
1862
}
1870
1863
1871
1864
if (auto *Dtor = dyn_cast<CXXDestructorDecl>(NewFD)) {
1872
1865
// A destructor can be constexpr only if the defaulted destructor could be;
1873
1866
// 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()) {
1877
1869
if (Kind == CheckConstexprKind::CheckValid)
1878
1870
return false;
1879
1871
if (!CheckConstexprDestructorSubobjects(*this, Dtor, Kind))
1880
1872
return false;
1881
1873
}
1882
1874
}
1883
1875
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))
1887
1878
return false;
1888
1879
1889
1880
Stmt *Body = NewFD->getBody();
@@ -2466,8 +2457,7 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
2466
2457
// function", so is not checked in CheckValid mode.
2467
2458
SmallVector<PartialDiagnosticAt, 8> Diags;
2468
2459
if (Kind == Sema::CheckConstexprKind::Diagnose &&
2469
- !Expr::isPotentialConstantExpr(Dcl, Diags) &&
2470
- !SemaRef.getLangOpts().CPlusPlus23) {
2460
+ !Expr::isPotentialConstantExpr(Dcl, Diags)) {
2471
2461
SemaRef.Diag(Dcl->getLocation(),
2472
2462
diag::ext_constexpr_function_never_constant_expr)
2473
2463
<< isa<CXXConstructorDecl>(Dcl) << Dcl->isConsteval()
@@ -7545,23 +7535,21 @@ static bool defaultedSpecialMemberIsConstexpr(
7545
7535
7546
7536
// C++1y [class.copy]p26:
7547
7537
// -- [the class] is a literal type, and
7548
- if (!Ctor && !ClassDecl->isLiteral() && !S.getLangOpts().CPlusPlus23 )
7538
+ if (!Ctor && !ClassDecl->isLiteral())
7549
7539
return false;
7550
7540
7551
7541
// -- every constructor involved in initializing [...] base class
7552
7542
// sub-objects shall be a constexpr constructor;
7553
7543
// -- the assignment operator selected to copy/move each direct base
7554
7544
// 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;
7565
7553
}
7566
7554
7567
7555
// -- every constructor involved in initializing non-static data members
@@ -7571,22 +7559,20 @@ static bool defaultedSpecialMemberIsConstexpr(
7571
7559
// -- for each non-static data member of X that is of class type (or array
7572
7560
// thereof), the assignment operator selected to copy/move that member is
7573
7561
// 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()))
7588
7573
return false;
7589
- }
7574
+ } else if (CSM == Sema::CXXDefaultConstructor) {
7575
+ return false;
7590
7576
}
7591
7577
}
7592
7578
@@ -7872,17 +7858,18 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
7872
7858
MD->isConstexpr() && !Constexpr &&
7873
7859
MD->getTemplatedKind() == FunctionDecl::TK_NonTemplate) {
7874
7860
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)
7877
7862
<< CSM;
7878
7863
for (const auto &I : RD->vbases())
7879
7864
Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here);
7880
7865
} 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;
7883
7870
}
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;
7886
7873
}
7887
7874
7888
7875
if (First) {
@@ -9114,11 +9101,13 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
9114
9101
// - if the function is a constructor or destructor, its class does not
9115
9102
// have any virtual base classes.
9116
9103
if (FD->isConstexpr()) {
9117
- if (!getLangOpts().CPlusPlus23 &&
9118
- CheckConstexprReturnType(*this, FD, CheckConstexprKind::Diagnose) &&
9104
+ if (CheckConstexprReturnType(*this, FD, CheckConstexprKind::Diagnose) &&
9119
9105
CheckConstexprParameterTypes(*this, FD, CheckConstexprKind::Diagnose) &&
9120
9106
!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)
9122
9111
<< FD->isImplicit() << (int)DCK << FD->isConsteval();
9123
9112
DefaultedComparisonAnalyzer(*this, RD, FD, DCK,
9124
9113
DefaultedComparisonAnalyzer::ExplainConstexpr)
0 commit comments