diff mbox series

[2/2] parse: warn about a 'case label' on empty statement

Message ID c47fb74a-0439-138a-4837-97ff9c983b71@ramsayjones.plus.com (mailing list archive)
State Mainlined, archived
Headers show
Series [1/2] sparse: fix broken 'memcpy-max-count' check | expand

Commit Message

Ramsay Jones Sept. 27, 2021, 11:45 p.m. UTC
Commit 0d6bb7e1 ("handle more graciously labels with no statement",
2020-10-26) allowed a label to appear just before the closing brace
of a compound statement. This is not valid C (which would require
at least a null statement). Similarly, a case label is also not
allowed to appear just before a closing brace.

So, extend the solution of commit 0d6bb7e1 to issue a warning for
case labels and 'insert' a null statement.

Note that the next C standard (C23 ?) will allow even more freedom
in the placement of labels (see N2508 [1]) and make this placement
(along with others) legal C.

[1] https://www9.open-std.org/JTC1/SC22/WG14/www/docs/n2508.pdf

Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com>
---
 parse.c                        |  5 +++++
 validation/label-positioning.c | 22 ++++++++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 validation/label-positioning.c
diff mbox series

Patch

diff --git a/parse.c b/parse.c
index bc1c0602..9f2a3cdf 100644
--- a/parse.c
+++ b/parse.c
@@ -2329,6 +2329,11 @@  static inline struct token *case_statement(struct token *token, struct statement
 	stmt->type = STMT_CASE;
 	token = expect(token, ':', "after default/case");
 	add_case_statement(stmt);
+	if (match_op(token, '}')) {
+		warning(token->pos, "statement expected after case label");
+		stmt->case_statement = alloc_statement(token->pos, STMT_NONE);
+		return token;
+	}
 	return statement(token, &stmt->case_statement);
 }
 
diff --git a/validation/label-positioning.c b/validation/label-positioning.c
new file mode 100644
index 00000000..583661ca
--- /dev/null
+++ b/validation/label-positioning.c
@@ -0,0 +1,22 @@ 
+extern int someval(void);
+
+static void func (int x)
+{
+	if (x > someval())
+		goto end;
+	switch (x) { case 0: }
+	switch (x) { case 1 ... 9: }
+	switch (x) { default: }
+end:
+}
+
+/*
+ * check-name: label-positioning
+ *
+ * check-error-start
+label-positioning.c:7:30: warning: statement expected after case label
+label-positioning.c:8:36: warning: statement expected after case label
+label-positioning.c:9:31: warning: statement expected after case label
+label-positioning.c:11:1: warning: statement expected after label
+ * check-error-end
+ */