Print this page
11506 smatch resync

*** 72,99 **** return 0; next = get_argument_from_call_expr(next->args, 0); return expr_equiv(next, arg); } static int is_valid_ptr(sval_t sval) { ! if (sval.type == &int_ctype && ! (sval.value == INT_MIN || sval.value == INT_MAX)) return 0; if (sval_cmp(valid_ptr_min_sval, sval) <= 0 && ! sval_cmp(valid_ptr_max_sval, sval) >= 0) return 1; return 0; } static void match_err_ptr(const char *fn, struct expression *expr, void *data) { struct expression *arg_expr; struct sm_state *sm, *tmp; - sval_t sval; arg_expr = get_argument_from_call_expr(expr->args, 0); sm = get_sm_state_expr(SMATCH_EXTRA, arg_expr); if (!sm) return; --- 72,134 ---- return 0; next = get_argument_from_call_expr(next->args, 0); return expr_equiv(next, arg); } + static int is_non_zero_int(struct range_list *rl) + { + struct data_range *tmp; + int cnt = -1; + + FOR_EACH_PTR(rl, tmp) { + cnt++; + + if (cnt == 0) { + if (tmp->min.value == INT_MIN && + tmp->max.value == -1) + continue; + } else if (cnt == 1) { + if (tmp->min.value == 1 && + tmp->max.value == INT_MAX) + return 1; + } + return 0; + } END_FOR_EACH_PTR(tmp); + return 0; + } + static int is_valid_ptr(sval_t sval) { ! if (sval.value == INT_MIN || sval.value == INT_MAX) return 0; if (sval_cmp(valid_ptr_min_sval, sval) <= 0 && ! sval_cmp(valid_ptr_max_sval, sval) >= 0) { return 1; + } return 0; } + static int has_distinct_zero(struct range_list *rl) + { + struct data_range *tmp; + + FOR_EACH_PTR(rl, tmp) { + if (tmp->min.value == 0 || tmp->max.value == 0) + return 1; + } END_FOR_EACH_PTR(tmp); + return 0; + } + static void match_err_ptr(const char *fn, struct expression *expr, void *data) { struct expression *arg_expr; struct sm_state *sm, *tmp; + if (is_impossible_path()) + return; + arg_expr = get_argument_from_call_expr(expr->args, 0); sm = get_sm_state_expr(SMATCH_EXTRA, arg_expr); if (!sm) return;
*** 107,127 **** return; FOR_EACH_PTR(sm->possible, tmp) { if (!estate_rl(tmp->state)) continue; if (is_valid_ptr(estate_min(tmp->state)) && is_valid_ptr(estate_max(tmp->state))) { sm_warning("passing a valid pointer to '%s'", fn); return; } - if (!rl_to_sval(estate_rl(tmp->state), &sval)) - continue; - if (sval.value != 0) - continue; - sm_warning("passing zero to '%s'", fn); - return; } END_FOR_EACH_PTR(tmp); } void check_zero_to_err_ptr(int id) { --- 142,164 ---- return; FOR_EACH_PTR(sm->possible, tmp) { if (!estate_rl(tmp->state)) continue; + if (is_non_zero_int(estate_rl(tmp->state))) + continue; + if (has_distinct_zero(estate_rl(tmp->state))) { + sm_warning("passing zero to '%s'", fn); + return; + } + if (strcmp(fn, "PTR_ERR") != 0) + continue; if (is_valid_ptr(estate_min(tmp->state)) && is_valid_ptr(estate_max(tmp->state))) { sm_warning("passing a valid pointer to '%s'", fn); return; } } END_FOR_EACH_PTR(tmp); } void check_zero_to_err_ptr(int id) {