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: in the check for array[enum], allo...
details: https://anonhg.NetBSD.org/src/rev/03d0429758ba
branches: trunk
changeset: 1024732:03d0429758ba
user: rillig <rillig%NetBSD.org@localhost>
date: Mon Nov 01 11:46:50 2021 +0000
description:
lint: in the check for array[enum], allow enum constant NUM
When an enum type defines a constant NUM_VALUES, this constant is
usually not part of the enum values available to the application but
rather a handy place for defining the number of other enum values. Don't
warn about this case.
Seen in openpam_impl.h and several other places.
diffstat:
tests/usr.bin/xlint/lint1/msg_348.c | 50 ++++++++++++++++++++++++++++++++++-
tests/usr.bin/xlint/lint1/msg_348.exp | 13 +++++---
usr.bin/xlint/lint1/tree.c | 37 +++++++++++++++++--------
3 files changed, 82 insertions(+), 18 deletions(-)
diffs (158 lines):
diff -r 47366857e3cb -r 03d0429758ba tests/usr.bin/xlint/lint1/msg_348.c
--- a/tests/usr.bin/xlint/lint1/msg_348.c Mon Nov 01 10:05:18 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_348.c Mon Nov 01 11:46:50 2021 +0000
@@ -1,11 +1,16 @@
-/* $NetBSD: msg_348.c,v 1.2 2021/10/31 23:15:44 rillig Exp $ */
+/* $NetBSD: msg_348.c,v 1.3 2021/11/01 11:46:50 rillig Exp $ */
# 3 "msg_348.c"
// Test for message 348: maximum value %d of '%s' does not match maximum array index %d [348]
+/* lint1-extra-flags: -r */
+
enum color {
red,
green,
+ /* expect+3: previous declaration of blue [260] */
+ /* expect+2: previous declaration of blue [260] */
+ /* expect+1: previous declaration of blue [260] */
blue
};
@@ -115,3 +120,46 @@
/* No warning since at least 1 enum constant is outside of INT. */
return name[large];
}
+
+enum color_with_count {
+ cc_red,
+ cc_green,
+ cc_blue,
+ cc_num_values
+};
+
+const char *
+color_with_count_name(enum color_with_count color)
+{
+ static const char *const name[] = { "red", "green", "blue" };
+ /* No warning since the maximum enum constant is a count. */
+ return name[color];
+}
+
+/*
+ * If the last enum constant contains "num" in its name, it is not
+ * necessarily the count of the other enum values, it may also be a
+ * legitimate application value, therefore don't warn in this case.
+ */
+const char *
+color_with_num(enum color_with_count color)
+{
+ static const char *const name[] = { "r", "g", "b", "num" };
+ /* No warning since the maximum values already match. */
+ return name[color];
+}
+
+enum color_with_uc_count {
+ CC_RED,
+ CC_GREEN,
+ CC_BLUE,
+ CC_NUM_VALUES
+};
+
+const char *
+color_with_uc_count_name(enum color_with_uc_count color)
+{
+ static const char *const name[] = { "red", "green", "blue" };
+ /* No warning since the maximum enum constant is a count. */
+ return name[color];
+}
diff -r 47366857e3cb -r 03d0429758ba tests/usr.bin/xlint/lint1/msg_348.exp
--- a/tests/usr.bin/xlint/lint1/msg_348.exp Mon Nov 01 10:05:18 2021 +0000
+++ b/tests/usr.bin/xlint/lint1/msg_348.exp Mon Nov 01 11:46:50 2021 +0000
@@ -1,5 +1,8 @@
-msg_348.c(32): warning: maximum value 2 of 'enum color' does not match maximum array index 1 [348]
-msg_348.c(45): warning: maximum value 2 of 'enum color' does not match maximum array index 3 [348]
-msg_348.c(82): warning: maximum value 2 of 'enum color' does not match maximum array index 1 [348]
-msg_348.c(103): warning: integral constant too large [56]
-msg_348.c(105): warning: integral constant too large [56]
+msg_348.c(37): warning: maximum value 2 of 'enum color' does not match maximum array index 1 [348]
+msg_348.c(14): previous declaration of blue [260]
+msg_348.c(50): warning: maximum value 2 of 'enum color' does not match maximum array index 3 [348]
+msg_348.c(14): previous declaration of blue [260]
+msg_348.c(87): warning: maximum value 2 of 'enum color' does not match maximum array index 1 [348]
+msg_348.c(14): previous declaration of blue [260]
+msg_348.c(108): warning: integral constant too large [56]
+msg_348.c(110): warning: integral constant too large [56]
diff -r 47366857e3cb -r 03d0429758ba usr.bin/xlint/lint1/tree.c
--- a/usr.bin/xlint/lint1/tree.c Mon Nov 01 10:05:18 2021 +0000
+++ b/usr.bin/xlint/lint1/tree.c Mon Nov 01 11:46:50 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tree.c,v 1.388 2021/10/31 23:15:44 rillig Exp $ */
+/* $NetBSD: tree.c,v 1.389 2021/11/01 11:46:50 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
-__RCSID("$NetBSD: tree.c,v 1.388 2021/10/31 23:15:44 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.389 2021/11/01 11:46:50 rillig Exp $");
#endif
#include <float.h>
@@ -1776,8 +1776,9 @@
static void
check_enum_array_index(const tnode_t *ln, const tnode_t *rn)
{
- int max_enum_value, max_array_index;
- const struct sym *ec;
+ int max_array_index;
+ int64_t max_enum_value;
+ const struct sym *ec, *max_ec;
if (ln->tn_op != ADDR)
return;
@@ -1794,22 +1795,34 @@
if (rn->tn_left->tn_type->t_tspec != ENUM)
return;
- max_enum_value = INT_MIN;
ec = rn->tn_left->tn_type->t_enum->en_first_enumerator;
- for (; ec != NULL; ec = ec->s_next) {
- int64_t ev = ec->s_value.v_quad;
- lint_assert(INT_MIN <= ev && ev <= INT_MAX);
- if (ev > max_enum_value)
- max_enum_value = (int)ev;
- }
+ max_ec = ec;
+ lint_assert(ec != NULL);
+ for (ec = ec->s_next; ec != NULL; ec = ec->s_next)
+ if (ec->s_value.v_quad > max_ec->s_value.v_quad)
+ max_ec = ec;
+
+ max_enum_value = max_ec->s_value.v_quad;
+ lint_assert(INT_MIN <= max_enum_value && max_enum_value <= INT_MAX);
max_array_index = ln->tn_left->tn_type->t_dim - 1;
if (max_enum_value == max_array_index)
return;
+ /*
+ * If the largest enum constant is named '*_NUM_*', it is typically
+ * not part of the allowed enum values but a marker for the number
+ * of actual enum values.
+ */
+ if (max_enum_value == max_array_index + 1 &&
+ (strstr(max_ec->s_name, "NUM") != NULL ||
+ strstr(max_ec->s_name, "num") != NULL))
+ return;
+
/* maximum value %d of '%s' does not match maximum array index %d */
- warning(348, max_enum_value, type_name(rn->tn_left->tn_type),
+ warning(348, (int)max_enum_value, type_name(rn->tn_left->tn_type),
max_array_index);
+ print_previous_declaration(-1, max_ec);
}
/*
Home |
Main Index |
Thread Index |
Old Index