Izaron updated this revision to Diff 461002.
Izaron added a comment.
Add diagnostics for C language
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D133887/new/
https://reviews.llvm.org/D133887
Files:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseStmt.cpp
clang/test/AST/ast-dump-stmt.c
clang/test/Parser/c2x-label.c
clang/test/Parser/cxx2b-label.cpp
clang/test/Parser/switch-recovery.cpp
clang/www/c_status.html
clang/www/cxx_status.html
Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1456,7 +1456,7 @@
<tr>
<td>Labels at the end of compound statements</td>
<td><a href="https://wg21.link/P2324R2">P2324R2</a></td>
- <td class="none" align="center">No</td>
+ <td class="unreleased" align="center">Clang 16</td>
</tr>
<tr>
<td>Delimited escape sequences</td>
Index: clang/www/c_status.html
===================================================================
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -763,7 +763,7 @@
<tr>
<td>Free positioning of labels inside compound statements</td>
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2508.pdf">N2508</a></td>
- <td class="none" align="center">No</td>
+ <td class="unreleased" align="center">Clang 16</td>
</tr>
<tr>
<td>Clarification request for C17 example of undefined behavior</td>
Index: clang/test/Parser/switch-recovery.cpp
===================================================================
--- clang/test/Parser/switch-recovery.cpp
+++ clang/test/Parser/switch-recovery.cpp
@@ -160,14 +160,14 @@
void missing_statement_case(int x) {
switch (x) {
case 1:
- case 0: // expected-error {{label at end of compound statement: expected statement}}
+ case 0: // expected-error {{label at end of switch compound statement: expected statement}}
}
}
void missing_statement_default(int x) {
switch (x) {
case 0:
- default: // expected-error {{label at end of compound statement: expected statement}}
+ default: // expected-error {{label at end of switch compound statement: expected statement}}
}
}
@@ -179,7 +179,7 @@
void pr19022_1a(int x) {
switch(x) {
case 1 // expected-error{{expected ':' after 'case'}} \
- // expected-error{{label at end of compound statement: expected statement}}
+ // expected-error{{label at end of switch compound statement: expected statement}}
}
}
Index: clang/test/Parser/cxx2b-label.cpp
===================================================================
--- /dev/null
+++ clang/test/Parser/cxx2b-label.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx2b -std=c++2b -Wpre-c++2b-compat %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx20 -std=c++20 %s
+
+void foo() {
+label1:
+ int x;
+label2:
+ x = 1;
+label3: label4: label5:
+} // cxx20-warning {{label at end of compound statement is a C++2b extension}} \
+ cxx2b-warning {{label at end of compound statement is incompatible with C++ standards before C++2b}}
Index: clang/test/Parser/c2x-label.c
===================================================================
--- /dev/null
+++ clang/test/Parser/c2x-label.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c17 -Wc2x-compat -verify=c17 %s
+// RUN: %clang_cc1 -fsyntax-only -std=c2x -Wpre-c2x-compat -verify=c2x %s
+
+// c2x-no-diagnostics
+
+void foo() {
+ int x;
+label1:
+ x = 1;
+label2: label3: label4:
+} // c17-warning {{label at end of compound statement is a C2x extension}}
Index: clang/test/AST/ast-dump-stmt.c
===================================================================
--- clang/test/AST/ast-dump-stmt.c
+++ clang/test/AST/ast-dump-stmt.c
@@ -161,6 +161,10 @@
// CHECK-NEXT: ImplicitCastExpr
// CHECK-NEXT: ImplicitCastExpr
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:9> 'void *' lvalue Var 0x{{[^ ]*}} 'ptr' 'void *'
+
+label3:
+ // CHECK-NEXT: LabelStmt 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:7> 'label3'
+ // CHECK-NEXT: NullStmt 0x{{[^ ]*}} <col:7>
}
void TestSwitch(int i) {
Index: clang/lib/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -679,9 +679,12 @@
/// ParseLabeledStatement - We have an identifier and a ':' after it.
///
+/// label:
+/// identifier ':'
+/// [GNU] identifier ':' attributes[opt]
+///
/// labeled-statement:
-/// identifier ':' statement
-/// [GNU] identifier ':' attributes[opt] statement
+/// label statement
///
StmtResult Parser::ParseLabeledStatement(ParsedAttributes &Attrs,
ParsedStmtContext StmtCtx) {
@@ -725,6 +728,18 @@
}
}
+ // The label may have no statement following it
+ if (SubStmt.isUnset() && Tok.is(tok::r_brace)) {
+ if (getLangOpts().CPlusPlus) {
+ Diag(Tok, getLangOpts().CPlusPlus2b
+ ? diag::warn_cxx20_compat_label_end_of_compound_statement
+ : diag::ext_cxx_label_end_of_compound_statement);
+ } else if (getLangOpts().C99 && !getLangOpts().C2x) {
+ Diag(Tok, diag::ext_c_label_end_of_compound_statement);
+ }
+ SubStmt = Actions.ActOnNullStmt(ColonLoc);
+ }
+
// If we've not parsed a statement yet, parse one now.
if (!SubStmt.isInvalid() && !SubStmt.isUsable())
SubStmt = ParseStatement(nullptr, StmtCtx);
@@ -873,8 +888,8 @@
// another parsing error, so avoid producing extra diagnostics.
if (ColonLoc.isValid()) {
SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
- Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
- << FixItHint::CreateInsertion(AfterColonLoc, " ;");
+ Diag(AfterColonLoc, diag::err_switch_label_end_of_compound_statement)
+ << FixItHint::CreateInsertion(AfterColonLoc, " ;");
}
SubStmt = StmtError();
}
@@ -928,8 +943,8 @@
// Diagnose the common error "switch (X) {... default: }", which is
// not valid.
SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
- Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
- << FixItHint::CreateInsertion(AfterColonLoc, " ;");
+ Diag(AfterColonLoc, diag::err_switch_label_end_of_compound_statement)
+ << FixItHint::CreateInsertion(AfterColonLoc, " ;");
SubStmt = true;
}
@@ -1096,10 +1111,10 @@
return Actions.ActOnExprStmt(E, /*DiscardedValue=*/!IsStmtExprResult);
}
-/// ParseCompoundStatementBody - Parse a sequence of statements and invoke the
-/// ActOnCompoundStmt action. This expects the '{' to be the current token, and
-/// consume the '}' at the end of the block. It does not manipulate the scope
-/// stack.
+/// ParseCompoundStatementBody - Parse a sequence of statements optionally
+/// followed by a label and invoke the ActOnCompoundStmt action. This expects
+/// the '{' to be the current token, and consume the '}' at the end of the
+/// block. It does not manipulate the scope stack.
StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
PrettyStackTraceLoc CrashInfo(PP.getSourceManager(),
Tok.getLocation(),
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -295,8 +295,17 @@
def note_force_empty_selector_name : Note<
"or insert whitespace before ':' to use %0 as parameter name "
"and have an empty entry in the selector">;
-def err_label_end_of_compound_statement : Error<
- "label at end of compound statement: expected statement">;
+def err_switch_label_end_of_compound_statement : Error<
+ "label at end of switch compound statement: expected statement">;
+def ext_c_label_end_of_compound_statement : ExtWarn<
+ "label at end of compound statement is a C2x extension">,
+ InGroup<C2x>;
+def ext_cxx_label_end_of_compound_statement : ExtWarn<
+ "label at end of compound statement is a C++2b extension">,
+ InGroup<CXX2b>;
+def warn_cxx20_compat_label_end_of_compound_statement : Warning<
+ "label at end of compound statement is incompatible with C++ standards before C++2b">,
+ InGroup<CXXPre2bCompat>, DefaultIgnore;
def err_address_of_label_outside_fn : Error<
"use of address-of-label extension outside of a function body">;
def err_asm_operand_wide_string_literal : Error<
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -246,6 +246,9 @@
so the [[maybe_unused]] attribute may be applied to a label to silence an
``-Wunused-label`` warning.
+- Implemented `WG14 N508 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2508.pdf>`_,
+ so labels can placed everywhere inside a compound statement.
+
C++ Language Changes in Clang
-----------------------------
@@ -294,6 +297,8 @@
C++2b Feature Support
^^^^^^^^^^^^^^^^^^^^^
+- Support label at end of compound statement (`P2324 <https://wg21.link/p2324r2>`_).
+
CUDA/HIP Language Changes in Clang
----------------------------------
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits