Module Name: src Committed By: rillig Date: Mon May 3 05:24:45 UTC 2021
Modified Files: src/tests/usr.bin/xlint/lint1: gcc_typeof_after_statement.c gcc_typeof_after_statement.exp src/usr.bin/xlint/lint1: cgram.y Log Message: lint: fix parsing of __typeof__ after statement in ({ ... }) Since C99, declarations and statements can be freely mixed, and GCC supported this even before 1999. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 \ src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c \ src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp cvs rdiff -u -r1.225 -r1.226 src/usr.bin/xlint/lint1/cgram.y Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c diff -u src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c:1.1 src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c:1.2 --- src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c:1.1 Thu Apr 22 22:43:26 2021 +++ src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.c Mon May 3 05:24:44 2021 @@ -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); Index: src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp diff -u src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp:1.1 src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp:1.2 --- src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp:1.1 Thu Apr 22 22:43:26 2021 +++ src/tests/usr.bin/xlint/lint1/gcc_typeof_after_statement.exp Mon May 3 05:24:44 2021 @@ -1,3 +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] Index: src/usr.bin/xlint/lint1/cgram.y diff -u src/usr.bin/xlint/lint1/cgram.y:1.225 src/usr.bin/xlint/lint1/cgram.y:1.226 --- src/usr.bin/xlint/lint1/cgram.y:1.225 Sun May 2 20:53:13 2021 +++ src/usr.bin/xlint/lint1/cgram.y Mon May 3 05:24:44 2021 @@ -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;