2 * sparse/smatch_extra.c
4 * Copyright (C) 2008 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
16 static struct smatch_state
*alloc_state(int val
)
18 struct smatch_state
*state
;
20 state
= malloc(sizeof(*state
));
21 state
->name
= "value";
22 state
->data
= malloc(sizeof(int));
23 *(int *)state
->data
= val
;
27 static struct smatch_state
*merge_func(const char *name
, struct symbol
*sym
,
28 struct smatch_state
*s1
,
29 struct smatch_state
*s2
)
34 static void match_function_call_after(struct expression
*expr
)
36 struct expression
*tmp
;
41 FOR_EACH_PTR(expr
->args
, tmp
) {
43 name
= get_variable_from_expr_simple(tmp
->unop
, &sym
);
45 name
= alloc_string(name
);
46 set_state(name
, my_id
, sym
, &undefined
);
50 } END_FOR_EACH_PTR(tmp
);
53 static void match_assign(struct expression
*expr
)
55 struct expression
*left
;
59 left
= strip_expr(expr
->left
);
60 name
= get_variable_from_expr_simple(left
, &sym
);
63 name
= alloc_string(name
);
64 set_state(name
, my_id
, sym
, alloc_state(get_value(expr
->right
)));
67 static void undef_expr(struct expression
*expr
)
72 name
= get_variable_from_expr_simple(expr
->unop
, &sym
);
75 if (!get_state(name
, my_id
, sym
))
77 name
= alloc_string(name
);
78 set_state(name
, my_id
, sym
, &undefined
);
81 static void match_declarations(struct symbol
*sym
)
86 name
= sym
->ident
->name
;
87 if (sym
->initializer
) {
88 set_state(name
, my_id
, sym
, alloc_state(get_value(sym
->initializer
)));
93 void register_smatch_extra(int id
)
96 add_merge_hook(my_id
, &merge_func
);
97 add_hook(&undef_expr
, OP_HOOK
);
98 add_hook(&match_function_call_after
, FUNCTION_CALL_AFTER_HOOK
);
99 add_hook(&match_assign
, ASSIGNMENT_AFTER_HOOK
);
100 add_hook(&match_declarations
, DECLARATION_HOOK
);
101 add_hook(&__implied_states_hook
, WHOLE_CONDITION_HOOK
);
104 static int expr_to_val(struct expression
*expr
)
106 struct smatch_state
*state
;
111 val
= get_value(expr
);
112 if (val
!= UNDEFINED
)
115 name
= get_variable_from_expr_simple(expr
, &sym
);
118 state
= get_state(name
, my_id
, sym
);
119 if (!state
|| !state
->data
)
121 return *(int *)state
->data
;
124 static int true_comparison(int left
, int comparison
, int right
)
128 case SPECIAL_UNSIGNED_LT
:
132 case SPECIAL_UNSIGNED_LTE
:
140 case SPECIAL_UNSIGNED_GTE
:
145 case SPECIAL_UNSIGNED_GT
:
149 case SPECIAL_NOTEQUAL
:
154 smatch_msg("unhandled comparison %d\n", comparison
);
159 int known_condition_true(struct expression
*expr
)
161 int left
, right
, ret
;
163 if (!expr
|| expr
->type
!= EXPR_COMPARE
)
166 if ((left
= expr_to_val(expr
->left
)) == UNDEFINED
)
169 if ((right
= expr_to_val(expr
->right
)) == UNDEFINED
)
172 ret
= true_comparison(left
, expr
->op
, right
);
174 SM_DEBUG("%d known condition: %d %s %d => true", get_lineno(),
175 left
, show_special(expr
->op
), right
);
177 smatch_msg("known condition: %d %s %d => false", left
,
178 show_special(expr
->op
), right
);