57 static int read_only;
58
59 static struct stree_stack *break_stack;
60 static struct stree_stack *fake_break_stack;
61 static struct stree_stack *switch_stack;
62 static struct range_list_stack *remaining_cases;
63 static struct stree_stack *default_stack;
64 static struct stree_stack *continue_stack;
65
66 static struct named_stree_stack *goto_stack;
67
68 static struct ptr_list *backup;
69
70 int option_debug;
71
72 void __print_cur_stree(void)
73 {
74 __print_stree(cur_stree);
75 }
76
77 int unreachable(void)
78 {
79 if (!cur_stree)
80 return 1;
81 return 0;
82 }
83
84 void __set_cur_stree_readonly(void)
85 {
86 read_only++;
87 }
88
89 void __set_cur_stree_writable(void)
90 {
91 read_only--;
92 }
93
94 struct sm_state *set_state(int owner, const char *name, struct symbol *sym, struct smatch_state *state)
95 {
96 struct sm_state *ret;
97
98 if (!name || !state)
99 return NULL;
100
101 if (read_only)
102 sm_perror("cur_stree is read only.");
103
104 if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
105 struct smatch_state *s;
106
107 s = __get_state(owner, name, sym);
108 if (!s)
109 sm_msg("%s new [%s] '%s' %s", __func__,
110 check_name(owner), name, show_state(state));
111 else
112 sm_msg("%s change [%s] '%s' %s => %s",
113 __func__, check_name(owner), name, show_state(s),
114 show_state(state));
115 }
116
117 if (owner != -1 && unreachable())
118 return NULL;
119
120 if (fake_cur_stree_stack)
121 set_state_stree_stack(&fake_cur_stree_stack, owner, name, sym, state);
122
123 ret = set_state_stree(&cur_stree, owner, name, sym, state);
124
125 return ret;
126 }
127
128 struct sm_state *set_state_expr(int owner, struct expression *expr, struct smatch_state *state)
129 {
130 char *name;
131 struct symbol *sym;
132 struct sm_state *ret = NULL;
133
134 expr = strip_expr(expr);
135 name = expr_to_var_sym(expr, &sym);
136 if (!name || !sym)
|
57 static int read_only;
58
59 static struct stree_stack *break_stack;
60 static struct stree_stack *fake_break_stack;
61 static struct stree_stack *switch_stack;
62 static struct range_list_stack *remaining_cases;
63 static struct stree_stack *default_stack;
64 static struct stree_stack *continue_stack;
65
66 static struct named_stree_stack *goto_stack;
67
68 static struct ptr_list *backup;
69
70 int option_debug;
71
72 void __print_cur_stree(void)
73 {
74 __print_stree(cur_stree);
75 }
76
77 bool __print_states(const char *owner)
78 {
79 struct sm_state *sm;
80 bool found = false;
81
82 if (!owner)
83 return false;
84
85 FOR_EACH_SM(__get_cur_stree(), sm) {
86 if (!strstr(check_name(sm->owner), owner))
87 continue;
88 sm_msg("%s", show_sm(sm));
89 found = true;
90 } END_FOR_EACH_SM(sm);
91
92 return found;
93 }
94
95 int unreachable(void)
96 {
97 if (!cur_stree)
98 return 1;
99 return 0;
100 }
101
102 void __set_cur_stree_readonly(void)
103 {
104 read_only++;
105 }
106
107 void __set_cur_stree_writable(void)
108 {
109 read_only--;
110 }
111
112 DECLARE_PTR_LIST(check_tracker_list, check_tracker_hook *);
113 static struct check_tracker_list **tracker_hooks;
114
115 void add_check_tracker(const char *check_name, check_tracker_hook *fn)
116 {
117 check_tracker_hook **p;
118 int owner;
119
120 owner = id_from_name(check_name);
121 if (!owner) {
122 printf("check not found. '%s'\n", check_name);
123 return;
124 }
125
126 p = malloc(sizeof(check_tracker_hook *));
127 *p = fn;
128 add_ptr_list(&tracker_hooks[owner], p);
129 }
130
131 static void call_tracker_hooks(int owner, const char *name, struct symbol *sym, struct smatch_state *state)
132 {
133 struct check_tracker_list *hooks;
134 check_tracker_hook **fn;
135
136 if ((unsigned short)owner == USHRT_MAX)
137 return;
138
139 hooks = tracker_hooks[owner];
140 FOR_EACH_PTR(hooks, fn) {
141 (*fn)(owner, name, sym, state);
142 } END_FOR_EACH_PTR(fn);
143 }
144
145 void allocate_tracker_array(int num_checks)
146 {
147 tracker_hooks = malloc(num_checks * sizeof(void *));
148 memset(tracker_hooks, 0, num_checks * sizeof(void *));
149 }
150
151 struct sm_state *set_state(int owner, const char *name, struct symbol *sym, struct smatch_state *state)
152 {
153 struct sm_state *ret;
154
155 if (!name || !state)
156 return NULL;
157
158 if (read_only)
159 sm_perror("cur_stree is read only.");
160
161 if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
162 struct smatch_state *s;
163
164 s = __get_state(owner, name, sym);
165 if (!s)
166 sm_msg("%s new [%s] '%s' %s", __func__,
167 check_name(owner), name, show_state(state));
168 else
169 sm_msg("%s change [%s] '%s' %s => %s",
170 __func__, check_name(owner), name, show_state(s),
171 show_state(state));
172 }
173
174 call_tracker_hooks(owner, name, sym, state);
175
176 if (owner != -1 && unreachable())
177 return NULL;
178
179 if (fake_cur_stree_stack)
180 set_state_stree_stack(&fake_cur_stree_stack, owner, name, sym, state);
181
182 ret = set_state_stree(&cur_stree, owner, name, sym, state);
183
184 return ret;
185 }
186
187 struct sm_state *set_state_expr(int owner, struct expression *expr, struct smatch_state *state)
188 {
189 char *name;
190 struct symbol *sym;
191 struct sm_state *ret = NULL;
192
193 expr = strip_expr(expr);
194 name = expr_to_var_sym(expr, &sym);
195 if (!name || !sym)
|