This is the start of the smatch_extra stuff.
[smatch.git] / smatch_extra.c
blob4def79726c74c429624859e097331f2b9d197e96
1 /*
2 * sparse/smatch_extra.c
4 * Copyright (C) 2008 Dan Carpenter.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include <stdlib.h>
11 #include "parse.h"
12 #include "smatch.h"
14 static int my_id;
16 static int merge_func(const char *name, struct symbol *sym, int s1, int s2)
18 return UNDEFINED;
21 static void match_function_call_after(struct expression *expr)
23 struct expression *tmp;
24 struct symbol *sym;
25 char *name;
26 int i = 0;
28 FOR_EACH_PTR(expr->args, tmp) {
29 if (tmp->op == '&') {
30 name = get_variable_from_expr_simple(tmp->unop, &sym);
31 if (name) {
32 name = alloc_string(name);
33 set_state(name, my_id, sym, UNDEFINED);
36 i++;
37 } END_FOR_EACH_PTR(tmp);
40 static void match_assign(struct expression *expr)
42 struct symbol *sym;
43 char *name;
45 name = get_variable_from_expr_simple(expr->left, &sym);
46 if (!name)
47 return;
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)
54 struct symbol *sym;
55 char *name;
57 name = get_variable_from_expr_simple(expr->unop, &sym);
58 if (!name)
59 return;
60 if (get_state(name, my_id, sym) == NOTFOUND)
61 return;
62 name = alloc_string(name);
63 set_state(name, my_id, sym, UNDEFINED);
66 static void match_declarations(struct symbol *sym)
68 const char *name;
70 if (sym->ident) {
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)
80 my_id = 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)
90 int val;
91 struct symbol *sym;
92 char *name;
94 val = get_value(expr, NULL);
95 if (val != UNDEFINED)
96 return val;
98 name = get_variable_from_expr_simple(expr, &sym);
99 if (!name)
100 return UNDEFINED;
101 val = get_state(name, my_id, sym);
102 if (val == NOTFOUND)
103 val = UNDEFINED;
104 return val;
107 static int true_comparison(int left, int comparison, int right)
109 switch(comparison){
110 case '<':
111 case SPECIAL_UNSIGNED_LT:
112 if (left < right)
113 return 1;
114 return 0;
115 case SPECIAL_UNSIGNED_LTE:
116 case SPECIAL_LTE:
117 if (left < right)
118 return 1;
119 case SPECIAL_EQUAL:
120 if (left == right)
121 return 1;
122 return 0;
123 case SPECIAL_UNSIGNED_GTE:
124 case SPECIAL_GTE:
125 if (left == right)
126 return 1;
127 case '>':
128 case SPECIAL_UNSIGNED_GT:
129 if (left > right)
130 return 1;
131 return 0;
132 case SPECIAL_NOTEQUAL:
133 if (left != right)
134 return 1;
135 return 0;
136 default:
137 smatch_msg("unhandled comparison %d\n", comparison);
139 return 0;
142 int known_condition_true(struct expression *expr)
144 int left, right, ret;
146 if (!expr || expr->type != EXPR_COMPARE)
147 return 0;
149 if ((left = expr_to_val(expr->left)) == UNDEFINED)
150 return 0;
152 if ((right = expr_to_val(expr->right)) == UNDEFINED)
153 return 0;
155 ret = true_comparison(left, expr->op, right);
156 smatch_msg("known condition: %d & %d => %s", left, right, (ret?"true":"false"));
158 return ret;