db/fixup_kernel.sh: fix clear_user() handling
[smatch.git] / smatch_kernel_xa_err.c
blobf3492a4504b42b809328511b9d08dbfb91e5b02a
1 /*
2 * Copyright 2024 Linaro Ltd.
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.
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.
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
18 #include "smatch.h"
19 #include "smatch_extra.h"
20 #include "smatch_slist.h"
22 static int my_id;
24 static void match_xa_is_err_true(const char *fn, struct expression *call_expr,
25 struct expression *assign_expr, void *unused)
27 struct expression *arg;
28 struct smatch_state *pre_state;
29 struct range_list *rl;
31 arg = get_argument_from_call_expr(call_expr->args, 0);
32 pre_state = get_state_expr(SMATCH_EXTRA, arg);
33 rl = estate_rl(pre_state);
34 if (!rl)
35 rl = alloc_rl(ptr_xa_err_min, ptr_xa_err_max);
36 rl = rl_intersection(rl, alloc_rl(ptr_xa_err_min, ptr_xa_err_max));
37 rl = cast_rl(get_type(arg), rl);
38 set_extra_expr_nomod(arg, alloc_estate_rl(rl));
41 static void match_xa_is_err_false(const char *fn, struct expression *call_expr,
42 struct expression *assign_expr, void *unused)
44 struct expression *arg;
45 struct smatch_state *pre_state;
46 struct range_list *rl;
48 arg = get_argument_from_call_expr(call_expr->args, 0);
49 pre_state = get_state_expr(SMATCH_EXTRA, arg);
50 if (pre_state) {
51 rl = estate_rl(pre_state);
52 rl = remove_range(rl, ptr_xa_err_min, ptr_xa_err_max);
53 } else {
54 rl = alloc_rl(valid_ptr_min_sval, valid_ptr_max_sval);
56 rl = cast_rl(get_type(arg), rl);
57 set_extra_expr_nomod(arg, alloc_estate_rl(rl));
60 static int implied_xa_err_return(struct expression *call, void *unused, struct range_list **rl)
62 struct expression *arg;
63 struct range_list *param_rl;
65 arg = get_argument_from_call_expr(call->args, 0);
66 if (!get_implied_rl(arg, &param_rl))
67 return false;
68 if (sval_cmp(rl_min(param_rl), ptr_xa_err_min) >= 0 &&
69 sval_cmp(rl_max(param_rl), ptr_xa_err_max) <= 0) {
70 *rl = alloc_rl(err_min, err_max);
71 return true;
74 return false;
77 void register_kernel_xa_err(int id)
79 my_id = id;
81 if (option_project != PROJ_KERNEL)
82 return;
84 return_implies_state("xa_is_err", 1, 1, &match_xa_is_err_true, NULL);
85 return_implies_state("xa_is_err", 0, 0, &match_xa_is_err_false, NULL);
87 add_implied_return_hook("xa_err", &implied_xa_err_return, NULL);