Make cur_slist static. It's only used in smatch_states.c.
[smatch.git] / smatch_extra.c
blob76c7eab4db83f63d271ed93d0b63ad8d85f0984e
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 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;
24 return state;
27 static struct smatch_state *merge_func(const char *name, struct symbol *sym,
28 struct smatch_state *s1,
29 struct smatch_state *s2)
31 return &undefined;
34 static void match_function_call_after(struct expression *expr)
36 struct expression *tmp;
37 struct symbol *sym;
38 char *name;
39 int i = 0;
41 FOR_EACH_PTR(expr->args, tmp) {
42 if (tmp->op == '&') {
43 name = get_variable_from_expr_simple(tmp->unop, &sym);
44 if (name) {
45 name = alloc_string(name);
46 set_state(name, my_id, sym, &undefined);
49 i++;
50 } END_FOR_EACH_PTR(tmp);
53 static void match_assign(struct expression *expr)
55 struct expression *left;
56 struct symbol *sym;
57 char *name;
59 left = strip_expr(expr->left);
60 name = get_variable_from_expr_simple(left, &sym);
61 if (!name)
62 return;
63 name = alloc_string(name);
64 set_state(name, my_id, sym, alloc_state(get_value(expr->right, NULL)));
67 static void undef_expr(struct expression *expr)
69 struct symbol *sym;
70 char *name;
72 name = get_variable_from_expr_simple(expr->unop, &sym);
73 if (!name)
74 return;
75 if (!get_state(name, my_id, sym))
76 return;
77 name = alloc_string(name);
78 set_state(name, my_id, sym, &undefined);
81 static void match_declarations(struct symbol *sym)
83 const char *name;
85 if (sym->ident) {
86 name = sym->ident->name;
87 if (sym->initializer) {
88 set_state(name, my_id, sym, alloc_state(get_value(sym->initializer, NULL)));
93 void register_smatch_extra(int id)
95 my_id = 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);
103 static int expr_to_val(struct expression *expr)
105 struct smatch_state *state;
106 int val;
107 struct symbol *sym;
108 char *name;
110 val = get_value(expr, NULL);
111 if (val != UNDEFINED)
112 return val;
114 name = get_variable_from_expr_simple(expr, &sym);
115 if (!name)
116 return UNDEFINED;
117 state = get_state(name, my_id, sym);
118 if (!state || !state->data)
119 return UNDEFINED;
120 return *(int *)state->data;
123 static int true_comparison(int left, int comparison, int right)
125 switch(comparison){
126 case '<':
127 case SPECIAL_UNSIGNED_LT:
128 if (left < right)
129 return 1;
130 return 0;
131 case SPECIAL_UNSIGNED_LTE:
132 case SPECIAL_LTE:
133 if (left < right)
134 return 1;
135 case SPECIAL_EQUAL:
136 if (left == right)
137 return 1;
138 return 0;
139 case SPECIAL_UNSIGNED_GTE:
140 case SPECIAL_GTE:
141 if (left == right)
142 return 1;
143 case '>':
144 case SPECIAL_UNSIGNED_GT:
145 if (left > right)
146 return 1;
147 return 0;
148 case SPECIAL_NOTEQUAL:
149 if (left != right)
150 return 1;
151 return 0;
152 default:
153 smatch_msg("unhandled comparison %d\n", comparison);
155 return 0;
158 int known_condition_true(struct expression *expr)
160 int left, right, ret;
162 if (!expr || expr->type != EXPR_COMPARE)
163 return 0;
165 if ((left = expr_to_val(expr->left)) == UNDEFINED)
166 return 0;
168 if ((right = expr_to_val(expr->right)) == UNDEFINED)
169 return 0;
171 ret = true_comparison(left, expr->op, right);
172 smatch_msg("known condition: %d & %d => %s", left, right, (ret?"true":"false"));
174 return ret;