Module Name: src
Committed By: rillig
Date: Sat Mar 9 10:54:12 UTC 2024
Modified Files:
src/usr.bin/xlint/lint1: func.c lint1.h
Log Message:
lint: internally store case label values in order of appearance
To generate a diff of this commit:
cvs rdiff -u -r1.181 -r1.182 src/usr.bin/xlint/lint1/func.c
cvs rdiff -u -r1.217 -r1.218 src/usr.bin/xlint/lint1/lint1.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.bin/xlint/lint1/func.c
diff -u src/usr.bin/xlint/lint1/func.c:1.181 src/usr.bin/xlint/lint1/func.c:1.182
--- src/usr.bin/xlint/lint1/func.c:1.181 Thu Feb 8 20:45:20 2024
+++ src/usr.bin/xlint/lint1/func.c Sat Mar 9 10:54:12 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: func.c,v 1.181 2024/02/08 20:45:20 rillig Exp $ */
+/* $NetBSD: func.c,v 1.182 2024/03/09 10:54:12 rillig Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID)
-__RCSID("$NetBSD: func.c,v 1.181 2024/02/08 20:45:20 rillig Exp $");
+__RCSID("$NetBSD: func.c,v 1.182 2024/03/09 10:54:12 rillig Exp $");
#endif
#include <stdlib.h>
@@ -162,12 +162,7 @@ end_control_statement(control_statement_
control_statement *cs = cstmt;
cstmt = cs->c_surrounding;
- case_label_t *cl, *next;
- for (cl = cs->c_case_labels; cl != NULL; cl = next) {
- next = cl->cl_next;
- free(cl);
- }
-
+ free(cs->c_case_labels.vals);
free(cs->c_switch_type);
free(cs);
}
@@ -436,6 +431,34 @@ check_case_label_enum(const tnode_t *tn,
#endif
}
+static bool
+check_duplicate_case_label(control_statement *cs, const val_t *nv)
+{
+ case_labels *labels = &cs->c_case_labels;
+ size_t i = 0, n = labels->len;
+
+ while (i < n && labels->vals[i].u.integer != nv->u.integer)
+ i++;
+
+ if (i < n) {
+ if (is_uinteger(nv->v_tspec))
+ /* duplicate case '%lu' in switch */
+ error(200, (unsigned long)nv->u.integer);
+ else
+ /* duplicate case '%ld' in switch */
+ error(199, (long)nv->u.integer);
+ return false;
+ }
+
+ if (labels->len >= labels->cap) {
+ labels->cap = 16 + 2 * labels->cap;
+ labels->vals = xrealloc(labels->vals,
+ sizeof(*labels->vals) * labels->cap);
+ }
+ labels->vals[labels->len++] = *nv;
+ return true;
+}
+
static void
check_case_label(tnode_t *tn)
{
@@ -487,27 +510,8 @@ check_case_label(tnode_t *tn)
convert_constant(CASE, 0, cs->c_switch_type, &nv, v);
free(v);
- /* look if we had this value already */
- case_label_t *cl;
- for (cl = cs->c_case_labels; cl != NULL; cl = cl->cl_next) {
- if (cl->cl_val.u.integer == nv.u.integer)
- break;
- }
- if (cl != NULL && is_uinteger(nv.v_tspec))
- /* duplicate case '%lu' in switch */
- error(200, (unsigned long)nv.u.integer);
- else if (cl != NULL)
- /* duplicate case '%ld' in switch */
- error(199, (long)nv.u.integer);
- else {
+ if (check_duplicate_case_label(cs, &nv))
check_getopt_case_label(nv.u.integer);
-
- /* Prepend the value to the list of case values. */
- cl = xcalloc(1, sizeof(*cl));
- cl->cl_val = nv;
- cl->cl_next = cs->c_case_labels;
- cs->c_case_labels = cl;
- }
}
void
@@ -660,7 +664,6 @@ stmt_switch_expr_stmt(void)
{
int nenum = 0, nclab = 0;
sym_t *esym;
- case_label_t *cl;
lint_assert(cstmt->c_switch_type != NULL);
@@ -675,8 +678,7 @@ stmt_switch_expr_stmt(void)
esym != NULL; esym = esym->s_next) {
nenum++;
}
- for (cl = cstmt->c_case_labels; cl != NULL; cl = cl->cl_next)
- nclab++;
+ nclab = (int)cstmt->c_case_labels.len;
if (hflag && eflag && nclab < nenum && !cstmt->c_default)
/* enumeration value(s) not handled in switch */
warning(206);
Index: src/usr.bin/xlint/lint1/lint1.h
diff -u src/usr.bin/xlint/lint1/lint1.h:1.217 src/usr.bin/xlint/lint1/lint1.h:1.218
--- src/usr.bin/xlint/lint1/lint1.h:1.217 Sat Mar 9 10:47:16 2024
+++ src/usr.bin/xlint/lint1/lint1.h Sat Mar 9 10:54:12 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: lint1.h,v 1.217 2024/03/09 10:47:16 rillig Exp $ */
+/* $NetBSD: lint1.h,v 1.218 2024/03/09 10:54:12 rillig Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@@ -425,14 +425,12 @@ typedef struct qual_ptr {
struct qual_ptr *p_next;
} qual_ptr;
-/*
- * The values of the 'case' labels, linked via cl_next in reverse order of
- * appearance in the code, that is from bottom to top.
- */
-typedef struct case_label {
- val_t cl_val;
- struct case_label *cl_next;
-} case_label_t;
+/* The values of the 'case' labels. */
+typedef struct {
+ val_t *vals;
+ size_t len;
+ size_t cap;
+} case_labels;
typedef enum {
CS_DO_WHILE,
@@ -466,7 +464,7 @@ typedef struct control_statement {
type_t *c_switch_type; /* type of switch expression */
tnode_t *c_switch_expr;
- case_label_t *c_case_labels; /* list of case values */
+ case_labels c_case_labels; /* list of case values */
memory_pool c_for_expr3_mem; /* saved memory for end of loop
* expression in for() */