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 handling of initializations



details:   https://anonhg.NetBSD.org/src/rev/e394d165a02e
branches:  trunk
changeset: 1029117:e394d165a02e
user:      rillig <rillig%NetBSD.org@localhost>
date:      Wed Dec 22 00:45:53 2021 +0000

description:
lint: fix handling of initializations

The implementation from March 2021 added proper support for designators
but didn't model the brace levels correctly.  In particular, it could
not handle additional braces or omitted braces.  In such a case, lint
skipped the remaining initializers from the initialization.  Due to
this, type errors in the remaining initializers went unnoticed.  Another
effect was that arrays of unknown size were wrongly reported as having
size 0.

Both GCC and Clang recommend placing braces around each sub-type that is
initialized, such as a struct, union or array.  Postfix does not follow
these recommendations, therefore lint had to be disabled in
external/ibm-public/postfix/Makefile.inc.  This commit fixes the bugs
mentioned there.

diffstat:

 tests/usr.bin/xlint/lint1/d_c99_init.c                  |   37 +-
 tests/usr.bin/xlint/lint1/d_c99_init.exp                |   17 +-
 tests/usr.bin/xlint/lint1/d_init_array_using_string.c   |    6 +-
 tests/usr.bin/xlint/lint1/d_init_array_using_string.exp |    4 +-
 tests/usr.bin/xlint/lint1/init.c                        |   26 +-
 tests/usr.bin/xlint/lint1/init.exp                      |    4 +
 tests/usr.bin/xlint/lint1/msg_179.c                     |    7 +-
 tests/usr.bin/xlint/lint1/msg_179.exp                   |    4 +-
 usr.bin/xlint/lint1/err.c                               |    6 +-
 usr.bin/xlint/lint1/init.c                              |  718 ++++++++-------
 10 files changed, 481 insertions(+), 348 deletions(-)

diffs (truncated from 1334 to 300 lines):

diff -r d1ca4d367b6f -r e394d165a02e tests/usr.bin/xlint/lint1/d_c99_init.c
--- a/tests/usr.bin/xlint/lint1/d_c99_init.c    Wed Dec 22 00:21:32 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_c99_init.c    Wed Dec 22 00:45:53 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: d_c99_init.c,v 1.35 2021/12/21 16:50:11 rillig Exp $   */
+/*     $NetBSD: d_c99_init.c,v 1.36 2021/12/22 00:45:53 rillig Exp $   */
 # 3 "d_c99_init.c"
 
 /*
@@ -24,7 +24,7 @@
 int scalar_with_too_many_initializers = { 3, 5 };      /* expect: 174 */
 
 
-// See init_expr, 'handing over to ASSIGN'.
+// See initialization_expr, 'handing over to INIT'.
 void
 struct_initialization_via_assignment(any arg)
 {
@@ -427,31 +427,46 @@
        .unknown_value = 4,     /* expect: does not have member */
 };
 
-struct point designators_with_subscript = {
+struct point subscript_designator_on_struct = {
        [0] = 3,                /* expect: only for arrays */
-       .member[0][0].member = 4, /* expect: does not have member 'member' */
-       .x.y.z = 5,     /* intentionally not caught, see designator_look_up */
+};
+
+struct point unknown_member_on_struct = {
+       /* expect+1: error: type 'struct point' does not have member 'member' [101] */
+       .member[0][0].member = 4,
+};
+
+struct point unknown_member_on_scalar = {
+       /* expect+1: error: syntax error 'scalar type cannot use designator' [249] */
+       .x.y.z = 5,
 };
 
 struct {
        int : 16;
-} struct_with_only_unnamed_members = { /* expect: has no named members */
-       123,            /* expect: too many struct/union initializers */
+       /* expect+2: warning: structure has no named members [65] */
+       /* expect+1: error: cannot initialize struct/union with no named member [179] */
+} struct_with_only_unnamed_members = {
+       123,
 };
 
 union {
        int : 16;
-} union_with_only_unnamed_members = {  /* expect: has no named members */
-       123,            /* expect: too many struct/union initializers */
+       /* expect+2: warning: union has no named members [65] */
+       /* expect+1: error: cannot initialize struct/union with no named member [179] */
+} union_with_only_unnamed_members = {
+       123,
 };
 
 int designator_for_scalar = {
        .value = 3,             /* expect: scalar type cannot use designator */
 };
 
-struct point designator_for_scalar_in_struct = {
+struct point member_designator_for_scalar_in_struct = {
        { .x = 3 },             /* expect: scalar type cannot use designator */
-       { [1] = 4 },            /* expect: scalar type cannot use designator */
+};
+struct point subscript_designator_for_scalar_in_struct = {
+       /* expect+1: error: syntax error 'designator '[...]' is only for arrays' [249] */
+       { [1] = 4 },
 };
 
 
diff -r d1ca4d367b6f -r e394d165a02e tests/usr.bin/xlint/lint1/d_c99_init.exp
--- a/tests/usr.bin/xlint/lint1/d_c99_init.exp  Wed Dec 22 00:21:32 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_c99_init.exp  Wed Dec 22 00:45:53 2021 +0000
@@ -18,11 +18,12 @@
 d_c99_init.c(421): error: type 'union value' does not have member 'unknown_value' [101]
 d_c99_init.c(427): error: type 'union value' does not have member 'unknown_value' [101]
 d_c99_init.c(431): error: syntax error 'designator '[...]' is only for arrays' [249]
-d_c99_init.c(432): error: type 'struct point' does not have member 'member' [101]
-d_c99_init.c(438): warning: structure has no named members [65]
-d_c99_init.c(439): error: too many struct/union initializers [172]
-d_c99_init.c(444): warning: union has no named members [65]
-d_c99_init.c(445): error: too many struct/union initializers [172]
-d_c99_init.c(449): error: syntax error 'scalar type cannot use designator' [249]
-d_c99_init.c(453): error: syntax error 'scalar type cannot use designator' [249]
-d_c99_init.c(454): error: syntax error 'scalar type cannot use designator' [249]
+d_c99_init.c(436): error: type 'struct point' does not have member 'member' [101]
+d_c99_init.c(441): error: syntax error 'scalar type cannot use designator' [249]
+d_c99_init.c(448): warning: structure has no named members [65]
+d_c99_init.c(448): error: cannot initialize struct/union with no named member [179]
+d_c99_init.c(456): warning: union has no named members [65]
+d_c99_init.c(456): error: cannot initialize struct/union with no named member [179]
+d_c99_init.c(461): error: syntax error 'scalar type cannot use designator' [249]
+d_c99_init.c(465): error: syntax error 'scalar type cannot use designator' [249]
+d_c99_init.c(469): error: syntax error 'designator '[...]' is only for arrays' [249]
diff -r d1ca4d367b6f -r e394d165a02e tests/usr.bin/xlint/lint1/d_init_array_using_string.c
--- a/tests/usr.bin/xlint/lint1/d_init_array_using_string.c     Wed Dec 22 00:21:32 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_init_array_using_string.c     Wed Dec 22 00:45:53 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: d_init_array_using_string.c,v 1.7 2021/12/21 22:21:11 rillig Exp $     */
+/*     $NetBSD: d_init_array_using_string.c,v 1.8 2021/12/22 00:45:53 rillig Exp $     */
 # 3 "d_init_array_using_string.c"
 
 /*
@@ -60,8 +60,8 @@
        };
 
        struct cs_ws type_mismatch = {
-               L"",            /* expect: cannot initialize */
-               "",             /* expect: cannot initialize */
+               L"",            /* expect: warning: illegal combination of integer (char) and pointer (pointer to int) [183] */
+               "",             /* expect: warning: illegal combination of integer (char) and pointer (pointer to char) [183] */
        };
 
        struct cs_ws no_terminating_null = {
diff -r d1ca4d367b6f -r e394d165a02e tests/usr.bin/xlint/lint1/d_init_array_using_string.exp
--- a/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp   Wed Dec 22 00:21:32 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp   Wed Dec 22 00:45:53 2021 +0000
@@ -2,7 +2,7 @@
 d_init_array_using_string.c(19): warning: illegal combination of 'pointer to const int' and 'pointer to char', op 'init' [124]
 d_init_array_using_string.c(37): warning: illegal combination of 'pointer to const char' and 'pointer to int', op 'init' [124]
 d_init_array_using_string.c(39): warning: illegal combination of 'pointer to const int' and 'pointer to char', op 'init' [124]
-d_init_array_using_string.c(63): error: cannot initialize 'array[10] of const char' from 'pointer to int' [185]
-d_init_array_using_string.c(64): error: cannot initialize 'array[10] of const int' from 'pointer to char' [185]
+d_init_array_using_string.c(63): warning: illegal combination of integer (char) and pointer (pointer to int) [183]
+d_init_array_using_string.c(64): warning: illegal combination of integer (char) and pointer (pointer to char) [183]
 d_init_array_using_string.c(74): warning: string literal too long (11) for target array (10) [187]
 d_init_array_using_string.c(76): warning: string literal too long (11) for target array (10) [187]
diff -r d1ca4d367b6f -r e394d165a02e tests/usr.bin/xlint/lint1/init.c
--- a/tests/usr.bin/xlint/lint1/init.c  Wed Dec 22 00:21:32 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/init.c  Wed Dec 22 00:45:53 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: init.c,v 1.9 2021/12/21 21:42:21 rillig Exp $  */
+/*     $NetBSD: init.c,v 1.10 2021/12/22 00:45:53 rillig Exp $ */
 # 3 "init.c"
 
 /*
@@ -106,3 +106,27 @@
 union incomplete_union {
        int num;
 };
+
+
+/* expect+1: warning: cannot initialize extern declaration: extern_var [26] */
+extern int extern_var = 1;
+int defined_var = 1;
+/* expect+1: warning: static variable static_var unused [226] */
+static int static_var = 1;
+/* expect+1: error: illegal storage class [8] */
+register int register_var = 1;
+/* expect+1: error: cannot initialize typedef: typedef_var [25] */
+typedef int typedef_var = 1;
+
+
+/*
+ * In an array of unknown size that is declared using fewer braces than
+ * recommended, ensure that the array size is updated at the end of the
+ * initializer.
+ */
+struct {
+       int x;
+       int y;
+} points_of_unknown_size[] = {
+       3, 4,
+};
diff -r d1ca4d367b6f -r e394d165a02e tests/usr.bin/xlint/lint1/init.exp
--- a/tests/usr.bin/xlint/lint1/init.exp        Wed Dec 22 00:21:32 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/init.exp        Wed Dec 22 00:45:53 2021 +0000
@@ -7,3 +7,7 @@
 init.c(98): error: 'u1' has incomplete type 'incomplete union incomplete_union' [31]
 init.c(101): error: initialization of incomplete type 'incomplete union incomplete_union' [175]
 init.c(104): error: 'u2' has incomplete type 'incomplete union incomplete_union' [31]
+init.c(112): warning: cannot initialize extern declaration: extern_var [26]
+init.c(117): error: illegal storage class [8]
+init.c(119): error: cannot initialize typedef: typedef_var [25]
+init.c(115): warning: static variable static_var unused [226]
diff -r d1ca4d367b6f -r e394d165a02e tests/usr.bin/xlint/lint1/msg_179.c
--- a/tests/usr.bin/xlint/lint1/msg_179.c       Wed Dec 22 00:21:32 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_179.c       Wed Dec 22 00:45:53 2021 +0000
@@ -1,24 +1,25 @@
-/*     $NetBSD: msg_179.c,v 1.3 2021/08/27 19:50:44 rillig Exp $       */
+/*     $NetBSD: msg_179.c,v 1.4 2021/12/22 00:45:53 rillig Exp $       */
 # 3 "msg_179.c"
 
 // Test for message: cannot initialize struct/union with no named member [179]
-/* This message is not used. */
 
 struct {
        unsigned int :0;
 } no_named_member = {
+       /* expect-1: error: cannot initialize struct/union with no named member [179] */
        /* no named member, therefore no initializer expression */
 };
 
 struct {
        /* no members */
 } empty = {
+       /* expect-1: error: cannot initialize struct/union with no named member [179] */
        /* no initializer expressions */
 };
 
 struct {
        unsigned int: 0;
 } no_named_member_init = {
-       /* expect+1: error: too many struct/union initializers [172] */
+       /* expect-1: error: cannot initialize struct/union with no named member [179] */
        3,
 };
diff -r d1ca4d367b6f -r e394d165a02e tests/usr.bin/xlint/lint1/msg_179.exp
--- a/tests/usr.bin/xlint/lint1/msg_179.exp     Wed Dec 22 00:21:32 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_179.exp     Wed Dec 22 00:45:53 2021 +0000
@@ -1,1 +1,3 @@
-msg_179.c(23): error: too many struct/union initializers [172]
+msg_179.c(8): error: cannot initialize struct/union with no named member [179]
+msg_179.c(15): error: cannot initialize struct/union with no named member [179]
+msg_179.c(22): error: cannot initialize struct/union with no named member [179]
diff -r d1ca4d367b6f -r e394d165a02e usr.bin/xlint/lint1/err.c
--- a/usr.bin/xlint/lint1/err.c Wed Dec 22 00:21:32 2021 +0000
+++ b/usr.bin/xlint/lint1/err.c Wed Dec 22 00:45:53 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: err.c,v 1.149 2021/12/21 22:21:11 rillig Exp $ */
+/*     $NetBSD: err.c,v 1.150 2021/12/22 00:45:53 rillig Exp $ */
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: err.c,v 1.149 2021/12/21 22:21:11 rillig Exp $");
+__RCSID("$NetBSD: err.c,v 1.150 2021/12/22 00:45:53 rillig Exp $");
 #endif
 
 #include <sys/types.h>
@@ -233,7 +233,7 @@
        "",                     /* no longer used */                  /* 176 */
        "non-constant initializer",                                   /* 177 */
        "initializer does not fit",                                   /* 178 */
-       "",                     /* unused since 2021-03-29 */         /* 179 */
+       "cannot initialize struct/union with no named member",        /* 179 */
        "bit-field initializer does not fit",                         /* 180 */
        "{}-enclosed initializer required",                           /* 181 */
        "incompatible pointer types (%s != %s)",                      /* 182 */
diff -r d1ca4d367b6f -r e394d165a02e usr.bin/xlint/lint1/init.c
--- a/usr.bin/xlint/lint1/init.c        Wed Dec 22 00:21:32 2021 +0000
+++ b/usr.bin/xlint/lint1/init.c        Wed Dec 22 00:45:53 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: init.c,v 1.228 2021/12/21 22:21:11 rillig Exp $        */
+/*     $NetBSD: init.c,v 1.229 2021/12/22 00:45:53 rillig Exp $        */
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: init.c,v 1.228 2021/12/21 22:21:11 rillig Exp $");
+__RCSID("$NetBSD: init.c,v 1.229 2021/12/22 00:45:53 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -52,21 +52,9 @@
  *
  *     int number = 12345;
  *     int number_with_braces = { 12345 };
- *
  *     int array_of_unknown_size[] = { 111, 222, 333 };
- *     int array_flat[2][2] = { 11, 12, 21, 22 };
- *     int array_nested[2][2] = { { 11, 12 }, { 21, 22 } };
- *
- *     struct { int x, y; } point = { 3, 4 };
  *     struct { int x, y; } point = { .y = 4, .x = 3 };
  *
- * Any scalar expression or string in the initializer may be surrounded by
- * additional pairs of braces.
- *
- * For nested aggregate objects, the inner braces may be omitted like in
- * array_flat or spelled out like in array_nested.  This is unusual in
- * practice and therefore only supported very basically.
- *
  * During an initialization, the grammar parser calls these functions:
  *
  *     begin_initialization
@@ -87,22 +75,33 @@
  *     d_c99_init.c for more examples
  */
 
+
+typedef enum designator_kind {
+       DK_STRUCT,              /* .member */
+       DK_UNION,               /* .member */
+       DK_ARRAY,               /* [subscript] */
+       /* TODO: actually necessary? */
+       DK_SCALAR               /* no textual representation, not generated
+                                * by the parser */
+} designator_kind;
+



Home | Main Index | Thread Index | Old Index