[clang] [clang][constexpr] Allow IndirectGotoStmt in constexpr functions for C++23 (PR #213449)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 5 04:17:26 PDT 2026
https://github.com/babadany2999 updated https://github.com/llvm/llvm-project/pull/213449
>From db3e8ab18e94e552c4e48dc128373c66b9551491 Mon Sep 17 00:00:00 2001
From: Baba Dan Constantin <babadany2999 at gmail.com>
Date: Sat, 1 Aug 2026 17:09:50 +0300
Subject: [PATCH 1/3] [clang][constexpr] Allow IndirectGotoStmt in constexpr
functions for C++23
P2242R3 ("More Relaxed Constexpr Functions") permitted jump statements such as `goto` and labels inside `constexpr` functions starting in C++23. When handling `GotoStmtClass` and `LabelStmtClass` in `CheckConstexprFunctionStmt`, `IndirectGotoStmtClass` (GNU computed goto) was inadvertently omitted.
As a result, any indirect goto inside a `constexpr` function body hit the default case in `CheckConstexprFunctionStmt` and triggered an unrecoverable hard error (`err_constexpr_body_invalid_stmt`), even when placed in unexecuted branches (e.g. behind `if consteval`).
This commit adds `case Stmt::IndirectGotoStmtClass:` alongside `GotoStmtClass` so that indirect gotos are treated consistently:
- Permitted in C++23 `constexpr` functions.
- Allowed in earlier standard dialects (C++11/14/17/20) as a C++23 extension warning.
- Evaluated properly by constant evaluation (which rejects actual compile-time execution of computed gotos if reached).
Regression test added to `clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp`.
---
clang/lib/Sema/SemaDeclCXX.cpp | 1 +
clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp | 8 ++++++++
2 files changed, 9 insertions(+)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 47b01b913b428..76b3d8cca9701 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2343,6 +2343,7 @@ CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S,
case Stmt::LabelStmtClass:
case Stmt::GotoStmtClass:
+ case Stmt::IndirectGotoStmtClass:
if (Cxx2bLoc.isInvalid())
Cxx2bLoc = S->getBeginLoc();
for (Stmt *SubStmt : S->children()) {
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
index 51990ee4341d2..508941ae0429d 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -167,6 +167,14 @@ constexpr int DisallowedStmtsCXX14_7() {
int n; // beforecxx20-warning {{uninitialized variable in a constexpr function}}
}
+constexpr int DisallowedStmtsCXX14_8() {
+ return 0; // beforecxx14-note {{previous}}
+ // - an indirect goto statement
+ goto *(&&x); // beforecxx23-warning {{use of this statement in a constexpr function is a C++23 extension}}
+ x:;
+ return 0; // beforecxx14-warning {{multiple return}}
+}
+
constexpr int ForStmt() {
for (int n = 0; n < 10; ++n) {} // beforecxx14-error {{statement not allowed in constexpr function}}
return 0;
>From 08b3e6677f1b522f31a6222bdd16833533053cc6 Mon Sep 17 00:00:00 2001
From: Baba Dan Constantin <babadany2999 at gmail.com>
Date: Sat, 1 Aug 2026 20:53:59 +0300
Subject: [PATCH 2/3] [clang][docs] Add release note for GNU computed `goto`
extension fix (#213449)
---
clang/docs/ReleaseNotes.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index a38b99ff8e075..a1a8405a2b888 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -117,6 +117,8 @@ features cannot lower the translation-unit ABI level;
#### C++23 Feature Support
+- Clang now allows indirect goto statements in `constexpr` functions in C++23 ([P2242R3](https://wg21.link/p2242r3)). (#213449)
+
#### C++20 Feature Support
#### C++17 Feature Support
>From cc8eee5e4421fb45f16ecd78b3722405418b3da1 Mon Sep 17 00:00:00 2001
From: Baba Dan Constantin <babadany2999 at gmail.com>
Date: Mon, 3 Aug 2026 10:24:22 +0300
Subject: [PATCH 3/3] [clang][constexpr] Move GNU computed goto constexpr test
to dedicated file and fix release note
---
clang/docs/ReleaseNotes.md | 6 +++---
clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp | 8 --------
clang/test/SemaCXX/gnu-constexpr-computed-goto.cpp | 12 ++++++++++++
3 files changed, 15 insertions(+), 11 deletions(-)
create mode 100644 clang/test/SemaCXX/gnu-constexpr-computed-goto.cpp
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index a1a8405a2b888..e56434404a578 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -117,8 +117,6 @@ features cannot lower the translation-unit ABI level;
#### C++23 Feature Support
-- Clang now allows indirect goto statements in `constexpr` functions in C++23 ([P2242R3](https://wg21.link/p2242r3)). (#213449)
-
#### C++20 Feature Support
#### C++17 Feature Support
@@ -160,6 +158,9 @@ features cannot lower the translation-unit ABI level;
### Non-comprehensive list of changes in this release
+- Clang now allows GNU computed `goto` extension in `constexpr` functions, matching the relaxed
+ `constexpr` function body rules introduced in C++23.
+
### New Compiler Flags
- New option `-fdefined-pointer-subtraction` added to preserve stable semantics
@@ -353,7 +354,6 @@ features cannot lower the translation-unit ABI level;
- Clang now attempts to print enumerator names rather than C-style cast expressions
in more diagnostics.
-
### Improvements to Clang's time-trace
### Improvements to Coverage Mapping
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
index 508941ae0429d..51990ee4341d2 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -167,14 +167,6 @@ constexpr int DisallowedStmtsCXX14_7() {
int n; // beforecxx20-warning {{uninitialized variable in a constexpr function}}
}
-constexpr int DisallowedStmtsCXX14_8() {
- return 0; // beforecxx14-note {{previous}}
- // - an indirect goto statement
- goto *(&&x); // beforecxx23-warning {{use of this statement in a constexpr function is a C++23 extension}}
- x:;
- return 0; // beforecxx14-warning {{multiple return}}
-}
-
constexpr int ForStmt() {
for (int n = 0; n < 10; ++n) {} // beforecxx14-error {{statement not allowed in constexpr function}}
return 0;
diff --git a/clang/test/SemaCXX/gnu-constexpr-computed-goto.cpp b/clang/test/SemaCXX/gnu-constexpr-computed-goto.cpp
new file mode 100644
index 0000000000000..e1ac12b2c7646
--- /dev/null
+++ b/clang/test/SemaCXX/gnu-constexpr-computed-goto.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=beforecxx14,beforecxx20,beforecxx23 -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=beforecxx20,beforecxx23 -std=c++14 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=beforecxx23 -std=c++20 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++23 %s
+// expected-no-diagnostics
+
+constexpr int GNUConstexprComputedGoto() {
+ return 0; // beforecxx14-note {{previous}}
+ goto *(&&x); // beforecxx23-warning {{use of this statement in a constexpr function is a C++23 extension}}
+ x:;
+ return 0; // beforecxx14-warning {{multiple return}}
+}
More information about the cfe-commits
mailing list