#include "smatch.h"
#include "smatch_extra.h"
static int find_param_eq(struct expression *expr, int size)
{
struct expression *arg;
sval_t val;
int i;
i = -1;
FOR_EACH_PTR(expr->args, arg) {
i++;
if (!get_implied_value(arg, &val))
continue;
if (val.value == size)
return i;
} END_FOR_EACH_PTR(arg);
return -1;
}
static void match_call(struct expression *expr)
{
struct expression *arg;
struct symbol *type, *arg_type;
int size, bytes;
int i, nr;
char buf[16];
char elem_count[8];
char byte_count[8];
snprintf(elem_count, sizeof(elem_count), "%d", ELEM_COUNT);
snprintf(byte_count, sizeof(byte_count), "%d", BYTE_COUNT);
i = -1;
FOR_EACH_PTR(expr->args, arg) {
i++;
type = get_type(arg);
if (!type || (type->type != SYM_PTR && type->type != SYM_ARRAY))
continue;
arg_type = get_arg_type(expr->fn, i);
if (arg_type != type)
continue;
size = get_array_size(arg);
if (size > 0) {
nr = find_param_eq(expr, size);
if (nr >= 0) {
snprintf(buf, sizeof(buf), "==$%d", nr);
sql_insert_caller_info(expr, ELEM_COUNT, i, buf, elem_count);
continue;
}
}
bytes = get_array_size_bytes(arg);
if (bytes > 0) {
nr = find_param_eq(expr, bytes);
if (nr >= 0) {
snprintf(buf, sizeof(buf), "==$%d", nr);
sql_insert_caller_info(expr, BYTE_COUNT, i, buf, byte_count);
continue;
}
}
} END_FOR_EACH_PTR(arg);
}
void register_passes_array_size(int id)
{
add_hook(&match_call, FUNCTION_CALL_HOOK);
}