@@ -1806,6 +1806,7 @@ static unsigned getRecordDiagFromTagKind(TagTypeKind Tag) {
18061806static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
18071807 Stmt *Body,
18081808 Sema::CheckConstexprKind Kind);
1809+ static bool CheckConstexprMissingReturn(Sema &SemaRef, const FunctionDecl *Dcl);
18091810
18101811// Check whether a function declaration satisfies the requirements of a
18111812// constexpr function definition or a constexpr constructor definition. If so,
@@ -2411,20 +2412,9 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
24112412 }
24122413 } else {
24132414 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());
24212415 switch (Kind) {
24222416 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))
24282418 return false;
24292419 break;
24302420
@@ -2494,6 +2484,28 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
24942484 return true;
24952485}
24962486
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+
24972509bool Sema::CheckImmediateEscalatingFunctionDefinition(
24982510 FunctionDecl *FD, const sema::FunctionScopeInfo *FSI) {
24992511 if (!getLangOpts().CPlusPlus20 || !FD->isImmediateEscalating())
0 commit comments