Module Name: src Committed By: rillig Date: Tue Mar 19 23:19:04 UTC 2024
Modified Files: src/usr.bin/xlint/lint1: ckctype.c ckgetopt.c debug.c emit1.c tree.c Log Message: lint: keep invalid arguments in function calls Previously, arguments of incomplete type or 'void' cleared all arguments of the function call expression, requiring extra checks in later checks. Invalid function calls are now exported to the .ln files, but that's irrelevant in practice as these invalid function calls make lint1 fail, after which xlint removes the .ln file. To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 src/usr.bin/xlint/lint1/ckctype.c cvs rdiff -u -r1.26 -r1.27 src/usr.bin/xlint/lint1/ckgetopt.c cvs rdiff -u -r1.73 -r1.74 src/usr.bin/xlint/lint1/debug.c cvs rdiff -u -r1.92 -r1.93 src/usr.bin/xlint/lint1/emit1.c cvs rdiff -u -r1.624 -r1.625 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/ckctype.c diff -u src/usr.bin/xlint/lint1/ckctype.c:1.11 src/usr.bin/xlint/lint1/ckctype.c:1.12 --- src/usr.bin/xlint/lint1/ckctype.c:1.11 Sat Mar 9 13:54:47 2024 +++ src/usr.bin/xlint/lint1/ckctype.c Tue Mar 19 23:19:03 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ckctype.c,v 1.11 2024/03/09 13:54:47 rillig Exp $ */ +/* $NetBSD: ckctype.c,v 1.12 2024/03/19 23:19:03 rillig Exp $ */ /*- * Copyright (c) 2021 The NetBSD Foundation, Inc. @@ -36,7 +36,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: ckctype.c,v 1.11 2024/03/09 13:54:47 rillig Exp $"); +__RCSID("$NetBSD: ckctype.c,v 1.12 2024/03/19 23:19:03 rillig Exp $"); #endif #include <string.h> @@ -123,7 +123,7 @@ void check_ctype_function_call(const function_call *call) { - if (call->args_len == 1 && call->args != NULL && + if (call->args_len == 1 && call->func->tn_op == NAME && is_ctype_function(call->func->u.sym->s_name)) check_ctype_arg(call->func->u.sym->s_name, call->args[0]); Index: src/usr.bin/xlint/lint1/ckgetopt.c diff -u src/usr.bin/xlint/lint1/ckgetopt.c:1.26 src/usr.bin/xlint/lint1/ckgetopt.c:1.27 --- src/usr.bin/xlint/lint1/ckgetopt.c:1.26 Sat Mar 9 13:54:47 2024 +++ src/usr.bin/xlint/lint1/ckgetopt.c Tue Mar 19 23:19:03 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: ckgetopt.c,v 1.26 2024/03/09 13:54:47 rillig Exp $ */ +/* $NetBSD: ckgetopt.c,v 1.27 2024/03/19 23:19:03 rillig Exp $ */ /*- * Copyright (c) 2021 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: ckgetopt.c,v 1.26 2024/03/09 13:54:47 rillig Exp $"); +__RCSID("$NetBSD: ckgetopt.c,v 1.27 2024/03/19 23:19:03 rillig Exp $"); #endif #include <stdbool.h> @@ -96,8 +96,6 @@ is_getopt_condition(const tnode_t *tn, c && call->func->u.ops.left->tn_op == NAME && strcmp(call->func->u.ops.left->u.sym->s_name, "getopt") == 0 && call->args_len == 3 - && call->args != NULL - && (last_arg = call->args[2]) != NULL && last_arg->tn_op == CVT && last_arg->u.ops.left->tn_op == ADDR Index: src/usr.bin/xlint/lint1/debug.c diff -u src/usr.bin/xlint/lint1/debug.c:1.73 src/usr.bin/xlint/lint1/debug.c:1.74 --- src/usr.bin/xlint/lint1/debug.c:1.73 Sat Mar 9 13:54:47 2024 +++ src/usr.bin/xlint/lint1/debug.c Tue Mar 19 23:19:03 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: debug.c,v 1.73 2024/03/09 13:54:47 rillig Exp $ */ +/* $NetBSD: debug.c,v 1.74 2024/03/19 23:19:03 rillig Exp $ */ /*- * Copyright (c) 2021 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: debug.c,v 1.73 2024/03/09 13:54:47 rillig Exp $"); +__RCSID("$NetBSD: debug.c,v 1.74 2024/03/19 23:19:03 rillig Exp $"); #endif #include <stdlib.h> @@ -247,11 +247,8 @@ debug_node(const tnode_t *tn) // NOLINT( debug_indent_inc(); const function_call *call = tn->u.call; debug_node(call->func); - if (call->args != NULL) { - for (size_t i = 0; i < call->args_len; i++) - debug_node(call->args[i]); - } else - debug_step("error in arguments"); + for (size_t i = 0, n = call->args_len; i < n; i++) + debug_node(call->args[i]); debug_indent_dec(); break; default: Index: src/usr.bin/xlint/lint1/emit1.c diff -u src/usr.bin/xlint/lint1/emit1.c:1.92 src/usr.bin/xlint/lint1/emit1.c:1.93 --- src/usr.bin/xlint/lint1/emit1.c:1.92 Sat Mar 9 13:54:47 2024 +++ src/usr.bin/xlint/lint1/emit1.c Tue Mar 19 23:19:03 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: emit1.c,v 1.92 2024/03/09 13:54:47 rillig Exp $ */ +/* $NetBSD: emit1.c,v 1.93 2024/03/19 23:19:03 rillig Exp $ */ /* * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> #if defined(__RCSID) -__RCSID("$NetBSD: emit1.c,v 1.92 2024/03/09 13:54:47 rillig Exp $"); +__RCSID("$NetBSD: emit1.c,v 1.93 2024/03/19 23:19:03 rillig Exp $"); #endif #include <stdlib.h> @@ -337,9 +337,8 @@ outcall(const tnode_t *tn, bool retval_u */ const function_call *call = tn->u.call; - /* information about arguments */ - for (size_t n = 1; call->args != NULL && n <= call->args_len; n++) { - const tnode_t *arg = call->args[n - 1]; + for (size_t i = 0, n = call->args_len; i < n; i++) { + const tnode_t *arg = call->args[i]; if (arg->tn_op == CON) { tspec_t t = arg->tn_type->t_tspec; if (is_integer(t)) { @@ -357,7 +356,7 @@ outcall(const tnode_t *tn, bool retval_u else /* negative if cast to signed */ outchar('n'); - outint((int)n); + outint((int)i + 1); } } else if (arg->tn_op == ADDR && arg->u.ops.left->tn_op == STRING && @@ -370,7 +369,7 @@ outcall(const tnode_t *tn, bool retval_u /* string literal, write all format specifiers */ outchar('s'); - outint((int)n); + outint((int)i + 1); outfstrg(buf.data); free(buf.data); } @@ -382,7 +381,7 @@ outcall(const tnode_t *tn, bool retval_u /* types of arguments */ outchar('f'); outint((int)call->args_len); - for (size_t i = 0; call->args != NULL && i < call->args_len; i++) + for (size_t i = 0, n = call->args_len; i < n; i++) outtype(call->args[i]->tn_type); /* expected type of return value */ outtype(tn->tn_type); Index: src/usr.bin/xlint/lint1/tree.c diff -u src/usr.bin/xlint/lint1/tree.c:1.624 src/usr.bin/xlint/lint1/tree.c:1.625 --- src/usr.bin/xlint/lint1/tree.c:1.624 Tue Mar 12 07:56:08 2024 +++ src/usr.bin/xlint/lint1/tree.c Tue Mar 19 23:19:04 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: tree.c,v 1.624 2024/03/12 07:56:08 rillig Exp $ */ +/* $NetBSD: tree.c,v 1.625 2024/03/19 23:19:04 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.624 2024/03/12 07:56:08 rillig Exp $"); +__RCSID("$NetBSD: tree.c,v 1.625 2024/03/19 23:19:04 rillig Exp $"); #endif #include <float.h> @@ -1710,9 +1710,8 @@ use(const tnode_t *tn) case CALL: case ICALL:; const function_call *call = tn->u.call; - if (call->args != NULL) - for (size_t i = 0, n = call->args_len; i < n; i++) - use(call->args[i]); + for (size_t i = 0, n = call->args_len; i < n; i++) + use(call->args[i]); break; default: lint_assert(has_operands(tn)); @@ -2694,28 +2693,12 @@ is_const_char_pointer(const tnode_t *tn) } static bool -is_first_arg_const_char_pointer(const tnode_t *tn) -{ - return tn->u.call->args != NULL - && tn->u.call->args_len >= 1 - && is_const_char_pointer(tn->u.call->args[0]); -} - -static bool is_const_pointer(const tnode_t *tn) { const type_t *tp = before_conversion(tn)->tn_type; return tp->t_tspec == PTR && tp->t_subt->t_const; } -static bool -is_second_arg_const_pointer(const tnode_t *tn) -{ - return tn->u.call->args_len >= 2 - && tn->u.call->args != NULL - && is_const_pointer(tn->u.call->args[1]); -} - static void check_unconst_function(const type_t *lstp, const tnode_t *rn) { @@ -2724,7 +2707,8 @@ check_unconst_function(const type_t *lst if (lstp->t_tspec == CHAR && !lstp->t_const && is_direct_function_call(rn, &function_name) && is_unconst_function(function_name) && - is_first_arg_const_char_pointer(rn)) { + rn->u.call->args_len >= 1 && + is_const_char_pointer(rn->u.call->args[0])) { /* call to '%s' effectively discards 'const' from argument */ warning(346, function_name); } @@ -2732,7 +2716,8 @@ check_unconst_function(const type_t *lst if (!lstp->t_const && is_direct_function_call(rn, &function_name) && strcmp(function_name, "bsearch") == 0 && - is_second_arg_const_pointer(rn)) { + rn->u.call->args_len >= 2 && + is_const_pointer(rn->u.call->args[1])) { /* call to '%s' effectively discards 'const' from argument */ warning(346, function_name); } @@ -4220,7 +4205,7 @@ check_prototype_argument( * Check types of all function arguments and insert conversions, * if necessary. */ -static bool +static void check_function_arguments(const function_call *call) { type_t *ftp = call->func->tn_type->t_subt; @@ -4239,42 +4224,40 @@ check_function_arguments(const function_ param = NULL; } - for (int n = 1; n <= narg; n++) { - tnode_t *arg = call->args[n - 1]; + for (int i = 0; i < narg; i++) { + tnode_t *arg = call->args[i]; /* some things which are always not allowed */ tspec_t at = arg->tn_type->t_tspec; if (at == VOID) { /* void expressions may not be arguments, arg #%d */ - error(151, n); - return false; + error(151, i + 1); + return; } if (is_struct_or_union(at) && is_incomplete(arg->tn_type)) { /* argument cannot have unknown size, arg #%d */ - error(152, n); - return false; + error(152, i + 1); + return; } if (is_integer(at) && arg->tn_type->t_is_enum && is_incomplete(arg->tn_type)) { /* argument cannot have unknown size, arg #%d */ - warning(152, n); + warning(152, i + 1); } arg = cconv(arg); - call->args[n - 1] = arg; + call->args[i] = arg; arg = param != NULL - ? check_prototype_argument(n, param->s_type, arg) + ? check_prototype_argument(i + 1, param->s_type, arg) : promote(NOOP, true, arg); - call->args[n - 1] = arg; + call->args[i] = arg; if (param != NULL) param = param->s_next; } - - return true; } tnode_t * @@ -4284,7 +4267,7 @@ build_function_call(tnode_t *func, bool if (func == NULL) return NULL; - op_t fcop = func->tn_op == NAME && func->tn_type->t_tspec == FUNC + op_t op = func->tn_op == NAME && func->tn_type->t_tspec == FUNC ? CALL : ICALL; call->func = func; @@ -4300,11 +4283,10 @@ build_function_call(tnode_t *func, bool return NULL; } - if (!check_function_arguments(call)) - call->args = NULL; + check_function_arguments(call); tnode_t *ntn = expr_alloc_tnode(); - ntn->tn_op = fcop; + ntn->tn_op = op; ntn->tn_type = func->tn_type->t_subt->t_subt; ntn->tn_sys = sys; ntn->u.call = call; @@ -4592,11 +4574,9 @@ check_expr_misc(const tnode_t *tn, bool bool discard = op == CVT && tn->tn_type->t_tspec == VOID; check_expr_misc(call->func, false, false, false, op == CALL, discard, szof); - if (call->args != NULL) { - for (size_t i = 0, n = call->args_len; i < n; i++) - check_expr_misc(call->args[i], - false, false, false, false, false, szof); - } + for (size_t i = 0, n = call->args_len; i < n; i++) + check_expr_misc(call->args[i], + false, false, false, false, false, szof); return; }