Avoid triggering a division by zero in the overflow check
[smatch.git] / check_expects_err_ptr.c
blob854f658955dd6ac21949f69724d8f7b2d258d748
1 /*
2 * smatch/check_expects_err_ptr.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
12 static int my_id;
13 static struct symbol *func_sym;
15 STATE(argument);
16 STATE(ok);
18 static void set_ok(struct sm_state *sm)
20 if (sm->state != &ok)
21 set_state(my_id, sm->name, sm->sym, &ok);
24 static void match_function_def(struct symbol *sym)
26 struct symbol *arg;
28 func_sym = sym;
29 FOR_EACH_PTR(func_sym->ctype.base_type->arguments, arg) {
30 if (!arg->ident) {
31 continue;
33 set_state(my_id, arg->ident->name, arg, &argument);
34 } END_FOR_EACH_PTR(arg);
37 static int get_arg_num(struct expression *expr)
39 struct smatch_state *state;
40 struct symbol *arg;
41 struct symbol *this_arg;
42 int i;
44 expr = strip_expr(expr);
45 if (expr->type != EXPR_SYMBOL)
46 return -1;
47 this_arg = expr->symbol;
49 state = get_state_expr(my_id, expr);
50 if (!state || state != &argument)
51 return -1;
53 i = 0;
54 FOR_EACH_PTR(func_sym->ctype.base_type->arguments, arg) {
55 if (arg == this_arg)
56 return i;
57 i++;
58 } END_FOR_EACH_PTR(arg);
60 return -1;
63 static void match_is_err(const char *fn, struct expression *expr, void *unused)
65 struct expression *arg;
66 int arg_num;
68 arg = get_argument_from_call_expr(expr->args, 0);
69 arg_num = get_arg_num(arg);
70 if (arg_num < 0)
71 return;
72 sm_msg("info: expects ERR_PTR %d", arg_num);
75 void check_expects_err_ptr(int id)
77 if (option_project != PROJ_KERNEL)
78 return;
79 if (!option_info)
80 return;
82 my_id = id;
83 add_hook(&match_function_def, FUNC_DEF_HOOK);
84 add_modification_hook(my_id, &set_ok);
85 add_function_hook("IS_ERR", &match_is_err, NULL);