67 static struct ptr_list *backup;
68
69 int option_debug;
70
71 void __print_cur_stree(void)
72 {
73 __print_stree(cur_stree);
74 }
75
76 int unreachable(void)
77 {
78 if (!cur_stree)
79 return 1;
80 return 0;
81 }
82
83 struct sm_state *set_state(int owner, const char *name, struct symbol *sym, struct smatch_state *state)
84 {
85 struct sm_state *ret;
86
87 if (!name)
88 return NULL;
89
90 if (read_only)
91 sm_perror("cur_stree is read only.");
92
93 if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
94 struct smatch_state *s;
95
96 s = get_state(owner, name, sym);
97 if (!s)
98 sm_msg("%s new [%s] '%s' %s", __func__,
99 check_name(owner), name, show_state(state));
100 else
101 sm_msg("%s change [%s] '%s' %s => %s",
102 __func__, check_name(owner), name, show_state(s),
103 show_state(state));
104 }
105
106 if (owner != -1 && unreachable())
107 return NULL;
108
109 if (fake_cur_stree_stack)
110 set_state_stree_stack(&fake_cur_stree_stack, owner, name, sym, state);
111
112 ret = set_state_stree(&cur_stree, owner, name, sym, state);
113
114 return ret;
115 }
116
179
180 FOR_EACH_SM(stree, sm) {
181 orig = get_sm_state(sm->owner, sm->name, sm->sym);
182 if (orig)
183 merged = merge_sm_states(orig, sm);
184 else
185 merged = sm;
186 __set_sm(merged);
187 } END_FOR_EACH_SM(sm);
188 }
189
190 void __set_sm(struct sm_state *sm)
191 {
192 if (read_only)
193 sm_perror("cur_stree is read only.");
194
195 if (option_debug ||
196 strcmp(check_name(sm->owner), option_debug_check) == 0) {
197 struct smatch_state *s;
198
199 s = get_state(sm->owner, sm->name, sm->sym);
200 if (!s)
201 sm_msg("%s new %s", __func__, show_sm(sm));
202 else
203 sm_msg("%s change %s (was %s)", __func__, show_sm(sm),
204 show_state(s));
205 }
206
207 if (unreachable())
208 return;
209
210 if (fake_cur_stree_stack)
211 overwrite_sm_state_stree_stack(&fake_cur_stree_stack, sm);
212
213 overwrite_sm_state_stree(&cur_stree, sm);
214 }
215
216 void __set_sm_cur_stree(struct sm_state *sm)
217 {
218 if (read_only)
219 sm_perror("cur_stree is read only.");
220
221 if (option_debug ||
222 strcmp(check_name(sm->owner), option_debug_check) == 0) {
223 struct smatch_state *s;
224
225 s = get_state(sm->owner, sm->name, sm->sym);
226 if (!s)
227 sm_msg("%s new %s", __func__, show_sm(sm));
228 else
229 sm_msg("%s change %s (was %s)",
230 __func__, show_sm(sm), show_state(s));
231 }
232
233 if (unreachable())
234 return;
235
236 overwrite_sm_state_stree(&cur_stree, sm);
237 }
238
239 void __set_sm_fake_stree(struct sm_state *sm)
240 {
241 if (read_only)
242 sm_perror("cur_stree is read only.");
243
244 if (option_debug ||
245 strcmp(check_name(sm->owner), option_debug_check) == 0) {
246 struct smatch_state *s;
247
248 s = get_state(sm->owner, sm->name, sm->sym);
249 if (!s)
250 sm_msg("%s new %s", __func__, show_sm(sm));
251 else
252 sm_msg("%s change %s (was %s)",
253 __func__, show_sm(sm), show_state(s));
254 }
255
256 if (unreachable())
257 return;
258
259 overwrite_sm_state_stree_stack(&fake_cur_stree_stack, sm);
260 }
261
262
263 typedef void (get_state_hook)(int owner, const char *name, struct symbol *sym);
264 DECLARE_PTR_LIST(fn_list, get_state_hook *);
265 static struct fn_list *get_state_hooks;
266
267 void add_get_state_hook(get_state_hook *fn)
268 {
460 return cur_stree;
461 }
462
463 int is_reachable(void)
464 {
465 if (cur_stree)
466 return 1;
467 return 0;
468 }
469
470 void set_true_false_states(int owner, const char *name, struct symbol *sym,
471 struct smatch_state *true_state,
472 struct smatch_state *false_state)
473 {
474 if (read_only)
475 sm_perror("cur_stree is read only.");
476
477 if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
478 struct smatch_state *tmp;
479
480 tmp = get_state(owner, name, sym);
481 sm_msg("%s [%s] '%s'. Was %s. Now T:%s F:%s", __func__,
482 check_name(owner), name, show_state(tmp),
483 show_state(true_state), show_state(false_state));
484 }
485
486 if (unreachable())
487 return;
488
489 if (!cond_false_stack || !cond_true_stack) {
490 sm_perror("missing true/false stacks");
491 return;
492 }
493
494 if (true_state)
495 set_state_stree_stack(&cond_true_stack, owner, name, sym, true_state);
496 if (false_state)
497 set_state_stree_stack(&cond_false_stack, owner, name, sym, false_state);
498 }
499
500 void set_true_false_states_expr(int owner, struct expression *expr,
514 }
515
516 void __set_true_false_sm(struct sm_state *true_sm, struct sm_state *false_sm)
517 {
518 int owner;
519 const char *name;
520 struct symbol *sym;
521
522 if (!true_sm && !false_sm)
523 return;
524
525 if (unreachable())
526 return;
527
528 owner = true_sm ? true_sm->owner : false_sm->owner;
529 name = true_sm ? true_sm->name : false_sm->name;
530 sym = true_sm ? true_sm->sym : false_sm->sym;
531 if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
532 struct smatch_state *tmp;
533
534 tmp = get_state(owner, name, sym);
535 sm_msg("%s [%s] '%s'. Was %s. Now T:%s F:%s", __func__,
536 check_name(owner), name, show_state(tmp),
537 show_state(true_sm ? true_sm->state : NULL),
538 show_state(false_sm ? false_sm->state : NULL));
539 }
540
541 if (!cond_false_stack || !cond_true_stack) {
542 sm_perror("missing true/false stacks");
543 return;
544 }
545
546 if (true_sm)
547 overwrite_sm_state_stree_stack(&cond_true_stack, true_sm);
548 if (false_sm)
549 overwrite_sm_state_stree_stack(&cond_false_stack, false_sm);
550 }
551
552 void nullify_path(void)
553 {
554 if (fake_cur_stree_stack) {
772 void __use_pre_cond_states(void)
773 {
774 free_stree(&cur_stree);
775 cur_stree = pop_stree(&pre_cond_stack);
776 }
777
778 void __use_cond_true_states(void)
779 {
780 __use_cond_stack(&cond_true_stack);
781 }
782
783 void __use_cond_false_states(void)
784 {
785 __use_cond_stack(&cond_false_stack);
786 }
787
788 void __negate_cond_stacks(void)
789 {
790 struct stree *old_false, *old_true;
791
792 __use_cond_stack(&cond_false_stack);
793 old_false = pop_stree(&cond_false_stack);
794 old_true = pop_stree(&cond_true_stack);
795 push_stree(&cond_false_stack, old_true);
796 push_stree(&cond_true_stack, old_false);
797 }
798
799 void __and_cond_states(void)
800 {
801 and_stree_stack(&cond_true_stack);
802 or_stree_stack(&pre_cond_stack, cur_stree, &cond_false_stack);
803 }
804
805 void __or_cond_states(void)
806 {
807 or_stree_stack(&pre_cond_stack, cur_stree, &cond_true_stack);
808 and_stree_stack(&cond_false_stack);
809 }
810
811 void __save_pre_cond_states(void)
812 {
|
67 static struct ptr_list *backup;
68
69 int option_debug;
70
71 void __print_cur_stree(void)
72 {
73 __print_stree(cur_stree);
74 }
75
76 int unreachable(void)
77 {
78 if (!cur_stree)
79 return 1;
80 return 0;
81 }
82
83 struct sm_state *set_state(int owner, const char *name, struct symbol *sym, struct smatch_state *state)
84 {
85 struct sm_state *ret;
86
87 if (!name || !state)
88 return NULL;
89
90 if (read_only)
91 sm_perror("cur_stree is read only.");
92
93 if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
94 struct smatch_state *s;
95
96 s = __get_state(owner, name, sym);
97 if (!s)
98 sm_msg("%s new [%s] '%s' %s", __func__,
99 check_name(owner), name, show_state(state));
100 else
101 sm_msg("%s change [%s] '%s' %s => %s",
102 __func__, check_name(owner), name, show_state(s),
103 show_state(state));
104 }
105
106 if (owner != -1 && unreachable())
107 return NULL;
108
109 if (fake_cur_stree_stack)
110 set_state_stree_stack(&fake_cur_stree_stack, owner, name, sym, state);
111
112 ret = set_state_stree(&cur_stree, owner, name, sym, state);
113
114 return ret;
115 }
116
179
180 FOR_EACH_SM(stree, sm) {
181 orig = get_sm_state(sm->owner, sm->name, sm->sym);
182 if (orig)
183 merged = merge_sm_states(orig, sm);
184 else
185 merged = sm;
186 __set_sm(merged);
187 } END_FOR_EACH_SM(sm);
188 }
189
190 void __set_sm(struct sm_state *sm)
191 {
192 if (read_only)
193 sm_perror("cur_stree is read only.");
194
195 if (option_debug ||
196 strcmp(check_name(sm->owner), option_debug_check) == 0) {
197 struct smatch_state *s;
198
199 s = __get_state(sm->owner, sm->name, sm->sym);
200 if (!s)
201 sm_msg("%s new %s", __func__, show_sm(sm));
202 else
203 sm_msg("%s change %s (was %s)", __func__, show_sm(sm),
204 show_state(s));
205 }
206
207 if (unreachable())
208 return;
209
210 if (fake_cur_stree_stack)
211 overwrite_sm_state_stree_stack(&fake_cur_stree_stack, sm);
212
213 overwrite_sm_state_stree(&cur_stree, sm);
214 }
215
216 void __set_sm_cur_stree(struct sm_state *sm)
217 {
218 if (read_only)
219 sm_perror("cur_stree is read only.");
220
221 if (option_debug ||
222 strcmp(check_name(sm->owner), option_debug_check) == 0) {
223 struct smatch_state *s;
224
225 s = __get_state(sm->owner, sm->name, sm->sym);
226 if (!s)
227 sm_msg("%s new %s", __func__, show_sm(sm));
228 else
229 sm_msg("%s change %s (was %s)",
230 __func__, show_sm(sm), show_state(s));
231 }
232
233 if (unreachable())
234 return;
235
236 overwrite_sm_state_stree(&cur_stree, sm);
237 }
238
239 void __set_sm_fake_stree(struct sm_state *sm)
240 {
241 if (read_only)
242 sm_perror("cur_stree is read only.");
243
244 if (option_debug ||
245 strcmp(check_name(sm->owner), option_debug_check) == 0) {
246 struct smatch_state *s;
247
248 s = __get_state(sm->owner, sm->name, sm->sym);
249 if (!s)
250 sm_msg("%s new %s", __func__, show_sm(sm));
251 else
252 sm_msg("%s change %s (was %s)",
253 __func__, show_sm(sm), show_state(s));
254 }
255
256 if (unreachable())
257 return;
258
259 overwrite_sm_state_stree_stack(&fake_cur_stree_stack, sm);
260 }
261
262
263 typedef void (get_state_hook)(int owner, const char *name, struct symbol *sym);
264 DECLARE_PTR_LIST(fn_list, get_state_hook *);
265 static struct fn_list *get_state_hooks;
266
267 void add_get_state_hook(get_state_hook *fn)
268 {
460 return cur_stree;
461 }
462
463 int is_reachable(void)
464 {
465 if (cur_stree)
466 return 1;
467 return 0;
468 }
469
470 void set_true_false_states(int owner, const char *name, struct symbol *sym,
471 struct smatch_state *true_state,
472 struct smatch_state *false_state)
473 {
474 if (read_only)
475 sm_perror("cur_stree is read only.");
476
477 if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
478 struct smatch_state *tmp;
479
480 tmp = __get_state(owner, name, sym);
481 sm_msg("%s [%s] '%s'. Was %s. Now T:%s F:%s", __func__,
482 check_name(owner), name, show_state(tmp),
483 show_state(true_state), show_state(false_state));
484 }
485
486 if (unreachable())
487 return;
488
489 if (!cond_false_stack || !cond_true_stack) {
490 sm_perror("missing true/false stacks");
491 return;
492 }
493
494 if (true_state)
495 set_state_stree_stack(&cond_true_stack, owner, name, sym, true_state);
496 if (false_state)
497 set_state_stree_stack(&cond_false_stack, owner, name, sym, false_state);
498 }
499
500 void set_true_false_states_expr(int owner, struct expression *expr,
514 }
515
516 void __set_true_false_sm(struct sm_state *true_sm, struct sm_state *false_sm)
517 {
518 int owner;
519 const char *name;
520 struct symbol *sym;
521
522 if (!true_sm && !false_sm)
523 return;
524
525 if (unreachable())
526 return;
527
528 owner = true_sm ? true_sm->owner : false_sm->owner;
529 name = true_sm ? true_sm->name : false_sm->name;
530 sym = true_sm ? true_sm->sym : false_sm->sym;
531 if (option_debug || strcmp(check_name(owner), option_debug_check) == 0) {
532 struct smatch_state *tmp;
533
534 tmp = __get_state(owner, name, sym);
535 sm_msg("%s [%s] '%s'. Was %s. Now T:%s F:%s", __func__,
536 check_name(owner), name, show_state(tmp),
537 show_state(true_sm ? true_sm->state : NULL),
538 show_state(false_sm ? false_sm->state : NULL));
539 }
540
541 if (!cond_false_stack || !cond_true_stack) {
542 sm_perror("missing true/false stacks");
543 return;
544 }
545
546 if (true_sm)
547 overwrite_sm_state_stree_stack(&cond_true_stack, true_sm);
548 if (false_sm)
549 overwrite_sm_state_stree_stack(&cond_false_stack, false_sm);
550 }
551
552 void nullify_path(void)
553 {
554 if (fake_cur_stree_stack) {
772 void __use_pre_cond_states(void)
773 {
774 free_stree(&cur_stree);
775 cur_stree = pop_stree(&pre_cond_stack);
776 }
777
778 void __use_cond_true_states(void)
779 {
780 __use_cond_stack(&cond_true_stack);
781 }
782
783 void __use_cond_false_states(void)
784 {
785 __use_cond_stack(&cond_false_stack);
786 }
787
788 void __negate_cond_stacks(void)
789 {
790 struct stree *old_false, *old_true;
791
792 old_false = pop_stree(&cond_false_stack);
793 old_true = pop_stree(&cond_true_stack);
794 push_stree(&cond_false_stack, old_true);
795 push_stree(&cond_true_stack, old_false);
796 }
797
798 void __and_cond_states(void)
799 {
800 and_stree_stack(&cond_true_stack);
801 or_stree_stack(&pre_cond_stack, cur_stree, &cond_false_stack);
802 }
803
804 void __or_cond_states(void)
805 {
806 or_stree_stack(&pre_cond_stack, cur_stree, &cond_true_stack);
807 and_stree_stack(&cond_false_stack);
808 }
809
810 void __save_pre_cond_states(void)
811 {
|