2 * sparse/smatch_extra.c
4 * Copyright (C) 2008 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
16 static int merge_func(const char *name
, struct symbol
*sym
, int s1
, int s2
)
21 static void match_function_call_after(struct expression
*expr
)
23 struct expression
*tmp
;
28 FOR_EACH_PTR(expr
->args
, tmp
) {
30 name
= get_variable_from_expr_simple(tmp
->unop
, &sym
);
32 name
= alloc_string(name
);
33 set_state(name
, my_id
, sym
, UNDEFINED
);
37 } END_FOR_EACH_PTR(tmp
);
40 static void match_assign(struct expression
*expr
)
45 name
= get_variable_from_expr_simple(expr
->left
, &sym
);
48 name
= alloc_string(name
);
49 set_state(name
, my_id
, sym
, get_value(expr
->right
, NULL
));
52 static void undef_expr(struct expression
*expr
)
57 name
= get_variable_from_expr_simple(expr
->unop
, &sym
);
60 if (get_state(name
, my_id
, sym
) == NOTFOUND
)
62 name
= alloc_string(name
);
63 set_state(name
, my_id
, sym
, UNDEFINED
);
66 static void match_declarations(struct symbol
*sym
)
71 name
= sym
->ident
->name
;
72 if (sym
->initializer
) {
73 set_state(name
, my_id
, sym
, get_value(sym
->initializer
, NULL
));
78 void register_smatch_extra(int id
)
81 add_merge_hook(my_id
, &merge_func
);
82 add_hook(&undef_expr
, OP_HOOK
);
83 add_hook(&match_function_call_after
, FUNCTION_CALL_AFTER_HOOK
);
84 add_hook(&match_assign
, ASSIGNMENT_AFTER_HOOK
);
85 add_hook(&match_declarations
, DECLARATION_HOOK
);
88 static int expr_to_val(struct expression
*expr
)
94 val
= get_value(expr
, NULL
);
98 name
= get_variable_from_expr_simple(expr
, &sym
);
101 val
= get_state(name
, my_id
, sym
);
107 static int true_comparison(int left
, int comparison
, int right
)
111 case SPECIAL_UNSIGNED_LT
:
115 case SPECIAL_UNSIGNED_LTE
:
123 case SPECIAL_UNSIGNED_GTE
:
128 case SPECIAL_UNSIGNED_GT
:
132 case SPECIAL_NOTEQUAL
:
137 smatch_msg("unhandled comparison %d\n", comparison
);
142 int known_condition_true(struct expression
*expr
)
144 int left
, right
, ret
;
146 if (!expr
|| expr
->type
!= EXPR_COMPARE
)
149 if ((left
= expr_to_val(expr
->left
)) == UNDEFINED
)
152 if ((right
= expr_to_val(expr
->right
)) == UNDEFINED
)
155 ret
= true_comparison(left
, expr
->op
, right
);
156 smatch_msg("known condition: %d & %d => %s", left
, right
, (ret
?"true":"false"));