Print this page
11972 resync smatch

*** 371,381 **** { db_info->ret_str = alloc_sname(ret_str), db_info->ret_state = state; } ! static bool fake_a_param_assignment(struct expression *expr, const char *return_str) { struct expression *arg, *left, *right, *tmp, *fake_assign; char *p; int param; char buf[256]; --- 371,381 ---- { db_info->ret_str = alloc_sname(ret_str), db_info->ret_state = state; } ! static bool fake_a_param_assignment(struct expression *expr, const char *return_str, struct smatch_state *orig) { struct expression *arg, *left, *right, *tmp, *fake_assign; char *p; int param; char buf[256];
*** 435,444 **** --- 435,464 ---- return false; fake_assign = assign_expression(left, '=', right); __in_fake_parameter_assign++; __split_expr(fake_assign); __in_fake_parameter_assign--; + + /* + * If the return is "0-65531[$0->nla_len - 4]" the faked expression + * is maybe (-4)-65531 but we know it is in the 0-65531 range so both + * parts have to be considered. We use _nomod() because it's not really + * another modification, it's just a clarification. + * + */ + if (estate_rl(orig)) { + struct smatch_state *faked; + struct range_list *rl; + + faked = get_extra_state(left); + if (estate_rl(faked)) { + rl = rl_intersection(estate_rl(faked), estate_rl(orig)); + if (rl) + set_extra_expr_nomod(expr, alloc_estate_rl(rl)); + } + } + return true; } static void set_return_assign_state(struct db_callback_info *db_info) {
*** 447,459 **** if (!db_info->ret_state) return; state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state)))); set_extra_expr_mod(expr, state); db_info->ret_state = NULL; - fake_a_param_assignment(db_info->expr, db_info->ret_str); db_info->ret_str = NULL; } static void set_other_side_state(struct db_callback_info *db_info) { --- 467,480 ---- if (!db_info->ret_state) return; state = alloc_estate_rl(cast_rl(get_type(expr), clone_rl(estate_rl(db_info->ret_state)))); + if (!fake_a_param_assignment(db_info->expr, db_info->ret_str, state)) set_extra_expr_mod(expr, state); + db_info->ret_state = NULL; db_info->ret_str = NULL; } static void set_other_side_state(struct db_callback_info *db_info) {
*** 1090,1100 **** set_state(-1, "unnull_path", NULL, &true_state); __add_return_comparison(strip_expr(db_info->expr), ret_str); __add_return_to_param_mapping(db_info->expr, ret_str); } - FOR_EACH_PTR(db_return_states_list, tmp) { if (tmp->type == type) tmp->callback(db_info->expr, param, key, value); } END_FOR_EACH_PTR(tmp); --- 1111,1120 ----
*** 1168,1183 **** } static void match_function_call(struct expression *expr) { struct call_back_list *call_backs; ! if (expr->fn->type == EXPR_SYMBOL && expr->fn->symbol) { ! call_backs = search_callback(func_hash, (char *)expr->fn->symbol->ident->name); if (call_backs) call_call_backs(call_backs, REGULAR_CALL, ! expr->fn->symbol->ident->name, expr); } db_return_states_call(expr); } static void match_macro_assign(struct expression *expr) --- 1188,1205 ---- } static void match_function_call(struct expression *expr) { struct call_back_list *call_backs; + struct expression *fn; ! fn = strip_expr(expr->fn); ! if (fn->type == EXPR_SYMBOL && fn->symbol) { ! call_backs = search_callback(func_hash, (char *)fn->symbol->ident->name); if (call_backs) call_call_backs(call_backs, REGULAR_CALL, ! fn->symbol->ident->name, expr); } db_return_states_call(expr); } static void match_macro_assign(struct expression *expr)