@@ -1806,6 +1806,7 @@ static unsigned getRecordDiagFromTagKind(TagTypeKind Tag) {
1806
1806
static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
1807
1807
Stmt *Body,
1808
1808
Sema::CheckConstexprKind Kind);
1809
+ static bool CheckConstexprMissingReturn(Sema &SemaRef, const FunctionDecl *Dcl);
1809
1810
1810
1811
// Check whether a function declaration satisfies the requirements of a
1811
1812
// constexpr function definition or a constexpr constructor definition. If so,
@@ -2411,20 +2412,9 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
2411
2412
}
2412
2413
} else {
2413
2414
if (ReturnStmts.empty()) {
2414
- // C++1y doesn't require constexpr functions to contain a 'return'
2415
- // statement. We still do, unless the return type might be void, because
2416
- // otherwise if there's no return statement, the function cannot
2417
- // be used in a core constant expression.
2418
- bool OK = SemaRef.getLangOpts().CPlusPlus14 &&
2419
- (Dcl->getReturnType()->isVoidType() ||
2420
- Dcl->getReturnType()->isDependentType());
2421
2415
switch (Kind) {
2422
2416
case Sema::CheckConstexprKind::Diagnose:
2423
- SemaRef.Diag(Dcl->getLocation(),
2424
- OK ? diag::warn_cxx11_compat_constexpr_body_no_return
2425
- : diag::err_constexpr_body_no_return)
2426
- << Dcl->isConsteval();
2427
- if (!OK)
2417
+ if (!CheckConstexprMissingReturn(SemaRef, Dcl))
2428
2418
return false;
2429
2419
break;
2430
2420
@@ -2494,6 +2484,28 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
2494
2484
return true;
2495
2485
}
2496
2486
2487
+ static bool CheckConstexprMissingReturn(Sema &SemaRef,
2488
+ const FunctionDecl *Dcl) {
2489
+ bool IsVoidOrDependentType = Dcl->getReturnType()->isVoidType() ||
2490
+ Dcl->getReturnType()->isDependentType();
2491
+ // Skip emitting a missing return error diagnostic for non-void functions
2492
+ // since C++23 no longer mandates constexpr functions to yield constant
2493
+ // expressions.
2494
+ if (SemaRef.getLangOpts().CPlusPlus23 && !IsVoidOrDependentType)
2495
+ return true;
2496
+
2497
+ // C++14 doesn't require constexpr functions to contain a 'return'
2498
+ // statement. We still do, unless the return type might be void, because
2499
+ // otherwise if there's no return statement, the function cannot
2500
+ // be used in a core constant expression.
2501
+ bool OK = SemaRef.getLangOpts().CPlusPlus14 && IsVoidOrDependentType;
2502
+ SemaRef.Diag(Dcl->getLocation(),
2503
+ OK ? diag::warn_cxx11_compat_constexpr_body_no_return
2504
+ : diag::err_constexpr_body_no_return)
2505
+ << Dcl->isConsteval();
2506
+ return OK;
2507
+ }
2508
+
2497
2509
bool Sema::CheckImmediateEscalatingFunctionDefinition(
2498
2510
FunctionDecl *FD, const sema::FunctionScopeInfo *FSI) {
2499
2511
if (!getLangOpts().CPlusPlus20 || !FD->isImmediateEscalating())
0 commit comments