Module Name:    src
Committed By:   rillig
Date:           Sat Mar  9 14:54:14 UTC 2024

Modified Files:
        src/usr.bin/xlint/lint1: tree.c

Log Message:
lint: merge duplicate code for checking array index


To generate a diff of this commit:
cvs rdiff -u -r1.612 -r1.613 src/usr.bin/xlint/lint1/tree.c

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/tree.c
diff -u src/usr.bin/xlint/lint1/tree.c:1.612 src/usr.bin/xlint/lint1/tree.c:1.613
--- src/usr.bin/xlint/lint1/tree.c:1.612	Sat Mar  9 13:54:47 2024
+++ src/usr.bin/xlint/lint1/tree.c	Sat Mar  9 14:54:14 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: tree.c,v 1.612 2024/03/09 13:54:47 rillig Exp $	*/
+/*	$NetBSD: tree.c,v 1.613 2024/03/09 14:54:14 rillig Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(__RCSID)
-__RCSID("$NetBSD: tree.c,v 1.612 2024/03/09 13:54:47 rillig Exp $");
+__RCSID("$NetBSD: tree.c,v 1.613 2024/03/09 14:54:14 rillig Exp $");
 #endif
 
 #include <float.h>
@@ -4327,52 +4327,37 @@ expr(tnode_t *tn, bool vctx, bool cond, 
 		expr_free_all();
 }
 
-/*
- * Checks the range of array indices, if possible.
- * amper is set if only the address of the element is used. This
- * means that the index is allowed to refer to the first element
- * after the array.
- */
+/* If the expression has the form '*(arr + idx)', check the array index. */
 static void
-check_array_index(tnode_t *tn, bool amper)
+check_array_index(const tnode_t *indir, bool taking_address)
 {
-	lint_assert(has_operands(tn));
-	const tnode_t *ln = tn->u.ops.left;
-	const tnode_t *rn = tn->u.ops.right;
-
-	/* We can only check constant indices. */
-	if (rn->tn_op != CON)
-		return;
-
-	/* Return if the left node does not stem from an array. */
-	if (ln->tn_op != ADDR)
-		return;
-	if (ln->u.ops.left->tn_op != STRING && ln->u.ops.left->tn_op != NAME)
-		return;
-	if (ln->u.ops.left->tn_type->t_tspec != ARRAY)
-		return;
+	const tnode_t *plus, *arr, *idx;
 
-	/*
-	 * For incomplete array types, we can print a warning only if the index
-	 * is negative.
-	 */
-	if (is_incomplete(ln->u.ops.left->tn_type)
-	    && rn->u.value.u.integer >= 0)
-		return;
+	if (indir->tn_op == INDIR
+	    && (plus = indir->u.ops.left, plus->tn_op == PLUS)
+	    && plus->u.ops.left->tn_op == ADDR
+	    && (arr = plus->u.ops.left->u.ops.left, true)
+	    && (arr->tn_op == STRING || arr->tn_op == NAME)
+	    && arr->tn_type->t_tspec == ARRAY
+	    && (idx = plus->u.ops.right, idx->tn_op == CON)
+	    && (!is_incomplete(arr->tn_type) || idx->u.value.u.integer < 0))
+		goto proceed;
+	return;
 
-	int elsz = length_in_bits(ln->tn_type->t_subt, NULL);
+proceed:;
+	int elsz = length_in_bits(arr->tn_type->t_subt, NULL);
 	if (elsz == 0)
 		return;
 	elsz /= CHAR_SIZE;
 
 	/* Change the unit of the index from bytes to element size. */
-	int64_t con = is_uinteger(rn->tn_type->t_tspec)
-	    ? (int64_t)((uint64_t)rn->u.value.u.integer / elsz)
-	    : rn->u.value.u.integer / elsz;
+	int64_t con = is_uinteger(idx->tn_type->t_tspec)
+	    ? (int64_t)((uint64_t)idx->u.value.u.integer / elsz)
+	    : idx->u.value.u.integer / elsz;
 
-	int dim = ln->u.ops.left->tn_type->u.dimension + (amper ? 1 : 0);
+	int dim = arr->tn_type->u.dimension + (taking_address ? 1 : 0);
 
-	if (!is_uinteger(rn->tn_type->t_tspec) && con < 0)
+	if (!is_uinteger(idx->tn_type->t_tspec) && con < 0)
 		/* array subscript cannot be negative: %ld */
 		warning(167, (long)con);
 	else if (dim > 0 && (uint64_t)con >= (uint64_t)dim)
@@ -4389,15 +4374,7 @@ check_expr_addr(const tnode_t *ln, bool 
 			mark_as_set(ln->u.sym);
 		mark_as_used(ln->u.sym, fcall, szof);
 	}
-	if (ln->tn_op == INDIR && ln->u.ops.left->tn_op == PLUS)
-		check_array_index(ln->u.ops.left, true);
-}
-
-static void
-check_expr_load(const tnode_t *ln)
-{
-	if (ln->tn_op == INDIR && ln->u.ops.left->tn_op == PLUS)
-		check_array_index(ln->u.ops.left, false);
+	check_array_index(ln, true);
 }
 
 /*
@@ -4439,9 +4416,7 @@ check_expr_assign(const tnode_t *ln, boo
 		if (ln->u.sym->s_scl == EXTERN)
 			outusg(ln->u.sym);
 	}
-	if (ln->tn_op == INDIR && ln->u.ops.left->tn_op == PLUS)
-		/* check the range of array indices */
-		check_array_index(ln->u.ops.left, false);
+	check_array_index(ln, false);
 }
 
 static void
@@ -4463,7 +4438,7 @@ check_expr_op(op_t op, const tnode_t *ln
 		check_expr_addr(ln, szof, fcall);
 		break;
 	case LOAD:
-		check_expr_load(ln);
+		check_array_index(ln, false);
 		/* FALLTHROUGH */
 	case INCBEF:
 	case DECBEF:

Reply via email to