Wed Mar 10 00:02:00 2021 UTC ()
lint: disable check for enum type mismatch in switch statement

This check has been too quick and broke the lint build.  Among others,
lib/libpuffs has -w included in LINTFLAGS, which means that the build
can fail even for new warnings, not only for errors.

libpuffs compares a uint16_t with constants from an unnamed enum type.
Since the enum type is completely unnamed (neither a tag nor a typedef),
there is no way to define a struct member having this type. This was a
scenario that I just didn't consider when I added the check to lint.

For now, disable the new check completely.  The previously existing lint
checks stay enabled, including the one that warns about mismatched
anonymous enum types in the '==' operator, which is very similar to the
now disabled check.


(rillig)
diff -r1.10 -r1.11 src/tests/usr.bin/xlint/lint1/msg_130.c
diff -r1.8 -r1.9 src/tests/usr.bin/xlint/lint1/msg_130.exp
diff -r1.75 -r1.76 src/usr.bin/xlint/lint1/func.c

cvs diff -r1.10 -r1.11 src/tests/usr.bin/xlint/lint1/msg_130.c (expand / switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/msg_130.c 2021/03/09 23:40:43 1.10
+++ src/tests/usr.bin/xlint/lint1/msg_130.c 2021/03/10 00:02:00 1.11
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: msg_130.c,v 1.10 2021/03/09 23:40:43 rillig Exp $ */ 1/* $NetBSD: msg_130.c,v 1.11 2021/03/10 00:02:00 rillig Exp $ */
2# 3 "msg_130.c" 2# 3 "msg_130.c"
3 3
4// Test for message: enum type mismatch: '%s' '%s' '%s' [130] 4// Test for message: enum type mismatch: '%s' '%s' '%s' [130]
5 5
6/* See also msg_241.c, which covers unusual operators on enums. */ 6/* See also msg_241.c, which covers unusual operators on enums. */
7 7
8enum color { 8enum color {
9 RED = 1 << 0, 9 RED = 1 << 0,
10 GREEN = 1 << 1, 10 GREEN = 1 << 1,
11 BLUE = 1 << 2 11 BLUE = 1 << 2
12}; 12};
13 13
14enum size { 14enum size {
@@ -34,57 +34,58 @@ example(_Bool cond, enum color c, enum s @@ -34,57 +34,58 @@ example(_Bool cond, enum color c, enum s
34 sink((c | MEDIUM) != 0); /* might be useful to warn about */ 34 sink((c | MEDIUM) != 0); /* might be useful to warn about */
35 35
36 c |= MEDIUM; /* might be useful to warn about */ 36 c |= MEDIUM; /* might be useful to warn about */
37 c &= MEDIUM; /* might be useful to warn about */ 37 c &= MEDIUM; /* might be useful to warn about */
38 38
39 /* The cast to unsigned is required by GCC at WARNS=6. */ 39 /* The cast to unsigned is required by GCC at WARNS=6. */
40 c &= ~(unsigned)MEDIUM; /* might be useful to warn about */ 40 c &= ~(unsigned)MEDIUM; /* might be useful to warn about */
41} 41}
42 42
43void 43void
44switch_example(enum color c) 44switch_example(enum color c)
45{ 45{
46 switch (c) { 46 switch (c) {
47 case EVENING: /* expect: 130 */ 47 case EVENING: /* maybe someday expect: 130 */
48 case LARGE: /* expect: 130 */ 48 case LARGE: /* maybe someday expect: 130 */
49 case 0: /* expect: 130 */ 49 case 0: /* maybe someday expect: 130 */
50 sink(1 == 1); 50 sink(1 == 1);
51 break; 51 break;
52 default: 52 default:
53 break; 53 break;
54 } 54 }
55} 55}
56 56
57/* 57/*
58 * Unnamed enum types can be used as a container for constants, especially 58 * Unnamed enum types can be used as a container for constants, especially
59 * since in C90 and C99, even after the declaration 'static const int x = 3', 59 * since in C90 and C99, even after the declaration 'static const int x = 3',
60 * 'x' is not a constant expression. 60 * 'x' is not a constant expression.
61 */ 61 */
62enum { 62enum {
63 sizeof_int = sizeof(int), 63 sizeof_int = sizeof(int),
64 sizeof_long = sizeof(long) 64 sizeof_long = sizeof(long)
65}; 65};
66 66
67enum { 67enum {
68 sizeof_uint = sizeof(unsigned int) 68 sizeof_uint = sizeof(unsigned int)
69}; 69};
70 70
71int 71int
72enum_constant_from_unnamed_type(int x) 72enum_constant_from_unnamed_type(int x)
73{ 73{
 74 /* using an enum constant as constant-expression */
74 switch (x) { 75 switch (x) {
75 case sizeof_int: /* expect: 130 *//* FIXME */ 76 case sizeof_int:
76 return 1; 77 return 1;
77 case sizeof_long: /* expect: 130 *//* FIXME */ 78 case sizeof_long:
78 return 2; 79 return 2;
79 default: 80 default:
80 break; 81 break;
81 } 82 }
82 83
83 if (x == sizeof_int) 84 if (x == sizeof_int)
84 return 4; 85 return 4;
85 if (x > sizeof_int) 86 if (x > sizeof_int)
86 return 5; 87 return 5;
87 88
88 if (sizeof_int == sizeof_uint) /* expect: 130 *//* FIXME */ 89 if (sizeof_int == sizeof_uint) /* expect: 130 *//* FIXME */
89 return 6; 90 return 6;
90 91

cvs diff -r1.8 -r1.9 src/tests/usr.bin/xlint/lint1/Attic/msg_130.exp (expand / switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/msg_130.exp 2021/03/09 23:40:43 1.8
+++ src/tests/usr.bin/xlint/lint1/Attic/msg_130.exp 2021/03/10 00:02:00 1.9
@@ -1,10 +1,5 @@ @@ -1,10 +1,5 @@
1msg_130.c(29): warning: enum type mismatch: 'enum color' ':' 'enum daytime' [130] 1msg_130.c(29): warning: enum type mismatch: 'enum color' ':' 'enum daytime' [130]
2msg_130.c(31): warning: enum type mismatch: 'enum color' '!=' 'enum size' [130] 2msg_130.c(31): warning: enum type mismatch: 'enum color' '!=' 'enum size' [130]
3msg_130.c(32): warning: enum type mismatch: 'enum color' '==' 'enum size' [130] 3msg_130.c(32): warning: enum type mismatch: 'enum color' '==' 'enum size' [130]
4msg_130.c(47): warning: enum type mismatch: 'enum color' '==' 'enum daytime' [130] 4msg_130.c(89): warning: enum type mismatch: 'enum <unnamed>' '==' 'enum <unnamed>' [130]
5msg_130.c(48): warning: enum type mismatch: 'enum color' '==' 'enum size' [130] 5msg_130.c(127): warning: enum type mismatch: 'enum <unnamed>' '==' 'enum <unnamed>' [130]
6msg_130.c(49): warning: enum type mismatch: 'enum color' '==' 'int' [130] 
7msg_130.c(75): warning: enum type mismatch: 'int' '==' 'enum <unnamed>' [130] 
8msg_130.c(77): warning: enum type mismatch: 'int' '==' 'enum <unnamed>' [130] 
9msg_130.c(88): warning: enum type mismatch: 'enum <unnamed>' '==' 'enum <unnamed>' [130] 
10msg_130.c(126): warning: enum type mismatch: 'enum <unnamed>' '==' 'enum <unnamed>' [130] 

cvs diff -r1.75 -r1.76 src/usr.bin/xlint/lint1/func.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/func.c 2021/03/05 17:10:05 1.75
+++ src/usr.bin/xlint/lint1/func.c 2021/03/10 00:02:00 1.76
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: func.c,v 1.75 2021/03/05 17:10:05 rillig Exp $ */ 1/* $NetBSD: func.c,v 1.76 2021/03/10 00:02:00 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#if HAVE_NBTOOL_CONFIG_H 34#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 35#include "nbtool_config.h"
36#endif 36#endif
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39#if defined(__RCSID) && !defined(lint) 39#if defined(__RCSID) && !defined(lint)
40__RCSID("$NetBSD: func.c,v 1.75 2021/03/05 17:10:05 rillig Exp $"); 40__RCSID("$NetBSD: func.c,v 1.76 2021/03/10 00:02:00 rillig Exp $");
41#endif 41#endif
42 42
43#include <stdlib.h> 43#include <stdlib.h>
44#include <string.h> 44#include <string.h>
45 45
46#include "lint1.h" 46#include "lint1.h"
47#include "cgram.h" 47#include "cgram.h"
48 48
49/* 49/*
50 * Contains a pointer to the symbol table entry of the current function 50 * Contains a pointer to the symbol table entry of the current function
51 * definition. 51 * definition.
52 */ 52 */
53sym_t *funcsym; 53sym_t *funcsym;
@@ -427,29 +427,31 @@ named_label(sym_t *sym) @@ -427,29 +427,31 @@ named_label(sym_t *sym)
427} 427}
428 428
429static void 429static void
430check_case_label_enum(const tnode_t *tn, const cstk_t *ci) 430check_case_label_enum(const tnode_t *tn, const cstk_t *ci)
431{ 431{
432 /* similar to typeok_enum in tree.c */ 432 /* similar to typeok_enum in tree.c */
433 433
434 if (!(tn->tn_type->t_is_enum || ci->c_swtype->t_is_enum)) 434 if (!(tn->tn_type->t_is_enum || ci->c_swtype->t_is_enum))
435 return; 435 return;
436 if (tn->tn_type->t_is_enum && ci->c_swtype->t_is_enum && 436 if (tn->tn_type->t_is_enum && ci->c_swtype->t_is_enum &&
437 tn->tn_type->t_enum == ci->c_swtype->t_enum) 437 tn->tn_type->t_enum == ci->c_swtype->t_enum)
438 return; 438 return;
439 439
 440#if 0 /* not yet ready, see msg_130.c */
440 /* enum type mismatch: '%s' '%s' '%s' */ 441 /* enum type mismatch: '%s' '%s' '%s' */
441 warning(130, type_name(ci->c_swtype), getopname(EQ), 442 warning(130, type_name(ci->c_swtype), getopname(EQ),
442 type_name(tn->tn_type)); 443 type_name(tn->tn_type));
 444#endif
443} 445}
444 446
445static void 447static void
446check_case_label(tnode_t *tn, cstk_t *ci) 448check_case_label(tnode_t *tn, cstk_t *ci)
447{ 449{
448 clst_t *cl; 450 clst_t *cl;
449 val_t *v; 451 val_t *v;
450 val_t nv; 452 val_t nv;
451 tspec_t t; 453 tspec_t t;
452 454
453 if (ci == NULL) { 455 if (ci == NULL) {
454 /* case not in switch */ 456 /* case not in switch */
455 error(195); 457 error(195);