Skip to content

Commit 4f88473

Browse files
author
Daniel Kroening
authored
Merge pull request #1268 from diffblue/link-goto-model
factor out goto model linking into separate file
2 parents e64d9c9 + 8e52f8d commit 4f88473

File tree

4 files changed

+230
-156
lines changed

4 files changed

+230
-156
lines changed

src/goto-programs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ SRC = basic_blocks.cpp \
2626
interpreter.cpp \
2727
interpreter_evaluate.cpp \
2828
json_goto_trace.cpp \
29+
link_goto_model.cpp \
2930
link_to_library.cpp \
3031
loop_ids.cpp \
3132
mm_io.cpp \

src/goto-programs/link_goto_model.cpp

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
/*******************************************************************\
2+
3+
Module: Link Goto Programs
4+
5+
Author: Michael Tautschnig, Daniel Kroening
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Link Goto Programs
11+
12+
#include "link_goto_model.h"
13+
14+
#include <unordered_set>
15+
16+
#include <util/base_type.h>
17+
#include <util/symbol.h>
18+
#include <util/rename_symbol.h>
19+
20+
#include <linking/linking_class.h>
21+
22+
#include "goto_model.h"
23+
24+
static void rename_symbols_in_function(
25+
goto_functionst::goto_functiont &function,
26+
const rename_symbolt &rename_symbol)
27+
{
28+
goto_programt &program=function.body;
29+
rename_symbol(function.type);
30+
31+
Forall_goto_program_instructions(iit, program)
32+
{
33+
rename_symbol(iit->code);
34+
rename_symbol(iit->guard);
35+
}
36+
}
37+
38+
/// Link a set of goto functions, considering weak symbols
39+
/// and symbol renaming
40+
static bool link_functions(
41+
symbol_tablet &dest_symbol_table,
42+
goto_functionst &dest_functions,
43+
const symbol_tablet &src_symbol_table,
44+
goto_functionst &src_functions,
45+
const rename_symbolt &rename_symbol,
46+
const std::unordered_set<irep_idt, irep_id_hash> &weak_symbols,
47+
const replace_symbolt &object_type_updates)
48+
{
49+
namespacet ns(dest_symbol_table);
50+
namespacet src_ns(src_symbol_table);
51+
52+
// merge functions
53+
Forall_goto_functions(src_it, src_functions)
54+
{
55+
// the function might have been renamed
56+
rename_symbolt::expr_mapt::const_iterator e_it=
57+
rename_symbol.expr_map.find(src_it->first);
58+
59+
irep_idt final_id=src_it->first;
60+
61+
if(e_it!=rename_symbol.expr_map.end())
62+
final_id=e_it->second;
63+
64+
// already there?
65+
goto_functionst::function_mapt::iterator dest_f_it=
66+
dest_functions.function_map.find(final_id);
67+
68+
if(dest_f_it==dest_functions.function_map.end()) // not there yet
69+
{
70+
rename_symbols_in_function(src_it->second, rename_symbol);
71+
72+
goto_functionst::goto_functiont &in_dest_symbol_table=
73+
dest_functions.function_map[final_id];
74+
75+
in_dest_symbol_table.body.swap(src_it->second.body);
76+
in_dest_symbol_table.type=src_it->second.type;
77+
}
78+
else // collision!
79+
{
80+
goto_functionst::goto_functiont &in_dest_symbol_table=
81+
dest_functions.function_map[final_id];
82+
83+
goto_functionst::goto_functiont &src_func=src_it->second;
84+
85+
if(in_dest_symbol_table.body.instructions.empty() ||
86+
weak_symbols.find(final_id)!=weak_symbols.end())
87+
{
88+
// the one with body wins!
89+
rename_symbols_in_function(src_func, rename_symbol);
90+
91+
in_dest_symbol_table.body.swap(src_func.body);
92+
in_dest_symbol_table.type=src_func.type;
93+
}
94+
else if(src_func.body.instructions.empty() ||
95+
src_ns.lookup(src_it->first).is_weak)
96+
{
97+
// just keep the old one in dest
98+
}
99+
else if(in_dest_symbol_table.type.get_bool(ID_C_inlined))
100+
{
101+
// ok, we silently ignore
102+
}
103+
else
104+
{
105+
// the linking code will have ensured that types match
106+
rename_symbol(src_func.type);
107+
INVARIANT(base_type_eq(in_dest_symbol_table.type, src_func.type, ns),
108+
"linking ensures that types match");
109+
}
110+
}
111+
}
112+
113+
// apply macros
114+
rename_symbolt macro_application;
115+
116+
forall_symbols(it, dest_symbol_table.symbols)
117+
if(it->second.is_macro && !it->second.is_type)
118+
{
119+
const symbolt &symbol=it->second;
120+
121+
INVARIANT(symbol.value.id()==ID_symbol, "must have symbol");
122+
const irep_idt &id=to_symbol_expr(symbol.value).get_identifier();
123+
124+
#if 0
125+
if(!base_type_eq(symbol.type, ns.lookup(id).type, ns))
126+
{
127+
std::cerr << symbol << '\n';
128+
std::cerr << ns.lookup(id) << '\n';
129+
}
130+
INVARIANT(base_type_eq(symbol.type, ns.lookup(id).type, ns),
131+
"type matches");
132+
#endif
133+
134+
macro_application.insert_expr(symbol.name, id);
135+
}
136+
137+
if(!macro_application.expr_map.empty())
138+
Forall_goto_functions(dest_it, dest_functions)
139+
rename_symbols_in_function(dest_it->second, macro_application);
140+
141+
if(!object_type_updates.expr_map.empty())
142+
{
143+
Forall_goto_functions(dest_it, dest_functions)
144+
Forall_goto_program_instructions(iit, dest_it->second.body)
145+
{
146+
object_type_updates(iit->code);
147+
object_type_updates(iit->guard);
148+
}
149+
}
150+
151+
return false;
152+
}
153+
154+
void link_goto_model(
155+
goto_modelt &dest,
156+
goto_modelt &src,
157+
message_handlert &message_handler)
158+
{
159+
typedef std::unordered_set<irep_idt, irep_id_hash> id_sett;
160+
id_sett weak_symbols;
161+
162+
forall_symbols(it, dest.symbol_table.symbols)
163+
if(it->second.is_weak)
164+
weak_symbols.insert(it->first);
165+
166+
linkingt linking(dest.symbol_table,
167+
src.symbol_table,
168+
message_handler);
169+
170+
if(linking.typecheck_main())
171+
throw 0;
172+
173+
if(link_functions(
174+
dest.symbol_table,
175+
dest.goto_functions,
176+
src.symbol_table,
177+
src.goto_functions,
178+
linking.rename_symbol,
179+
weak_symbols,
180+
linking.object_type_updates))
181+
throw 0;
182+
}

src/goto-programs/link_goto_model.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*******************************************************************\
2+
3+
Module: Read Goto Programs
4+
5+
Author: Daniel Kroening, kroening@kroening.com
6+
7+
\*******************************************************************/
8+
9+
/// \file
10+
/// Read Goto Programs
11+
12+
#ifndef CPROVER_GOTO_PROGRAMS_LINK_GOTO_MODEL_H
13+
#define CPROVER_GOTO_PROGRAMS_LINK_GOTO_MODEL_H
14+
15+
class goto_modelt;
16+
class message_handlert;
17+
18+
void link_goto_model(
19+
goto_modelt &dest,
20+
goto_modelt &src,
21+
message_handlert &);
22+
23+
#endif // CPROVER_GOTO_PROGRAMS_LINK_GOTO_MODEL_H

0 commit comments

Comments
 (0)