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 (__in_pre_post_condition
)
35 if (get_value(expr
, &dummy
))
38 if (get_macro_name(expr
->pos
))
42 if (implied_condition_true(expr
))
44 else if (implied_condition_false(expr
))
49 state
= get_stored_condition(expr
);
50 if (!state
|| !state
->data
)
52 if (get_macro_name(((struct expression
*)state
->data
)->pos
))
56 * we allow double checking for NULL because people do this all the time
57 * and trying to stop them is a losers' battle.
59 if (is_pointer(expr
) && is_true
)
62 if (definitely_inside_loop()) {
68 name
= expr_to_var_sym(expr
, &sym
);
71 set_state_expr(my_id
, expr
, &checked
);
72 set_state_slist(&to_check
, my_id
, name
, sym
, &checked
);
77 name
= expr_to_str(expr
);
78 sm_msg("warn: we tested '%s' before and it was '%s'", name
, state
->name
);
82 int get_check_line(struct sm_state
*sm
)
86 FOR_EACH_PTR(sm
->possible
, tmp
) {
87 if (tmp
->state
== &checked
)
89 } END_FOR_EACH_PTR(tmp
);
94 static void after_loop(struct statement
*stmt
)
96 struct sm_state
*check
, *sm
;
98 if (!stmt
|| stmt
->type
!= STMT_ITERATOR
)
100 if (definitely_inside_loop())
105 FOR_EACH_PTR(to_check
, check
) {
107 sm
= get_sm_state(my_id
, check
->name
, check
->sym
);
111 if (slist_has_state(sm
->possible
, &modified
))
114 sm_printf("%s:%d %s() ", get_filename(), get_check_line(sm
), get_function());
115 sm_printf("warn: we tested '%s' already\n", check
->name
);
116 } END_FOR_EACH_PTR(check
);
118 free_slist(&to_check
);
121 static void match_func_end(struct symbol
*sym
)
126 sm_msg("debug: odd... found an function without an end.");
127 free_slist(&to_check
);
130 void check_double_checking(int id
)
137 add_hook(&match_condition
, CONDITION_HOOK
);
138 add_modification_hook(my_id
, &set_modified
);
139 add_hook(after_loop
, STMT_HOOK_AFTER
);
140 add_hook(&match_func_end
, END_FUNC_HOOK
);