Skip to content

Commit 90eeafc

Browse files
committed
feat(92583): [C++23] update constexpr diagnostics for missing return statements per P2448
1 parent 6e22b53 commit 90eeafc

File tree

4 files changed

+31
-14
lines changed

4 files changed

+31
-14
lines changed

clang/lib/Sema/SemaDeclCXX.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,7 @@ static unsigned getRecordDiagFromTagKind(TagTypeKind Tag) {
18061806
static 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

@@ -2487,6 +2477,26 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
24872477
return true;
24882478
}
24892479

2480+
static bool CheckConstexprMissingReturn(Sema &SemaRef,
2481+
const FunctionDecl *Dcl) {
2482+
bool IsVoidOrDependentType = Dcl->getReturnType()->isVoidType() ||
2483+
Dcl->getReturnType()->isDependentType();
2484+
2485+
if (SemaRef.getLangOpts().CPlusPlus23 && !IsVoidOrDependentType)
2486+
return true;
2487+
2488+
// C++1y doesn't require constexpr functions to contain a 'return'
2489+
// statement. We still do, unless the return type might be void, because
2490+
// otherwise if there's no return statement, the function cannot
2491+
// be used in a core constant expression.
2492+
bool OK = SemaRef.getLangOpts().CPlusPlus14 && IsVoidOrDependentType;
2493+
SemaRef.Diag(Dcl->getLocation(),
2494+
OK ? diag::warn_cxx11_compat_constexpr_body_no_return
2495+
: diag::err_constexpr_body_no_return)
2496+
<< Dcl->isConsteval();
2497+
return OK;
2498+
}
2499+
24902500
bool Sema::CheckImmediateEscalatingFunctionDefinition(
24912501
FunctionDecl *FD, const sema::FunctionScopeInfo *FSI) {
24922502
if (!getLangOpts().CPlusPlus20 || !FD->isImmediateEscalating())

clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ constexpr int ClassDecl3() {
212212
return 0;
213213
}
214214

215-
constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
215+
constexpr int NoReturn() {} // beforecxx23-error {{no return statement in constexpr function}}
216216
constexpr int MultiReturn() {
217217
return 0; // beforecxx14-note {{return statement}}
218218
return 0; // beforecxx14-warning {{multiple return statements in constexpr function}}

clang/test/SemaCXX/constant-expression-cxx14.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ constexpr void k() {
8282

8383
// If the return type is not 'void', no return statements => never a constant
8484
// expression, so still diagnose that case.
85-
[[noreturn]] constexpr int fn() { // expected-error {{no return statement in constexpr function}}
85+
[[noreturn]] constexpr int fn() { // cxx14_20-error {{no return statement in constexpr function}}
8686
fn();
8787
}
8888

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %clang_cc1 -Wno-return-type -std=c++23 -fsyntax-only -verify %s
2+
// expected-no-diagnostics
3+
constexpr int f() { }
4+
static_assert(__is_same(decltype([] constexpr -> int { }( )), int));
5+
6+
consteval int g() { }
7+
static_assert(__is_same(decltype([] consteval -> int { }( )), int));

0 commit comments

Comments
 (0)