2 * Copyright 2023 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"
23 static const char *kernel_macros
[] = {
24 "DP_FFE_PRESET_MAX_LEVEL",
29 "LOGICVC_DIMENSIONS_MAX",
34 "TSL2591_ALS_MAX_VALUE",
35 "UBIFS_COMPR_TYPES_CNT",
36 "XFS_MAX_CRC_AG_BLOCKS",
40 static const char **allowed_macros
;
42 static bool is_lt_zero(struct expression
*expr
)
44 if (expr
->type
!= EXPR_COMPARE
)
46 if (expr
->op
!= '<' && expr
->op
!= SPECIAL_UNSIGNED_LT
)
48 if (!expr_is_zero(expr
->right
))
53 static bool check_is_ulong_max_recursive(struct expression
*expr
)
57 expr
= strip_expr(expr
);
59 if (!get_value(expr
, &sval
))
62 if (expr
->type
== EXPR_BINOP
) {
63 if (check_is_ulong_max_recursive(expr
->left
))
68 if (sval_cmp(sval
, sval_type_max(&ulong_ctype
)) == 0)
73 static bool is_u64_vs_ulongmax(struct expression
*expr
)
75 struct symbol
*left
, *right
;
77 if (expr
->op
!= '>' && expr
->op
!= SPECIAL_UNSIGNED_GT
)
79 if (!check_is_ulong_max_recursive(expr
->right
))
82 left
= get_type(expr
->left
);
83 right
= get_type(expr
->right
);
87 if (type_positive_bits(left
) < type_positive_bits(right
))
90 if (type_bits(left
) != 64)
92 if (right
!= &ulong_ctype
&& right
!= &uint_ctype
)
98 static bool is_allowed_impossible_limit(struct expression
*expr
)
106 macro
= get_macro_name(expr
->pos
);
110 while (allowed_macros
[++i
]) {
111 if (strcmp(macro
, allowed_macros
[i
]) == 0)
117 static void match_condition(struct expression
*expr
)
122 struct range_list
*rl_left_orig
, *rl_right_orig
;
123 struct range_list
*rl_left
, *rl_right
;
126 if (expr
->type
!= EXPR_COMPARE
)
129 /* handled by check_unsigned_lt_zero.c */
130 if (is_lt_zero(expr
))
133 type
= get_type(expr
);
137 if (get_macro_name(expr
->pos
))
140 /* check that one and only one side is known */
141 if (get_value(expr
->left
, &known
)) {
142 if (get_value(expr
->right
, &known
))
144 rl_left_orig
= alloc_rl(known
, known
);
145 rl_left
= cast_rl(type
, rl_left_orig
);
147 min
= sval_type_min(get_type(expr
->right
));
148 max
= sval_type_max(get_type(expr
->right
));
149 rl_right_orig
= alloc_rl(min
, max
);
150 rl_right
= cast_rl(type
, rl_right_orig
);
151 } else if (get_value(expr
->right
, &known
)) {
152 rl_right_orig
= alloc_rl(known
, known
);
153 rl_right
= cast_rl(type
, rl_right_orig
);
155 min
= sval_type_min(get_type(expr
->left
));
156 max
= sval_type_max(get_type(expr
->left
));
157 rl_left_orig
= alloc_rl(min
, max
);
158 rl_left
= cast_rl(type
, rl_left_orig
);
163 if (possibly_true_rl(rl_left
, expr
->op
, rl_right
))
165 if (is_u64_vs_ulongmax(expr
))
167 if (is_allowed_impossible_limit(expr
->right
))
170 name
= expr_to_str(expr
);
171 sm_warning("impossible condition '(%s) => (%s %s %s)'", name
,
172 show_rl(rl_left
), show_special(expr
->op
), show_rl(rl_right
));
176 void check_impossible_compare(int id
)
180 if (option_project
== PROJ_KERNEL
)
181 allowed_macros
= kernel_macros
;
183 add_hook(&match_condition
, CONDITION_HOOK
);