buf_size: record static variables in the database
[smatch.git] / check_kernel.c
blob8439e911cafae853140b346c0dd0ea3796f01c2b
1 /*
2 * sparse/check_kernel.c
4 * Copyright (C) 2010 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
11 * This is kernel specific stuff for smatch_extra.
14 #include "smatch.h"
15 #include "smatch_extra.h"
17 static void match_err_cast(const char *fn, struct expression *expr, void *unused)
19 struct expression *arg;
20 struct expression *right;
21 struct range_list *rl;
23 right = strip_expr(expr->right);
24 arg = get_argument_from_call_expr(right->args, 0);
26 if (get_implied_range_list(arg, &rl))
27 set_extra_expr_mod(expr->left, alloc_estate_range_list(rl));
28 else
29 set_extra_expr_mod(expr->left, alloc_estate_range(-4095, -1));
32 static void match_param_nonnull(const char *fn, struct expression *call_expr,
33 struct expression *assign_expr, void *_param)
35 int param = PTR_INT(_param);
36 struct expression *arg;
37 struct smatch_state *pre_state;
38 struct smatch_state *true_state;
40 arg = get_argument_from_call_expr(call_expr->args, param);
41 pre_state = get_state_expr(SMATCH_EXTRA, arg);
42 true_state = add_filter(pre_state, 0);
43 set_extra_expr_nomod(arg, true_state);
46 static void match_not_err(const char *fn, struct expression *call_expr,
47 struct expression *assign_expr, void *unused)
49 struct expression *arg;
50 struct smatch_state *pre_state;
51 struct smatch_state *new_state;
53 arg = get_argument_from_call_expr(call_expr->args, 0);
54 pre_state = get_state_expr(SMATCH_EXTRA, arg);
55 new_state = filter_range(pre_state, whole_range.min, -1);
56 set_extra_expr_nomod(arg, new_state);
59 static void match_err(const char *fn, struct expression *call_expr,
60 struct expression *assign_expr, void *unused)
62 struct expression *arg;
63 struct smatch_state *pre_state;
64 struct smatch_state *new_state;
66 arg = get_argument_from_call_expr(call_expr->args, 0);
67 pre_state = get_state_expr(SMATCH_EXTRA, arg);
68 new_state = filter_range(pre_state, whole_range.min, -4096);
69 new_state = filter_range(new_state, 0, whole_range.max);
70 set_extra_expr_nomod(arg, new_state);
73 static void match_container_of(const char *fn, struct expression *expr, void *unused)
75 set_extra_expr_mod(expr->left, alloc_estate_range(valid_ptr_min, valid_ptr_max));
78 void check_kernel(int id)
80 if (option_project != PROJ_KERNEL)
81 return;
83 add_function_assign_hook_extra("ERR_PTR", &match_err_cast, NULL);
84 add_function_assign_hook_extra("ERR_CAST", &match_err_cast, NULL);
85 add_function_assign_hook_extra("PTR_ERR", &match_err_cast, NULL);
86 return_implies_state("IS_ERR_OR_NULL", 0, 0, &match_param_nonnull, (void *)0);
87 return_implies_state("IS_ERR", 0, 0, &match_not_err, NULL);
88 return_implies_state("IS_ERR", 1, 1, &match_err, NULL);
89 return_implies_state("tomoyo_memory_ok", 1, 1, &match_param_nonnull, (void *)0);
90 add_macro_assign_hook_extra("container_of", &match_container_of, NULL);