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 initialization with brace-encl...



details:   https://anonhg.NetBSD.org/src/rev/28a4645b03a9
branches:  trunk
changeset: 954463:28a4645b03a9
user:      rillig <rillig%NetBSD.org@localhost>
date:      Fri Apr 09 23:03:26 2021 +0000

description:
lint: fix initialization with brace-enclosed string literal

C99 allows this form in 6.7.8p14 and p15.

The previous lint tests did not cover the case of an array at the top
level of the object to be initialized, they only covered the error cases
(d_c99_init.c, variables 'prefixed_message' and 'message_with_suffix').

Lint is now more generous than strictly required by C99, but since GCC
and Clang already cover the case of 'message_with_suffix', this is ok.

The test d_init_array_using_string.c was wrong before in rejecting the
initializer for 'extra_braces'.  I had tested that Clang generated a
warning for this, but I had not inspected its warning carefully enough.
Clang had not warned about the extra braces but only about a type
mismatch since I tested on a platform where wchar_t was 16 bit.

diffstat:

 tests/usr.bin/xlint/lint1/d_c99_init.c                  |   7 +--
 tests/usr.bin/xlint/lint1/d_c99_init.exp                |   2 -
 tests/usr.bin/xlint/lint1/d_init_array_using_string.c   |   4 +-
 tests/usr.bin/xlint/lint1/d_init_array_using_string.exp |   2 -
 usr.bin/xlint/lint1/init.c                              |  29 +++++++++-------
 5 files changed, 21 insertions(+), 23 deletions(-)

diffs (184 lines):

diff -r 8ca20253fe56 -r 28a4645b03a9 tests/usr.bin/xlint/lint1/d_c99_init.c
--- a/tests/usr.bin/xlint/lint1/d_c99_init.c    Fri Apr 09 22:32:28 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_c99_init.c    Fri Apr 09 23:03:26 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: d_c99_init.c,v 1.32 2021/04/09 22:08:14 rillig Exp $   */
+/*     $NetBSD: d_c99_init.c,v 1.33 2021/04/09 23:03:26 rillig Exp $   */
 # 3 "d_c99_init.c"
 
 /*
@@ -237,8 +237,8 @@
 };
 
 char message_with_suffix[] = {
-       "message",              /* expect: illegal combination */
-       /* */
+       "message",
+       /* The excess character is not detected by lint but by compilers. */
        '\n',
 };
 
@@ -389,6 +389,5 @@
 
 /* Seen in pcidevs_data.h, variable 'pci_words'. */
 const char string_initialized_with_braced_literal[] = {
-       /* FIXME: *//* expect+1: illegal combination of integer (char) and pointer (pointer to char) [183] */
        "initializer",
 };
diff -r 8ca20253fe56 -r 28a4645b03a9 tests/usr.bin/xlint/lint1/d_c99_init.exp
--- a/tests/usr.bin/xlint/lint1/d_c99_init.exp  Fri Apr 09 22:32:28 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_c99_init.exp  Fri Apr 09 23:03:26 2021 +0000
@@ -8,7 +8,6 @@
 d_c99_init.c(221): error: array subscript cannot be > 1: 2 [168]
 d_c99_init.c(230): error: too many struct/union initializers [172]
 d_c99_init.c(236): warning: illegal combination of integer (char) and pointer (pointer to char) [183]
-d_c99_init.c(240): warning: illegal combination of integer (char) and pointer (pointer to char) [183]
 d_c99_init.c(321): error: duplicate case in switch: 0 [199]
 d_c99_init.c(330): error: type 'struct point' does not have member 'r' [101]
 d_c99_init.c(337): error: type 'struct point' does not have member 'r' [101]
@@ -24,4 +23,3 @@
 d_c99_init.c(381): error: syntax error 'scalar type cannot use designator' [249]
 d_c99_init.c(385): error: syntax error 'scalar type cannot use designator' [249]
 d_c99_init.c(386): error: syntax error 'scalar type cannot use designator' [249]
-d_c99_init.c(393): warning: illegal combination of integer (char) and pointer (pointer to char) [183]
diff -r 8ca20253fe56 -r 28a4645b03a9 tests/usr.bin/xlint/lint1/d_init_array_using_string.c
--- a/tests/usr.bin/xlint/lint1/d_init_array_using_string.c     Fri Apr 09 22:32:28 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_init_array_using_string.c     Fri Apr 09 23:03:26 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: d_init_array_using_string.c,v 1.3 2021/03/30 14:25:28 rillig Exp $     */
+/*     $NetBSD: d_init_array_using_string.c,v 1.4 2021/04/09 23:03:26 rillig Exp $     */
 # 3 "d_init_array_using_string.c"
 
 /*
@@ -74,6 +74,4 @@
                { "" },
                { L"" },
        };
-       /* expect-3: illegal combination of integer (char) and pointer (pointer to char) */
-       /* expect-3: illegal combination of integer (int) and pointer (pointer to int) */
 }
diff -r 8ca20253fe56 -r 28a4645b03a9 tests/usr.bin/xlint/lint1/d_init_array_using_string.exp
--- a/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp   Fri Apr 09 22:32:28 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp   Fri Apr 09 23:03:26 2021 +0000
@@ -6,5 +6,3 @@
 d_init_array_using_string.c(60): error: cannot initialize 'array[10] of const int' from 'pointer to char' [185]
 d_init_array_using_string.c(69): warning: non-null byte ignored in string initializer [187]
 d_init_array_using_string.c(70): warning: non-null byte ignored in string initializer [187]
-d_init_array_using_string.c(74): warning: illegal combination of integer (char) and pointer (pointer to char) [183]
-d_init_array_using_string.c(75): warning: illegal combination of integer (int) and pointer (pointer to int) [183]
diff -r 8ca20253fe56 -r 28a4645b03a9 usr.bin/xlint/lint1/init.c
--- a/usr.bin/xlint/lint1/init.c        Fri Apr 09 22:32:28 2021 +0000
+++ b/usr.bin/xlint/lint1/init.c        Fri Apr 09 23:03:26 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: init.c,v 1.193 2021/04/02 14:50:47 rillig Exp $        */
+/*     $NetBSD: init.c,v 1.194 2021/04/09 23:03:26 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.193 2021/04/02 14:50:47 rillig Exp $");
+__RCSID("$NetBSD: init.c,v 1.194 2021/04/09 23:03:26 rillig Exp $");
 #endif
 
 #include <stdlib.h>
@@ -599,7 +599,7 @@
 }
 
 static const type_t *
-brace_level_sub_type_array(const struct brace_level *bl)
+brace_level_sub_type_array(const struct brace_level *bl, bool is_string)
 {
 
        if (!bl->bl_confused && !bl->bl_type->t_incomplete_array &&
@@ -608,6 +608,10 @@
                error(173, bl->bl_type->t_dim);
        }
 
+       if (is_string && bl->bl_subscript == 0 &&
+           bl->bl_type->t_subt->t_tspec != ARRAY)
+               return bl->bl_type;
+
        return bl->bl_type->t_subt;
 }
 
@@ -625,7 +629,7 @@
 
 /* Return the type of the sub-object that is currently being initialized. */
 static const type_t *
-brace_level_sub_type(const struct brace_level *bl)
+brace_level_sub_type(const struct brace_level *bl, bool is_string)
 {
 
        if (bl->bl_designation.dn_head != NULL)
@@ -636,7 +640,7 @@
        case UNION:
                return brace_level_sub_type_struct_or_union(bl);
        case ARRAY:
-               return brace_level_sub_type_array(bl);
+               return brace_level_sub_type_array(bl, is_string);
        default:
                return brace_level_sub_type_scalar(bl);
        }
@@ -750,12 +754,12 @@
  * initialized.
  */
 static const type_t *
-initialization_sub_type(struct initialization *in)
+initialization_sub_type(struct initialization *in, bool is_string)
 {
        const type_t *tp;
 
        tp = in->in_brace_level != NULL
-           ? brace_level_sub_type(in->in_brace_level)
+           ? brace_level_sub_type(in->in_brace_level, is_string)
            : in->in_sym->s_type;
        if (tp == NULL)
                in->in_err = true;
@@ -772,7 +776,7 @@
 
        debug_enter();
 
-       tp = initialization_sub_type(in);
+       tp = initialization_sub_type(in, false);
        if (tp == NULL) {
                in->in_err = true;
                goto done;
@@ -893,7 +897,7 @@
                return false;
 
        bl = in->in_brace_level;
-       tp = initialization_sub_type(in);
+       tp = initialization_sub_type(in, true);
        strg = tn->tn_string;
 
        if (!is_string_array(tp, strg->st_tspec))
@@ -901,14 +905,15 @@
        if (bl != NULL && tp->t_tspec != ARRAY && bl->bl_subscript != 0)
                return false;
 
-       if (bl != NULL && tp->t_dim < (int)strg->st_len) {
+       if (!tp->t_incomplete_array && tp->t_dim < (int)strg->st_len) {
                /* non-null byte ignored in string initializer */
                warning(187);
        }
 
        if (tp == in->in_sym->s_type && tp->t_incomplete_array) {
                if (bl != NULL) {
-                       bl->bl_subscript = strg->st_len + 1;
+                       bl->bl_subscript = strg->st_len;
+                       /* see brace_level_advance for the +1 */
                        /* see initialization_set_size_of_unknown_array */
                } else
                        update_type_of_array_of_unknown_size(in->in_sym,
@@ -946,7 +951,7 @@
 
        if (bl != NULL)
                brace_level_apply_designation(bl);
-       tp = initialization_sub_type(in);
+       tp = initialization_sub_type(in, false);
        if (tp == NULL)
                goto done;
 



Home | Main Index | Thread Index | Old Index