extra: handle "if (a - 3 > 100) "
[smatch.git] / check_param_mapper.c
blob41c499a781f4c54871fbd312f7e57f4c901dfa85
1 /*
2 * sparse/check_param_mapper.c
4 * Copyright (C) 2009 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * The idea behind this test is that if we have:
12 * void foo(int bar)
13 * {
14 * baz(1, bar);
15 * }
17 * Passing "bar" to foo() really means passing "bar" to baz();
19 * In this case it would print:
20 * info: param_mapper 0 => bar 1
24 #include "smatch.h"
26 static int my_id;
28 STATE(argument);
30 static struct symbol *func_sym;
32 static void delete(struct sm_state *sm)
34 set_state(my_id, sm->name, sm->sym, &undefined);
37 static void match_function_def(struct symbol *sym)
39 struct symbol *arg;
41 func_sym = sym;
42 FOR_EACH_PTR(func_sym->ctype.base_type->arguments, arg) {
43 if (!arg->ident) {
44 continue;
46 set_state(my_id, arg->ident->name, arg, &argument);
47 } END_FOR_EACH_PTR(arg);
50 static int get_arg_num(struct expression *expr)
52 struct smatch_state *state;
53 struct symbol *arg;
54 struct symbol *this_arg;
55 int i;
57 expr = strip_expr(expr);
58 if (expr->type != EXPR_SYMBOL)
59 return -1;
60 this_arg = expr->symbol;
62 state = get_state_expr(my_id, expr);
63 if (!state || state != &argument)
64 return -1;
66 i = 0;
67 FOR_EACH_PTR(func_sym->ctype.base_type->arguments, arg) {
68 if (arg == this_arg)
69 return i;
70 i++;
71 } END_FOR_EACH_PTR(arg);
73 return -1;
76 static void match_call(struct expression *expr)
78 struct expression *tmp;
79 char *func;
80 int arg_num;
81 int i;
83 if (expr->fn->type != EXPR_SYMBOL)
84 return;
86 func = expr->fn->symbol_name->name;
88 i = 0;
89 FOR_EACH_PTR(expr->args, tmp) {
90 tmp = strip_expr(tmp);
91 arg_num = get_arg_num(tmp);
92 if (arg_num >= 0)
93 sm_msg("info: param_mapper %d => %s %d", arg_num, func, i);
94 i++;
95 } END_FOR_EACH_PTR(tmp);
98 void check_param_mapper(int id)
100 if (!option_param_mapper)
101 return;
102 my_id = id;
103 add_modification_hook(my_id, &delete);
104 add_hook(&match_function_def, FUNC_DEF_HOOK);
105 add_hook(&match_call, FUNCTION_CALL_HOOK);