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
19 #include "smatch_extra.h"
20 #include "smatch_slist.h"
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
);
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
);
51 rl
= estate_rl(pre_state
);
52 rl
= remove_range(rl
, ptr_xa_err_min
, ptr_xa_err_max
);
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
, ¶m_rl
))
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
);
77 void register_kernel_xa_err(int id
)
81 if (option_project
!= PROJ_KERNEL
)
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
);