param_cleared: handle direct assignments
[smatch.git] / smatch_var_sym.c
blobbce7169b0777f49bf359208996e570c5a452a23e
1 /*
2 * Copyright (C) 2013 Oracle.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
18 #include "smatch.h"
20 ALLOCATOR(var_sym, "var_sym structs");
22 struct var_sym *alloc_var_sym(const char *var, struct symbol *sym)
24 struct var_sym *tmp;
26 tmp = __alloc_var_sym(0);
27 tmp->var = alloc_string(var);
28 tmp->sym = sym;
29 return tmp;
32 struct var_sym_list *expr_to_vsl(struct expression *expr)
34 struct var_sym_list *ret = NULL;
35 char *var;
36 struct symbol *sym;
38 expr = strip_expr(expr);
39 if (!expr)
40 return NULL;
42 if (expr->type == EXPR_BINOP ||
43 expr->type == EXPR_LOGICAL ||
44 expr->type == EXPR_COMPARE) {
45 struct var_sym_list *left, *right;
47 left = expr_to_vsl(expr->left);
48 right = expr_to_vsl(expr->right);
49 ret = combine_var_sym_lists(left, right);
50 free_var_syms_and_list(&left);
51 free_var_syms_and_list(&right);
52 return ret;
54 var = expr_to_var_sym(expr, &sym);
55 if (!var || !sym) {
56 free_string(var);
57 return NULL;
59 add_var_sym(&ret, var, sym);
60 return ret;
63 void add_var_sym(struct var_sym_list **list, const char *var, struct symbol *sym)
65 struct var_sym *tmp;
67 if (in_var_sym_list(*list, var, sym))
68 return;
69 tmp = alloc_var_sym(var, sym);
70 add_ptr_list(list, tmp);
73 void add_var_sym_expr(struct var_sym_list **list, struct expression *expr)
75 char *var;
76 struct symbol *sym;
78 var = expr_to_var_sym(expr, &sym);
79 if (!var || !sym)
80 goto free;
81 add_var_sym(list, var, sym);
82 free:
83 free_string(var);
86 static void free_var_sym(struct var_sym *vs)
88 free_string(vs->var);
89 __free_var_sym(vs);
92 void del_var_sym(struct var_sym_list **list, const char *var, struct symbol *sym)
94 struct var_sym *tmp;
96 FOR_EACH_PTR(*list, tmp) {
97 if (tmp->sym == sym && strcmp(tmp->var, var) == 0) {
98 DELETE_CURRENT_PTR(tmp);
99 free_var_sym(tmp);
100 return;
102 } END_FOR_EACH_PTR(tmp);
105 int in_var_sym_list(struct var_sym_list *list, const char *var, struct symbol *sym)
107 struct var_sym *tmp;
109 FOR_EACH_PTR(list, tmp) {
110 if (tmp->sym == sym && strcmp(tmp->var, var) == 0)
111 return 1;
112 } END_FOR_EACH_PTR(tmp);
113 return 0;
116 struct var_sym_list *clone_var_sym_list(struct var_sym_list *from_vsl)
118 struct var_sym *tmp, *clone_vs;
119 struct var_sym_list *to_vsl = NULL;
121 FOR_EACH_PTR(from_vsl, tmp) {
122 clone_vs = alloc_var_sym(tmp->var, tmp->sym);
123 add_ptr_list(&to_vsl, clone_vs);
124 } END_FOR_EACH_PTR(tmp);
125 return to_vsl;
128 void merge_var_sym_list(struct var_sym_list **dest, struct var_sym_list *src)
130 struct var_sym *tmp;
132 FOR_EACH_PTR(src, tmp) {
133 add_var_sym(dest, tmp->var, tmp->sym);
134 } END_FOR_EACH_PTR(tmp);
137 struct var_sym_list *combine_var_sym_lists(struct var_sym_list *one, struct var_sym_list *two)
139 struct var_sym_list *to_vsl;
141 to_vsl = clone_var_sym_list(one);
142 merge_var_sym_list(&to_vsl, two);
143 return to_vsl;
146 void free_var_sym_list(struct var_sym_list **list)
148 __free_ptr_list((struct ptr_list **)list);
151 void free_var_syms_and_list(struct var_sym_list **list)
153 struct var_sym *tmp;
155 FOR_EACH_PTR(*list, tmp) {
156 free_var_sym(tmp);
157 } END_FOR_EACH_PTR(tmp);
158 free_var_sym_list(list);