param_key: fix container of when no struct member is referenced
[smatch.git] / smatch_links.c
blob8690b872ebb089db03b9de82e599c5b0ca17e178
1 /*
2 * Copyright (C) 2014 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
19 * Some helper functions for managing links.
23 #include "smatch.h"
24 #include "smatch_slist.h"
26 static struct smatch_state *alloc_link(struct var_sym_list *links)
28 struct smatch_state *state;
29 static char buf[256] = "";
30 struct var_sym *tmp;
31 int cnt = 0;
33 state = __alloc_smatch_state(0);
35 FOR_EACH_PTR(links, tmp) {
36 cnt += snprintf(buf + cnt, sizeof(buf) - cnt, "%s%s",
37 cnt ? ", " : "", tmp->var);
38 if (cnt >= sizeof(buf))
39 goto done;
40 } END_FOR_EACH_PTR(tmp);
42 done:
43 state->name = alloc_sname(buf);
44 state->data = links;
45 return state;
48 struct smatch_state *merge_link_states(struct smatch_state *s1, struct smatch_state *s2)
50 struct var_sym_list *new_links;
52 if (s1 == &undefined)
53 return s2;
54 if (s2 == &undefined)
55 return s1;
57 if (var_sym_lists_equiv(s1->data, s2->data))
58 return s1;
60 new_links = clone_var_sym_list(s1->data);
61 merge_var_sym_list(&new_links, s2->data);
63 return alloc_link(new_links);
66 void store_link(int link_id, const char *var, struct symbol *sym, const char *link_name, struct symbol *link_sym)
69 struct smatch_state *old_state;
70 struct var_sym_list *links;
72 if (!cur_func_sym)
73 return;
75 old_state = get_state(link_id, var, sym);
76 if (old_state)
77 links = clone_var_sym_list(old_state->data);
78 else
79 links = NULL;
81 add_var_sym(&links, link_name, link_sym);
82 set_state(link_id, var, sym, alloc_link(links));
85 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr)
87 struct var_sym_list *links;
88 struct var_sym *tmp;
90 links = sm->state->data;
92 FOR_EACH_PTR(links, tmp) {
93 set_state(sm->owner - 1, tmp->var, tmp->sym, &undefined);
94 } END_FOR_EACH_PTR(tmp);
95 set_state(sm->owner, sm->name, sm->sym, &undefined);
98 void set_up_link_functions(int id, int link_id)
100 if (id + 1 != link_id)
101 sm_fatal("FATAL ERROR: links need to be registered directly after the check");
103 set_dynamic_states(link_id);
104 add_merge_hook(link_id, &merge_link_states);
105 add_modification_hook(link_id, &match_link_modify);
106 // free link at the end of function