From bb9559db9abf7852bb89eef2e2c496ed8bc585e4 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 20 Dec 2013 12:43:11 +0300 Subject: [PATCH] extra: assume indexes are in bounds Sometimes, we know the size of the array but we don't know the value of the index. After this patch we assume that the index is valid. We only assume this after we have had a chance to warn about the overflow, so it shouldn't hide any bugs. If the index is used more than once though, the second use doesn't generate a warning. Signed-off-by: Dan Carpenter --- smatch_extra.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/smatch_extra.c b/smatch_extra.c index 24ff3551..c7173445 100644 --- a/smatch_extra.c +++ b/smatch_extra.c @@ -1286,6 +1286,44 @@ void __extra_match_condition(struct expression *expr) } } +static void assume_indexes_are_valid(struct expression *expr) +{ + struct expression *array_expr; + int array_size; + struct expression *offset; + struct symbol *offset_type; + struct range_list *rl_before; + struct range_list *rl_after; + struct range_list *filter = NULL; + sval_t size; + + expr = strip_expr(expr); + if (!is_array(expr)) + return; + + offset = get_array_offset(expr); + offset_type = get_type(offset); + if (offset_type && type_signed(offset_type)) { + filter = alloc_rl(sval_type_min(offset_type), + sval_type_val(offset_type, -1)); + } + + array_expr = strip_parens(expr->unop->left); + array_size = get_real_array_size(array_expr); + if (array_size > 1) { + size = sval_type_val(offset_type, array_size); + add_range(&filter, size, sval_type_max(offset_type)); + } + + if (!filter) + return; + get_absolute_rl(offset, &rl_before); + rl_after = rl_filter(rl_before, filter); + if (rl_equiv(rl_before, rl_after)) + return; + set_extra_expr_nomod(offset, alloc_estate_rl(rl_after)); +} + /* returns 1 if it is not possible for expr to be value, otherwise returns 0 */ int implied_not_equal(struct expression *expr, long long val) { @@ -1545,4 +1583,6 @@ void register_smatch_extra_late(int id) add_hook(&match_call_info, FUNCTION_CALL_HOOK); add_member_info_callback(my_id, struct_member_callback); add_returned_member_callback(my_id, returned_member_callback); + + add_hook(&assume_indexes_are_valid, OP_HOOK); } -- 2.11.4.GIT