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: