static void match_returns_handle(const char *fn, struct expression *expr, void *info) { char *left_name = NULL; struct symbol *left_sym; left_name = expr_to_var_sym(expr->left, &left_sym); if (!left_name || !left_sym) goto free; set_state_expr(my_id, expr->left, &filehandle); free: free_string(left_name); }
static void match_allocation(const char *fn, struct expression *expr, void *info) { char *left_name; struct symbol *left_sym; left_name = expr_to_var_sym(expr->left, &left_sym); if (!left_name || !left_sym) goto free; if (left_sym->ctype.modifiers & (MOD_NONLOCAL | MOD_STATIC | MOD_ADDRESSABLE)) goto free; add_tracker(&allocated, my_id, left_name, left_sym); free: free_string(left_name); }
static void match_return(struct expression *ret_value) { char *name; struct symbol *sym; sval_t tmp; if (__inline_fn) return; if (get_value(ret_value, &tmp) && tmp.value == 0) return; returns_new_stuff = 1; name = expr_to_var_sym(ret_value, &sym); if (!name || !sym) { returns_old_stuff = 1; goto free; } if (!in_tracker_list(allocated, my_id, name, sym)) returns_old_stuff = 1; free: free_string(name); }
static void check_expr(struct expression *expr) { struct sm_state *sm; sval_t max; sval_t sval; char *name; int overflow = 0; int underflow = 0; sm = get_sm_state_expr(my_max_id, expr); if (sm && slist_has_state(sm->possible, &user_data)) { if (!get_absolute_max(expr, &max) || sval_cmp_val(max, 20000) > 0) overflow = 1; } sm = get_sm_state_expr(my_min_id, expr); if (sm && slist_has_state(sm->possible, &user_data)) { if (!get_absolute_min(expr, &sval) || (sval_is_negative(sval) && sval_cmp_val(sval, -20000) < 0)) underflow = 1; } if (!overflow && !underflow) return; name = expr_to_var_sym(expr, NULL); if (overflow && underflow) sm_msg("warn: check for integer over/underflow '%s'", name); else if (underflow) sm_msg("warn: check for integer underflow '%s'", name); else sm_msg("warn: check for integer overflow '%s'", name); free_string(name); set_state_expr(my_max_id, expr, &capped); set_state_expr(my_min_id, expr, &capped); }