1 /* 2 * Copyright (C) 2009 Dan Carpenter. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt 16 */ 17 18 /* 19 * The idea behind this test is that if we have: 20 * void foo(int bar) 21 * { 22 * baz(1, bar); 23 * } 24 * 25 * Passing "bar" to foo() really means passing "bar" to baz(); 26 * 27 * In this case it would print: 28 * info: param_mapper 0 => bar 1 29 * 30 */ 31 32 #include "smatch.h" 33 34 static int my_id; 35 36 STATE(argument); 37 38 static struct symbol *func_sym; 39 40 static void delete(struct sm_state *sm, struct expression *mod_expr) 41 { 42 set_state(my_id, sm->name, sm->sym, &undefined); 43 } 44 45 static void match_function_def(struct symbol *sym) 46 { 47 struct symbol *arg; 48 49 func_sym = sym; 50 FOR_EACH_PTR(func_sym->ctype.base_type->arguments, arg) { 51 if (!arg->ident) { 52 continue; 53 } 54 set_state(my_id, arg->ident->name, arg, &argument); 55 } END_FOR_EACH_PTR(arg); 56 } 57 58 static int get_arg_num(struct expression *expr) 59 { 60 struct smatch_state *state; 61 struct symbol *arg; 62 struct symbol *this_arg; 63 int i; 64 65 expr = strip_expr(expr); 66 if (expr->type != EXPR_SYMBOL) 67 return -1; 68 this_arg = expr->symbol; 69 70 state = get_state_expr(my_id, expr); 71 if (!state || state != &argument) 72 return -1; 73 74 i = 0; 75 FOR_EACH_PTR(func_sym->ctype.base_type->arguments, arg) { 76 if (arg == this_arg) 77 return i; 78 i++; 79 } END_FOR_EACH_PTR(arg); 80 81 return -1; 82 } 83 84 static void match_call(struct expression *expr) 85 { 86 struct expression *tmp; 87 char *func; 88 int arg_num; 89 int i; 90 91 if (expr->fn->type != EXPR_SYMBOL) 92 return; 93 94 func = expr->fn->symbol_name->name; 95 96 i = 0; 97 FOR_EACH_PTR(expr->args, tmp) { 98 tmp = strip_expr(tmp); 99 arg_num = get_arg_num(tmp); 100 if (arg_num >= 0) 101 sm_msg("info: param_mapper %d => %s %d", arg_num, func, i); 102 i++; 103 } END_FOR_EACH_PTR(tmp); 104 } 105 106 void check_param_mapper(int id) 107 { 108 if (!option_param_mapper) 109 return; 110 my_id = id; 111 add_modification_hook(my_id, &delete); 112 add_hook(&match_function_def, FUNC_DEF_HOOK); 113 add_hook(&match_call, FUNCTION_CALL_HOOK); 114 } 115