2 * smatch/check_double_checking.c
4 * Copyright (C) 2014 Oracle.
6 * Licensed under the Open Software License version 1.1
11 #include "smatch_slist.h"
18 struct state_list
*to_check
;
20 static void set_modified(struct sm_state
*sm
, struct expression
*mod_expr
)
22 set_state(my_id
, sm
->name
, sm
->sym
, &modified
);
25 static void match_condition(struct expression
*expr
)
27 struct smatch_state
*state
;
32 if (get_value(expr
, &dummy
))
35 if (get_macro_name(expr
->pos
))
39 if (implied_condition_true(expr
))
41 else if (implied_condition_false(expr
))
46 state
= get_stored_condition(expr
);
47 if (!state
|| !state
->data
)
49 if (get_macro_name(((struct expression
*)state
->data
)->pos
))
53 * we allow double checking for NULL because people do this all the time
54 * and trying to stop them is a losers' battle.
56 if (is_pointer(expr
) && is_true
)
59 if (definitely_inside_loop()) {
65 name
= expr_to_var_sym(expr
, &sym
);
68 set_state_expr(my_id
, expr
, &checked
);
69 set_state_slist(&to_check
, my_id
, name
, sym
, &checked
);
74 name
= expr_to_str(expr
);
75 sm_msg("warn: we tested '%s' before and it was '%s'", name
, state
->name
);
79 int get_check_line(struct sm_state
*sm
)
83 FOR_EACH_PTR(sm
->possible
, tmp
) {
84 if (tmp
->state
== &checked
)
86 } END_FOR_EACH_PTR(tmp
);
91 static void after_loop(struct statement
*stmt
)
93 struct sm_state
*check
, *sm
;
95 if (!stmt
|| stmt
->type
!= STMT_ITERATOR
)
97 if (definitely_inside_loop())
102 FOR_EACH_PTR(to_check
, check
) {
104 sm
= get_sm_state(my_id
, check
->name
, check
->sym
);
108 if (slist_has_state(sm
->possible
, &modified
))
111 sm_printf("%s:%d %s() ", get_filename(), get_check_line(sm
), get_function());
112 sm_printf("warn: we tested '%s' already\n", check
->name
);
113 } END_FOR_EACH_PTR(check
);
115 free_slist(&to_check
);
118 static void match_func_end(struct symbol
*sym
)
123 sm_msg("debug: odd... found an function without an end.");
124 free_slist(&to_check
);
127 void check_double_checking(int id
)
134 add_hook(&match_condition
, CONDITION_HOOK
);
135 add_modification_hook(my_id
, &set_modified
);
136 add_hook(after_loop
, STMT_HOOK_AFTER
);
137 add_hook(&match_func_end
, END_FUNC_HOOK
);