2 * Copyright (C) 2011 Dan Carpenter.
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_slist.h"
23 static int right_side_changes(struct expression
*expr
)
27 if (get_value(expr
->right
, &dummy
))
32 static bool is_lt_ARRAY_SIZE(struct expression
*expr
)
37 * One cause of false positives is:
38 * for (i = 0; i < ARRAY_SIZE(); i++) {
39 * but the ARRAY_SIZE() is zero. Silence these false positives.
42 if (!expr
|| expr
->type
!= EXPR_COMPARE
)
44 if (expr
->op
!= '<' && expr
->op
!= SPECIAL_UNSIGNED_LT
)
46 if (!expr_is_zero(expr
->right
))
48 macro
= get_macro_name(expr
->right
->pos
);
49 if (!macro
|| strcmp(macro
, "ARRAY_SIZE") != 0)
55 static struct expression
*get_iterator_set(struct statement
*stmt
)
57 struct expression
*expr
;
61 if (stmt
->type
!= STMT_EXPRESSION
)
63 expr
= stmt
->expression
;
64 if (expr
->type
!= EXPR_ASSIGNMENT
)
68 if (right_side_changes(expr
))
73 static struct expression
*get_iterator_tested(struct expression
*expr
)
77 if (expr
->type
!= EXPR_COMPARE
)
82 static void match_loop(struct statement
*stmt
)
84 struct expression
*iterator
;
88 if (get_macro_name(stmt
->pos
))
91 iterator
= get_iterator_set(stmt
->iterator_pre_statement
);
92 iter_set
= expr_to_var(iterator
);
93 iterator
= get_iterator_tested(stmt
->iterator_pre_condition
);
94 iter_tested
= expr_to_var(iterator
);
95 if (!iter_set
|| !iter_tested
)
97 if (strcmp(iter_set
, iter_tested
))
100 /* smatch doesn't handle loops correctly so this silences some
103 if (right_side_changes(stmt
->iterator_pre_condition
))
106 if (is_lt_ARRAY_SIZE(stmt
->iterator_pre_condition
))
109 if (implied_condition_false(stmt
->iterator_pre_condition
))
110 sm_warning("we never enter this loop");
113 free_string(iter_set
);
114 free_string(iter_tested
);
117 void check_bogus_loop(int id
)
120 add_hook(&match_loop
, PRELOOP_HOOK
);