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