Module Name: src Committed By: rillig Date: Fri Apr 9 23:03:26 UTC 2021
Modified Files: src/tests/usr.bin/xlint/lint1: d_c99_init.c d_c99_init.exp d_init_array_using_string.c d_init_array_using_string.exp src/usr.bin/xlint/lint1: init.c Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/tests/usr.bin/xlint/lint1/d_c99_init.c cvs rdiff -u -r1.25 -r1.26 src/tests/usr.bin/xlint/lint1/d_c99_init.exp cvs rdiff -u -r1.3 -r1.4 \ src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c \ src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp cvs rdiff -u -r1.193 -r1.194 src/usr.bin/xlint/lint1/init.c 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/d_c99_init.c diff -u src/tests/usr.bin/xlint/lint1/d_c99_init.c:1.32 src/tests/usr.bin/xlint/lint1/d_c99_init.c:1.33 --- src/tests/usr.bin/xlint/lint1/d_c99_init.c:1.32 Fri Apr 9 22:08:14 2021 +++ src/tests/usr.bin/xlint/lint1/d_c99_init.c Fri Apr 9 23:03:26 2021 @@ -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 prefixed_message[] = { }; 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 @@ struct point designator_for_scalar_in_st /* 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", }; Index: src/tests/usr.bin/xlint/lint1/d_c99_init.exp diff -u src/tests/usr.bin/xlint/lint1/d_c99_init.exp:1.25 src/tests/usr.bin/xlint/lint1/d_c99_init.exp:1.26 --- src/tests/usr.bin/xlint/lint1/d_c99_init.exp:1.25 Fri Apr 9 22:08:14 2021 +++ src/tests/usr.bin/xlint/lint1/d_c99_init.exp Fri Apr 9 23:03:26 2021 @@ -8,7 +8,6 @@ d_c99_init.c(219): error: array subscrip 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(377): error: too many struc 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] Index: src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c diff -u src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c:1.3 src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c:1.4 --- src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c:1.3 Tue Mar 30 14:25:28 2021 +++ src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c Fri Apr 9 23:03:26 2021 @@ -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 @@ test_array_initialization_in_struct(void { "" }, { 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) */ } Index: src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp diff -u src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp:1.3 src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp:1.4 --- src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp:1.3 Tue Mar 30 14:25:28 2021 +++ src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp Fri Apr 9 23:03:26 2021 @@ -6,5 +6,3 @@ d_init_array_using_string.c(59): error: 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] Index: src/usr.bin/xlint/lint1/init.c diff -u src/usr.bin/xlint/lint1/init.c:1.193 src/usr.bin/xlint/lint1/init.c:1.194 --- src/usr.bin/xlint/lint1/init.c:1.193 Fri Apr 2 14:50:47 2021 +++ src/usr.bin/xlint/lint1/init.c Fri Apr 9 23:03:26 2021 @@ -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 @@ brace_level_sub_type_struct_or_union(con } 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 @@ brace_level_sub_type_array(const struct 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 @@ brace_level_sub_type_scalar(const struct /* 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 @@ brace_level_sub_type(const struct brace_ 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 @@ initialization_debug(const struct initia * 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 @@ initialization_begin_brace_level(struct 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 @@ initialization_init_array_using_string(s 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 @@ initialization_init_array_using_string(s 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 @@ initialization_expr(struct initializatio if (bl != NULL) brace_level_apply_designation(bl); - tp = initialization_sub_type(in); + tp = initialization_sub_type(in, false); if (tp == NULL) goto done;