bit_shift: add a comment explaining what the check does
[smatch.git] / check_return_enomem.c
blob0ac3ba547dffec95317cde1053d8a6b59140024d
1 /*
2 * smatch/check_return_enomem.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * Complains about places that return -1 instead of -ENOMEM
14 #include "smatch.h"
15 #include "smatch_slist.h"
16 #include "smatch_extra.h"
18 #define ENOMEM 12
20 static int my_id;
22 STATE(enomem);
23 STATE(ok);
25 static void ok_to_use(struct sm_state *sm, struct expression *mod_expr)
27 if (sm->state != &ok)
28 set_state(my_id, sm->name, sm->sym, &ok);
31 static void allocation_succeeded(const char *fn, struct expression *call_expr,
32 struct expression *assign_expr, void *unused)
34 set_state_expr(my_id, assign_expr->left, &ok);
37 static void allocation_failed(const char *fn, struct expression *call_expr,
38 struct expression *assign_expr, void *_arg_no)
40 set_state_expr(my_id, assign_expr->left, &enomem);
43 static void match_return(struct expression *ret_value)
45 struct sm_state *sm;
46 struct state_list *slist;
47 sval_t sval;
49 if (!ret_value)
50 return;
51 if (returns_unsigned(cur_func_sym))
52 return;
53 if (returns_pointer(cur_func_sym))
54 return;
55 if (!get_value(ret_value, &sval) || sval.value != -1)
56 return;
57 if (get_macro_name(ret_value->pos))
58 return;
60 slist = get_all_states(my_id);
62 FOR_EACH_PTR(slist, sm) {
63 if (sm->state == &enomem) {
64 sm_msg("warn: returning -1 instead of -ENOMEM is sloppy");
65 goto out;
67 } END_FOR_EACH_PTR(sm);
69 out:
70 free_slist(&slist);
73 void check_return_enomem(int id)
75 if (option_project != PROJ_KERNEL)
76 return;
78 my_id = id;
79 return_implies_state("kmalloc", valid_ptr_min, valid_ptr_max, &allocation_succeeded, INT_PTR(0));
80 return_implies_state("kmalloc", 0, 0, &allocation_failed, INT_PTR(0));
81 return_implies_state("kzalloc", valid_ptr_min, valid_ptr_max, &allocation_succeeded, INT_PTR(0));
82 return_implies_state("kzalloc", 0, 0, &allocation_failed, INT_PTR(0));
83 return_implies_state("kcalloc", valid_ptr_min, valid_ptr_max, &allocation_succeeded, INT_PTR(0));
84 return_implies_state("kcalloc", 0, 0, &allocation_failed, INT_PTR(0));
85 add_hook(&match_return, RETURN_HOOK);
86 add_modification_hook(my_id, &ok_to_use);