[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
@@ -751,8 +751,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
cor3ntin wrote:
Am i missing something or is this always true?
https://github.com/llvm/llvm-project/pull/169688
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From a901f4390ef621a19d385a381286e9f885becdc6 Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 --
clang/lib/Sema/SemaStmt.cpp | 30 +++-
.../cxx2c-expansion-stmts-control-flow.cpp| 135 ++
7 files changed, 223 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index eeb5edf5d8cb8..59ff2571b1445 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3747,6 +3747,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index f334f58ebd0a7..260ed1f55b44a 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e75cda8473cbd..b479cd297a301 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9623,7 +9623,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index a11aece69d525..3c4537f98f8d9 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -751,8 +751,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -796,6 +797,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 9502b440dbe97..a715ef4404cf5 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4468,7 +4468,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
//
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From a901f4390ef621a19d385a381286e9f885becdc6 Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 --
clang/lib/Sema/SemaStmt.cpp | 30 +++-
.../cxx2c-expansion-stmts-control-flow.cpp| 135 ++
7 files changed, 223 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index eeb5edf5d8cb8..59ff2571b1445 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3747,6 +3747,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index f334f58ebd0a7..260ed1f55b44a 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index e75cda8473cbd..b479cd297a301 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9623,7 +9623,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index a11aece69d525..3c4537f98f8d9 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -751,8 +751,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -796,6 +797,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 9502b440dbe97..a715ef4404cf5 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4468,7 +4468,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
//
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
@@ -3738,6 +3738,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
Sirraide wrote:
Apparently we really don’t
https://github.com/llvm/llvm-project/pull/169688
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From c33d4df1c7ff384ffb2dcf7643b640a66f1ba7fb Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7f6fd47b3bb71..ee53b489fce35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3738,6 +3738,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index f334f58ebd0a7..260ed1f55b44a 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 89f8f4deb091a..1df7e7a87e586 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9602,7 +9602,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index a6e3e055896c2..fc635db70920d 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -752,8 +752,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -797,6 +798,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 6167ba1943735..3e75474ae9c03 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4468,7 +4468,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From c33d4df1c7ff384ffb2dcf7643b640a66f1ba7fb Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7f6fd47b3bb71..ee53b489fce35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3738,6 +3738,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index f334f58ebd0a7..260ed1f55b44a 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 89f8f4deb091a..1df7e7a87e586 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9602,7 +9602,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index a6e3e055896c2..fc635db70920d 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -752,8 +752,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -797,6 +798,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 6167ba1943735..3e75474ae9c03 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4468,7 +4468,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 25ca853332bac6e747372857c7e0127affb3c7c9 Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7f6fd47b3bb71..ee53b489fce35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3738,6 +3738,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index f334f58ebd0a7..260ed1f55b44a 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 89f8f4deb091a..1df7e7a87e586 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9602,7 +9602,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index a6e3e055896c2..fc635db70920d 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -752,8 +752,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -797,6 +798,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 6167ba1943735..3e75474ae9c03 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4468,7 +4468,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
github-actions[bot] wrote: # :window: Windows x64 Test Results * 53294 tests passed * 1029 tests skipped * 1 test failed ## Failed Tests (click on a test name to see its output) ### Clang Clang.SemaTemplate/GH176155.cpp ``` Exit Code: 1 Command Output (stdout): -- # RUN: at line 1 c:\_work\llvm-project\llvm-project\build\bin\clang.exe -cc1 -internal-isystem C:\_work\llvm-project\llvm-project\build\lib\clang\23\include -nostdsysteminc -std=c++20 -fsyntax-only -verify C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp # executed command: 'c:\_work\llvm-project\llvm-project\build\bin\clang.exe' -cc1 -internal-isystem 'C:\_work\llvm-project\llvm-project\build\lib\clang\23\include' -nostdsysteminc -std=c++20 -fsyntax-only -verify 'C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp' # .---command stderr # | error: 'expected-error' diagnostics expected but not seen: # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 11 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:12): variable 'i' cannot be implicitly captured in a lambda with no capture-default specified # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 11 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:15): variable 'i' cannot be implicitly captured in a lambda with no capture-default specified # | error: 'expected-note' diagnostics expected but not seen: # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:6): while substituting into a lambda expression here # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:7): capture 'i' by value # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:7): capture 'i' by value # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:8): capture 'i' by reference # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:8): capture 'i' by reference # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:9): default capture by value # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:9): default capture by value # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:10): default capture by reference # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:10): default capture by reference # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 11 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:13): 'i' declared here # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:14): lambda expression begins here # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 11 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:16): 'i' declared here # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 5 (directive at C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp:17): lambda expression begins here # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 23: in instantiation of default argument for 'f' required here # | File C:\_work\llvm-project\llvm-project\clang\test\SemaTemplate\GH176155.cpp Line 26: while substituting deduced template arguments into function template 'f' # | 17 errors generated. # `- # error: command failed with exit status: 1 -- ``` If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label. https://github.com/llvm/llvm-project/pull/169688 __
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
github-actions[bot] wrote: # :penguin: Linux x64 Test Results * 87002 tests passed * 1328 tests skipped * 1 test failed ## Failed Tests (click on a test name to see its output) ### Clang Clang.SemaTemplate/GH176155.cpp ``` Exit Code: 1 Command Output (stdout): -- # RUN: at line 1 /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -cc1 -internal-isystem /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/clang/23/include -nostdsysteminc -std=c++20 -fsyntax-only -verify /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp # executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -cc1 -internal-isystem /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lib/clang/23/include -nostdsysteminc -std=c++20 -fsyntax-only -verify /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp # .---command stderr # | error: 'expected-error' diagnostics expected but not seen: # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 11 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:12): variable 'i' cannot be implicitly captured in a lambda with no capture-default specified # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 11 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:15): variable 'i' cannot be implicitly captured in a lambda with no capture-default specified # | error: 'expected-note' diagnostics expected but not seen: # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:6): while substituting into a lambda expression here # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:7): capture 'i' by value # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:7): capture 'i' by value # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:8): capture 'i' by reference # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:8): capture 'i' by reference # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:9): default capture by value # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:9): default capture by value # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:10): default capture by reference # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:10): default capture by reference # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 11 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:13): 'i' declared here # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:14): lambda expression begins here # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 11 (directive at /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp:16): 'i' declared here # | File /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/SemaTemplate/GH176155.cpp Line 5 (directive at /home/gha/actions-runner/_work/llvm-project/llv
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From c9e4f2dee86593281b4d09fa7dbf24cb874295da Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7f6fd47b3bb71..ee53b489fce35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3738,6 +3738,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index f334f58ebd0a7..260ed1f55b44a 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 89f8f4deb091a..1df7e7a87e586 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9602,7 +9602,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index f4f2d6c7a249d..9e6a66db596df 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -752,8 +752,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -797,6 +798,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 6167ba1943735..3e75474ae9c03 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4468,7 +4468,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From c9e4f2dee86593281b4d09fa7dbf24cb874295da Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7f6fd47b3bb71..ee53b489fce35 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3738,6 +3738,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index f334f58ebd0a7..260ed1f55b44a 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 89f8f4deb091a..1df7e7a87e586 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9602,7 +9602,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index f4f2d6c7a249d..9e6a66db596df 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -752,8 +752,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -797,6 +798,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 6167ba1943735..3e75474ae9c03 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4468,7 +4468,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 31dfa44cec804e7f9850524ef0b60f8ccfcedc3b Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 208c885909b00..6994cd88fba21 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3720,6 +3720,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0adc570c73011..5a3603c284cd1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9531,7 +9531,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 59eac05e8f39e..73f1d1a7b46fd 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -744,8 +744,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -789,6 +790,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 90eee36d7dbe6..169e1d1cf1cb5 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4466,7 +4466,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 31dfa44cec804e7f9850524ef0b60f8ccfcedc3b Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 208c885909b00..6994cd88fba21 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3720,6 +3720,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 0adc570c73011..5a3603c284cd1 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9531,7 +9531,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 59eac05e8f39e..73f1d1a7b46fd 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -744,8 +744,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -789,6 +790,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 90eee36d7dbe6..169e1d1cf1cb5 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4466,7 +4466,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 3cf63f47cd71cefb1abf2784ab38041ff959a921 Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d91e1526ae47f..bf6d017e845fc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3708,6 +3708,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f5a36626a9dad..a4a4fd287ab12 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9530,7 +9530,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 59eac05e8f39e..73f1d1a7b46fd 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -744,8 +744,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -789,6 +790,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 3cf63f47cd71cefb1abf2784ab38041ff959a921 Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d91e1526ae47f..bf6d017e845fc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3708,6 +3708,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f5a36626a9dad..a4a4fd287ab12 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9530,7 +9530,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 59eac05e8f39e..73f1d1a7b46fd 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -744,8 +744,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -789,6 +790,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 0a945e66ca01c3a5f9d8914cfb6c7f0459a866b3 Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d91e1526ae47f..bf6d017e845fc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3708,6 +3708,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 268c81351e744..c90ddf91a663b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9530,7 +9530,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 59eac05e8f39e..73f1d1a7b46fd 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -744,8 +744,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -789,6 +790,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 0a945e66ca01c3a5f9d8914cfb6c7f0459a866b3 Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index d91e1526ae47f..bf6d017e845fc 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3708,6 +3708,12 @@ def err_expansion_stmt_incomplete : Error<
"cannot expand expression of incomplete type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 268c81351e744..c90ddf91a663b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9530,7 +9530,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 59eac05e8f39e..73f1d1a7b46fd 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -744,8 +744,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -789,6 +790,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
/
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 20da66c4ce7543e65d42fce8a0acfc43a749c1aa Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0ddaa461deff5..5115c175849e1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3706,6 +3706,12 @@ def err_expansion_stmt_invalid_init : Error<
"cannot expand expression of type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b102544342416..82fc2875e2abf 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9519,7 +9519,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 39751c79c6852..7b0e0ff17733b 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -715,8 +715,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -760,6 +761,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
// Local l
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 162cc15dff58d47852cc0d88311754395bec12f5 Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0ddaa461deff5..5115c175849e1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3706,6 +3706,12 @@ def err_expansion_stmt_invalid_init : Error<
"cannot expand expression of type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b102544342416..82fc2875e2abf 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9519,7 +9519,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 39751c79c6852..7b0e0ff17733b 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -715,8 +715,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -760,6 +761,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
// Local l
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide updated
https://github.com/llvm/llvm-project/pull/169688
>From 162cc15dff58d47852cc0d88311754395bec12f5 Mon Sep 17 00:00:00 2001
From: Sirraide
Date: Wed, 26 Nov 2025 17:21:39 +0100
Subject: [PATCH] [Clang] [C++26] Expansion Statements (Part 9)
---
.../clang/Basic/DiagnosticSemaKinds.td| 6 +
clang/include/clang/Sema/ScopeInfo.h | 6 +-
clang/include/clang/Sema/Sema.h | 3 +-
clang/lib/Parse/ParseStmt.cpp | 11 +-
clang/lib/Sema/SemaLookup.cpp | 47 +--
clang/lib/Sema/SemaStmt.cpp | 30 -
.../cxx2c-expansion-stmts-control-flow.cpp| 117 ++
7 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0ddaa461deff5..5115c175849e1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3706,6 +3706,12 @@ def err_expansion_stmt_invalid_init : Error<
"cannot expand expression of type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b102544342416..82fc2875e2abf 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9519,7 +9519,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 39751c79c6852..7b0e0ff17733b 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -715,8 +715,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -760,6 +761,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
// Local l
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide edited https://github.com/llvm/llvm-project/pull/169688 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide ready_for_review https://github.com/llvm/llvm-project/pull/169688 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
llvmbot wrote:
@llvm/pr-subscribers-clang-codegen
Author: None (Sirraide)
Changes
---
Full diff: https://github.com/llvm/llvm-project/pull/169688.diff
7 Files Affected:
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+6)
- (modified) clang/include/clang/Sema/ScopeInfo.h (+5-1)
- (modified) clang/include/clang/Sema/Sema.h (+2-1)
- (modified) clang/lib/Parse/ParseStmt.cpp (+9-2)
- (modified) clang/lib/Sema/SemaLookup.cpp (+38-9)
- (modified) clang/lib/Sema/SemaStmt.cpp (+28-2)
- (added) clang/test/SemaCXX/cxx2c-expansion-stmts-control-flow.cpp (+117)
``diff
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0ddaa461deff5..5115c175849e1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3706,6 +3706,12 @@ def err_expansion_stmt_invalid_init : Error<
"cannot expand expression of type %0">;
def err_expansion_stmt_lambda : Error<
"cannot expand lambda closure type">;
+def err_expansion_stmt_case : Error<
+ "%select{'case'|'default'}0 belongs to 'switch' outside enclosing expansion
statement">;
+def note_enclosing_switch_statement_here : Note<
+ "switch statement is here">;
+def err_expansion_stmt_label : Error<
+ "labels are not allowed in expansion statements">;
def err_attribute_patchable_function_entry_invalid_section
: Error<"section argument to 'patchable_function_entry' attribute is not "
diff --git a/clang/include/clang/Sema/ScopeInfo.h
b/clang/include/clang/Sema/ScopeInfo.h
index 4f4d38c961140..2a410bd2eab91 100644
--- a/clang/include/clang/Sema/ScopeInfo.h
+++ b/clang/include/clang/Sema/ScopeInfo.h
@@ -202,7 +202,11 @@ class FunctionScopeInfo {
public:
/// A SwitchStmt, along with a flag indicating if its list of case statements
/// is incomplete (because we dropped an invalid one while parsing).
- using SwitchInfo = llvm::PointerIntPair;
+ struct SwitchInfo : llvm::PointerIntPair {
+DeclContext *EnclosingDC;
+SwitchInfo(SwitchStmt *Switch, DeclContext *DC)
+: PointerIntPair(Switch, false), EnclosingDC(DC) {}
+ };
/// SwitchStack - This is the current set of active switch statements in the
/// block.
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b102544342416..82fc2875e2abf 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9519,7 +9519,8 @@ class Sema final : public SemaBase {
/// of an __label__ label name, otherwise it is a normal label definition
/// or use.
LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc,
- SourceLocation GnuLabelLoc =
SourceLocation());
+ SourceLocation GnuLabelLoc = SourceLocation(),
+ bool ForLabelStmt = false);
/// Perform a name lookup for a label with the specified name; this does not
/// create a new label if the lookup fails.
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 39751c79c6852..7b0e0ff17733b 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -715,8 +715,9 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
// identifier ':' statement
SourceLocation ColonLoc = ConsumeToken();
- LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
- IdentTok.getLocation());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(
+ IdentTok.getIdentifierInfo(), IdentTok.getLocation(), /*GnuLabelLoc=*/{},
+ /*ForLabelStmt=*/true);
// Read label attributes, if present.
StmtResult SubStmt;
@@ -760,6 +761,12 @@ StmtResult Parser::ParseLabeledStatement(ParsedAttributes
&Attrs,
DiagnoseLabelFollowedByDecl(*this, SubStmt.get());
+ // If a label cannot appear here, just return the underlying statement.
+ if (!LD) {
+Attrs.clear();
+return SubStmt.get();
+ }
+
Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
Attrs.clear();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 88dcd27d45ad2..576ec6c80770e 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4463,7 +4463,8 @@ LabelDecl *Sema::LookupExistingLabel(IdentifierInfo *II,
SourceLocation Loc) {
}
LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc,
- SourceLocation GnuLabelLoc) {
+ SourceLocation GnuLabelLoc,
+ bool ForLabelStmt) {
if (GnuLabelLoc.isValid()) {
// Local label definitions always shadow existing labels.
auto *Res = LabelDecl::Create(Context, CurContext, Loc, II, GnuLabelLoc);
@@ -4472,15 +4473,43 @@ LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo
*II, SourceLocati
[llvm-branch-commits] [clang] [Clang] [C++26] Expansion Statements (Part 9: Control Flow) (PR #169688)
https://github.com/Sirraide edited https://github.com/llvm/llvm-project/pull/169688 ___ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
