11506 smatch resync
1 /* 2 * Copyright (C) 2014 Oracle. 3 * 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. 8 * 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. 13 * 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 16 */ 17 18 /* 19 * Some helper functions for managing links. 20 * 21 */ 22 23 #include "smatch.h" 24 #include "smatch_slist.h" 25 26 static struct smatch_state *alloc_link(struct var_sym_list *links) 27 { 28 struct smatch_state *state; 29 static char buf[256]; 30 struct var_sym *tmp; 31 int i; 32 33 state = __alloc_smatch_state(0); 34 35 i = 0; 36 FOR_EACH_PTR(links, tmp) { 37 if (!i++) { 38 snprintf(buf, sizeof(buf), "%s", tmp->var); 39 } else { 40 append(buf, ", ", sizeof(buf)); 41 append(buf, tmp->var, sizeof(buf)); 42 } 43 } END_FOR_EACH_PTR(tmp); 44 45 state->name = alloc_sname(buf); 46 state->data = links; 47 return state; 48 } 49 50 struct smatch_state *merge_link_states(struct smatch_state *s1, struct smatch_state *s2) 51 { 52 struct var_sym_list *new_links; 53 54 if (s1 == &undefined) 55 return s2; 56 if (s2 == &undefined) 57 return s1; 58 59 if (var_sym_lists_equiv(s1->data, s2->data)) 60 return s1; 61 62 new_links = clone_var_sym_list(s1->data); 63 merge_var_sym_list(&new_links, s2->data); 64 65 return alloc_link(new_links); 66 } 67 68 void store_link(int link_id, const char *var, struct symbol *sym, const char *link_name, struct symbol *link_sym) 69 { 70 71 struct smatch_state *old_state; 72 struct var_sym_list *links; 73 74 if (!cur_func_sym) 75 return; 76 77 old_state = get_state(link_id, var, sym); 78 if (old_state) 79 links = clone_var_sym_list(old_state->data); 80 else 81 links = NULL; 82 83 add_var_sym(&links, link_name, link_sym); 84 set_state(link_id, var, sym, alloc_link(links)); 85 } 86 87 static void match_link_modify(struct sm_state *sm, struct expression *mod_expr) 88 { 89 struct var_sym_list *links; 90 struct var_sym *tmp; 91 92 links = sm->state->data; 93 94 FOR_EACH_PTR(links, tmp) { 95 set_state(sm->owner - 1, tmp->var, tmp->sym, &undefined); 96 } END_FOR_EACH_PTR(tmp); 97 set_state(sm->owner, sm->name, sm->sym, &undefined); 98 } 99 100 void set_up_link_functions(int id, int link_id) 101 { 102 if (id + 1 != link_id) 103 sm_fatal("FATAL ERROR: links need to be registered directly after the check"); 104 105 add_merge_hook(link_id, &merge_link_states); 106 add_modification_hook(link_id, &match_link_modify); 107 // free link at the end of function 108 } 109 --- EOF ---