static void match_loop(struct statement *stmt) { struct expression *iterator; char *iter_set; char *iter_tested; if (get_macro_name(stmt->pos)) return; iterator = get_iterator_set(stmt->iterator_pre_statement); iter_set = expr_to_var(iterator); iterator = get_iterator_tested(stmt->iterator_pre_condition); iter_tested = expr_to_var(iterator); if (!iter_set || !iter_tested) goto free; if (strcmp(iter_set, iter_tested)) goto free; /* smatch doesn't handle loops correctly so this silences some * false positives. */ if (right_side_changes(stmt->iterator_pre_condition)) goto free; if (implied_condition_false(stmt->iterator_pre_condition)) sm_msg("warn: we never enter this loop"); free: free_string(iter_set); free_string(iter_tested); }
static void match_dma_func(const char *fn, struct expression *expr, void *param) { struct expression *arg; struct symbol *sym; char *name; arg = get_argument_from_call_expr(expr->args, PTR_INT(param)); arg = strip_expr(arg); if (!arg) return; if (arg->type == EXPR_PREOP && arg->op == '&') { if (arg->unop->type != EXPR_SYMBOL) return; name = expr_to_str(arg); sm_msg("error: doing dma on the stack (%s)", name); free_string(name); return; } if (arg->type != EXPR_SYMBOL) return; sym = get_type(arg); if (!sym || sym->type != SYM_ARRAY) return; name = expr_to_var(arg); sm_msg("error: doing dma on the stack (%s)", name); free_string(name); }
static char *get_fn_name(struct expression *expr) { if (expr->type != EXPR_CALL) return NULL; if (expr->fn->type != EXPR_SYMBOL) return NULL; return expr_to_var(expr->fn); }
static void print_missing_break(struct expression *expr) { char *name; if (get_switch_expr() == last_print_expr) return; last_print_expr = get_switch_expr(); name = expr_to_var(expr); sm_msg("warn: missing break? reassigning '%s'", name); free_string(name); }
static void match_condition(struct expression *expr) { if (expr->type == EXPR_ASSIGNMENT) match_condition(expr->left); if (get_state_expr(my_id, expr) == &filehandle) { char *name; name = expr_to_var(expr); sm_msg("error: comparing a filehandle against zero '%s'", name); set_state_expr(my_id, expr, &oktocheck); free_string(name); } }
static void match_free(const char *fn, struct expression *expr, void *data) { struct expression *arg_expr; char *name; sval_t sval; arg_expr = get_argument_from_call_expr(expr->args, 0); if (!get_implied_value(arg_expr, &sval)) return; if (sval.value != 0) return; name = expr_to_var(arg_expr); sm_msg("warn: calling %s() when '%s' is always NULL.", fn, name); free_string(name); }
static void match_assign(struct expression *expr) { char *name; name = get_macro_name(expr->pos); if (!name || strcmp(name, "get_user") != 0) { match_normal_assign(expr); return; } name = expr_to_var(expr->right); if (!name || strcmp(name, "__val_gu") != 0) goto free; set_state_expr(my_max_id, expr->left, &user_data); set_state_expr(my_min_id, expr->left, &user_data); free: free_string(name); }
static void match_return(struct expression *ret_value) { sval_t rval; sval_t lret; char *name; if (!get_value(ret_value, &rval) || rval.value >= 0) return; if (get_implied_value(last_return, &lret)) return; if (!get_implied_max(last_return, &lret) || lret.value >= 0) return; if (get_implied_min(last_return, &lret) && !sval_is_min(lret)) return; name = expr_to_var(last_return); sm_msg("info: why not propagate '%s' from %s() instead of %s?", name, get_fn_name(last_func), sval_to_str(rval)); free_string(name); }