Or vs and: warn about bitwise ANDs that always give zero
[smatch.git] / check_bogus_loop.c
blobe29e0dc1c6ad2a3269c5086e5c6c886bf50e1204
1 /*
2 * smatch/check_bogus_for_loop.c
4 * Copyright (C) 2011 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
11 #include "smatch_slist.h"
13 static int my_id;
15 static int right_side_changes(struct expression *expr)
17 long long dummy;
19 if (get_value(expr->right, &dummy))
20 return 0;
21 return 1;
24 static struct expression *get_iterator_set(struct statement *stmt)
26 struct expression *expr;
28 if (!stmt)
29 return NULL;
30 if (stmt->type != STMT_EXPRESSION)
31 return NULL;
32 expr = stmt->expression;
33 if (expr->type != EXPR_ASSIGNMENT)
34 return NULL;
35 if (expr->op != '=')
36 return NULL;
37 if (right_side_changes(expr))
38 return NULL;
39 return expr->left;
42 static struct expression *get_iterator_tested(struct expression *expr)
44 if (!expr)
45 return NULL;
46 if (expr->type != EXPR_COMPARE)
47 return NULL;
48 return expr->left;
51 static void match_loop(struct statement *stmt)
53 struct expression *iterator;
54 char *iter_set;
55 char *iter_tested;
57 if (get_macro_name(stmt->pos))
58 return;
60 iterator = get_iterator_set(stmt->iterator_pre_statement);
61 iter_set = get_variable_from_expr(iterator, NULL);
62 iterator = get_iterator_tested(stmt->iterator_pre_condition);
63 iter_tested = get_variable_from_expr(iterator, NULL);
64 if (!iter_set || !iter_tested)
65 goto free;
66 if (strcmp(iter_set, iter_tested))
67 goto free;
69 /* smatch doesn't handle loops correctly so this silences some
70 * false positives.
72 if (right_side_changes(stmt->iterator_pre_condition))
73 goto free;
75 if (implied_condition_false(stmt->iterator_pre_condition))
76 sm_msg("warn: we never enter this loop");
78 free:
79 free_string(iter_set);
80 free_string(iter_tested);
83 void check_bogus_loop(int id)
85 my_id = id;
86 add_hook(&match_loop, PRELOOP_HOOK);