1 /* 2 * Copyright (C) 2017 Oracle. 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 #include "smatch.h" 19 #include "smatch_extra.h" 20 21 static int find_param_eq(struct expression *expr, int size) 22 { 23 struct expression *arg; 24 sval_t val; 25 int i; 26 27 i = -1; 28 FOR_EACH_PTR(expr->args, arg) { 29 i++; 30 if (!get_implied_value(arg, &val)) 31 continue; 32 if (val.value == size) 33 return i; 34 } END_FOR_EACH_PTR(arg); 35 36 return -1; 37 } 38 39 static void match_call(struct expression *expr) 40 { 41 struct expression *arg; 42 struct symbol *type; 43 int size, bytes; 44 int i, nr; 45 char buf[16]; 46 47 48 i = -1; 49 FOR_EACH_PTR(expr->args, arg) { 50 i++; 51 type = get_type(arg); 52 if (!type || (type->type != SYM_PTR && type->type != SYM_ARRAY)) 53 continue; 54 size = get_array_size(arg); 55 if (size > 0) { 56 nr = find_param_eq(expr, size); 57 if (nr >= 0) { 58 snprintf(buf, sizeof(buf), "%d", nr); 59 sql_insert_caller_info(expr, ARRAYSIZE_ARG, i, buf, ""); 60 continue; 61 } 62 } 63 bytes = get_array_size_bytes(arg); 64 if (bytes > 0) { 65 nr = find_param_eq(expr, bytes); 66 if (nr >= 0) { 67 snprintf(buf, sizeof(buf), "%d", nr); 68 sql_insert_caller_info(expr, SIZEOF_ARG, i, buf, ""); 69 continue; 70 } 71 } 72 } END_FOR_EACH_PTR(arg); 73 } 74 75 void register_passes_array_size(int id) 76 { 77 add_hook(&match_call, FUNCTION_CALL_HOOK); 78 } 79 80