Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/xlint/lint1 lint: fix parsing of __typeof__ after st...
details: https://anonhg.NetBSD.org/src/rev/85b0f284eae6
branches: trunk
changeset: 378994:85b0f284eae6
user: rillig <rillig%NetBSD.org@localhost>
date: Mon May 03 05:24:44 2021 +0000
description:
lint: fix parsing of __typeof__ after statement in ({ ... })
Since C99, declarations and statements can be freely mixed, and GCC
supported this even before 1999.
diffstat:
tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c | 15 +-
tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp | 4 +-
usr.bin/xlint/lint1/cgram.y | 87 ++++++---------
3 files changed, 46 insertions(+), 60 deletions(-)
diffs (187 lines):
diff -r f7d84b0d3143 -r 85b0f284eae6 tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c
--- a/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c Mon May 03 03:50:43 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c Mon May 03 05:24:44 2021 +0000
@@ -1,9 +1,9 @@
-/* $NetBSD: gcc_typeof_after_statement.c,v 1.1 2021/04/22 22:43:26 rillig Exp $ */
+/* $NetBSD: gcc_typeof_after_statement.c,v 1.2 2021/05/03 05:24:44 rillig Exp $ */
# 3 "gcc_typeof_after_statement.c"
/*
- * As of 2021-04-23, lint cannot parse typeof(...) if there is a statement
- * before it.
+ * Before cgram.y 1.226 from 2021-05-03, lint could not parse typeof(...) if
+ * there was a statement before it.
*/
void *
@@ -12,12 +12,11 @@ example(void **ptr)
return ({
if (*ptr != (void *)0)
ptr++;
-
- /* FIXME: This is a legitimate use case. */
- /* expect+1: syntax error '__typeof__' [249] */
__typeof__(*ptr) ret = *ptr;
- /* expect+1: 'ret' undefined [99] */
ret;
- /* expect+1: illegal combination of pointer (pointer to void) and integer (int) [183] */
});
}
+
+/* Just to keep the .exp file. */
+/* expect+1: static function unused declared but not defined */
+static void unused(void);
diff -r f7d84b0d3143 -r 85b0f284eae6 tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp
--- a/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp Mon May 03 03:50:43 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp Mon May 03 05:24:44 2021 +0000
@@ -1,3 +1,1 @@
-gcc_typeof_after_statement.c(18): error: syntax error '__typeof__' [249]
-gcc_typeof_after_statement.c(20): error: 'ret' undefined [99]
-gcc_typeof_after_statement.c(22): warning: illegal combination of pointer (pointer to void) and integer (int) [183]
+gcc_typeof_after_statement.c(22): warning: static function unused declared but not defined [290]
diff -r f7d84b0d3143 -r 85b0f284eae6 usr.bin/xlint/lint1/cgram.y
--- a/usr.bin/xlint/lint1/cgram.y Mon May 03 03:50:43 2021 +0000
+++ b/usr.bin/xlint/lint1/cgram.y Mon May 03 05:24:44 2021 +0000
@@ -1,5 +1,5 @@
%{
-/* $NetBSD: cgram.y,v 1.225 2021/05/02 20:53:13 rillig Exp $ */
+/* $NetBSD: cgram.y,v 1.226 2021/05/03 05:24:44 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: cgram.y,v 1.225 2021/05/02 20:53:13 rillig Exp $");
+__RCSID("$NetBSD: cgram.y,v 1.226 2021/05/03 05:24:44 rillig Exp $");
#endif
#include <limits.h>
@@ -123,7 +123,7 @@ anonymize(sym_t *s)
}
%}
-%expect 189
+%expect 181
%union {
val_t *y_val;
@@ -323,8 +323,8 @@ anonymize(sym_t *s)
%type <y_sym> parameter_type_list
%type <y_sym> parameter_declaration
%type <y_tnode> expr
-%type <y_tnode> expr_statement_val
-%type <y_tnode> expr_statement_list
+%type <y_tnode> gcc_statement_expr_list
+%type <y_tnode> gcc_statement_expr_item
%type <y_tnode> term
%type <y_tnode> generic_expr
%type <y_tnode> func_arg_list
@@ -1614,33 +1614,6 @@ expr_statement:
}
;
-/*
- * The following two productions are used to implement
- * ({ [[decl-list] stmt-list] }).
- * XXX: This is not well tested.
- */
-expr_statement_val:
- expr T_SEMI {
- /* XXX: We should really do that only on the last name */
- if ($1->tn_op == NAME)
- $1->tn_sym->s_used = true;
- $$ = $1;
- expr($1, false, false, false, false);
- seen_fallthrough = false;
- }
- | non_expr_statement {
- $$ = expr_zalloc_tnode();
- $$->tn_type = gettyp(VOID);
- }
- ;
-
-expr_statement_list:
- expr_statement_val
- | expr_statement_list expr_statement_val {
- $$ = $2;
- }
- ;
-
selection_statement: /* C99 6.8.4 */
if_without_else {
save_warning_flags();
@@ -1831,20 +1804,6 @@ read_until_rparen:
}
;
-declaration_list_opt:
- /* empty */
- | declaration_list
- ;
-
-declaration_list:
- declaration {
- clear_warning_flags();
- }
- | declaration_list declaration {
- clear_warning_flags();
- }
- ;
-
constant_expr_list_opt:
/* empty */
| constant_expr_list
@@ -1933,11 +1892,10 @@ term:
$2->tn_parenthesized = true;
$$ = $2;
}
- | T_LPAREN compound_statement_lbrace declaration_list_opt
- expr_statement_list {
+ | T_LPAREN compound_statement_lbrace gcc_statement_expr_list {
block_level--;
mem_block_level--;
- begin_initialization(mktempsym(dup_type($4->tn_type)));
+ begin_initialization(mktempsym(dup_type($3->tn_type)));
mem_block_level++;
block_level++;
/* ({ }) is a GCC extension */
@@ -2043,6 +2001,37 @@ term:
}
;
+/*
+ * The inner part of a GCC statement-expression of the form ({ ... }).
+ *
+ * https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
+ */
+gcc_statement_expr_list:
+ gcc_statement_expr_item
+ | gcc_statement_expr_list gcc_statement_expr_item {
+ $$ = $2;
+ }
+ ;
+
+gcc_statement_expr_item:
+ declaration {
+ clear_warning_flags();
+ $$ = NULL;
+ }
+ | non_expr_statement {
+ $$ = expr_zalloc_tnode();
+ $$->tn_type = gettyp(VOID);
+ }
+ | expr T_SEMI {
+ /* XXX: We should really do that only on the last name */
+ if ($1->tn_op == NAME)
+ $1->tn_sym->s_used = true;
+ $$ = $1;
+ expr($1, false, false, false, false);
+ seen_fallthrough = false;
+ }
+ ;
+
string:
T_STRING {
$$ = $1;
Home |
Main Index |
Thread Index |
Old Index