Skip to content

Commit 5671835

Browse files
Daniel Kroeningtautschnig
Daniel Kroening
authored andcommitted
value_sets now have function identifiers
We are working towards removing the "function" field from goto_programt::instructionst::instructiont, and thus need to pass the identifier of the function whenever it actually is required.
1 parent e2a5430 commit 5671835

18 files changed

+169
-127
lines changed

src/analyses/flow_insensitive_analysis.cpp

Lines changed: 65 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@ exprt flow_insensitive_abstract_domain_baset::get_return_lhs(locationt to) const
4646
return to_code_function_call(to->code).lhs();
4747
}
4848

49-
void flow_insensitive_analysis_baset::operator()(
50-
const goto_functionst &goto_functions)
49+
void flow_insensitive_analysis_baset::
50+
operator()(const irep_idt &function_id, const goto_programt &goto_program)
5151
{
52-
initialize(goto_functions);
53-
fixedpoint(goto_functions);
52+
initialize(goto_program);
53+
goto_functionst goto_functions;
54+
fixedpoint(function_id, goto_program, goto_functions);
5455
}
5556

56-
void flow_insensitive_analysis_baset::operator()(
57-
const goto_programt &goto_program)
57+
void flow_insensitive_analysis_baset::
58+
operator()(const goto_functionst &goto_functions)
5859
{
59-
initialize(goto_program);
60-
goto_functionst goto_functions;
61-
fixedpoint(goto_program, goto_functions);
60+
initialize(goto_functions);
61+
fixedpoint(goto_functions);
6262
}
6363

6464
void flow_insensitive_analysis_baset::output(
@@ -69,14 +69,14 @@ void flow_insensitive_analysis_baset::output(
6969
{
7070
out << "////\n" << "//// Function: " << f_it->first << "\n////\n\n";
7171

72-
output(f_it->second.body, f_it->first, out);
72+
output(f_it->first, f_it->second.body, out);
7373
}
7474
}
7575

7676
void flow_insensitive_analysis_baset::output(
77-
const goto_programt &,
7877
const irep_idt &,
79-
std::ostream &out) const
78+
const goto_programt &,
79+
std::ostream &out)
8080
{
8181
get_state().output(ns, out);
8282
}
@@ -99,6 +99,7 @@ flow_insensitive_analysis_baset::get_next(
9999
}
100100

101101
bool flow_insensitive_analysis_baset::fixedpoint(
102+
const irep_idt &function_id,
102103
const goto_programt &goto_program,
103104
const goto_functionst &goto_functions)
104105
{
@@ -119,14 +120,15 @@ bool flow_insensitive_analysis_baset::fixedpoint(
119120
{
120121
locationt l=get_next(working_set);
121122

122-
if(visit(l, working_set, goto_program, goto_functions))
123+
if(visit(function_id, l, working_set, goto_program, goto_functions))
123124
new_data=true;
124125
}
125126

126127
return new_data;
127128
}
128129

129130
bool flow_insensitive_analysis_baset::visit(
131+
const irep_idt &function_id,
130132
locationt l,
131133
working_sett &working_set,
132134
const goto_programt &goto_program,
@@ -157,16 +159,16 @@ bool flow_insensitive_analysis_baset::visit(
157159
// this is a big special case
158160
const code_function_callt &code = to_code_function_call(l->code);
159161

160-
changed=
161-
do_function_call_rec(
162-
l,
163-
code.function(),
164-
code.arguments(),
165-
get_state(),
166-
goto_functions);
162+
changed = do_function_call_rec(
163+
function_id,
164+
l,
165+
code.function(),
166+
code.arguments(),
167+
get_state(),
168+
goto_functions);
167169
}
168170
else
169-
changed = get_state().transform(ns, l, to_l);
171+
changed = get_state().transform(ns, function_id, l, function_id, to_l);
170172

171173
if(changed || !seen(to_l))
172174
{
@@ -193,6 +195,7 @@ bool flow_insensitive_analysis_baset::visit(
193195
}
194196

195197
bool flow_insensitive_analysis_baset::do_function_call(
198+
const irep_idt &calling_function,
196199
locationt l_call,
197200
const goto_functionst &goto_functions,
198201
const goto_functionst::function_mapt::const_iterator f_it,
@@ -222,9 +225,15 @@ bool flow_insensitive_analysis_baset::do_function_call(
222225
t->location_number=1;
223226

224227
locationt l_next=l_call; l_next++;
225-
bool new_data=state.transform(ns, l_call, r);
226-
new_data = state.transform(ns, r, t) || new_data;
227-
new_data = state.transform(ns, t, l_next) || new_data;
228+
// do the edge from the call site to the simulated function (the artificial
229+
// return statement that we just generated)
230+
bool new_data =
231+
state.transform(ns, calling_function, l_call, f_it->first, r);
232+
// do the edge from the return to the artificial end-of-function
233+
new_data = state.transform(ns, f_it->first, r, f_it->first, t) || new_data;
234+
// do edge from (artificial) end of function to instruction after call
235+
new_data =
236+
state.transform(ns, f_it->first, t, calling_function, l_next) || new_data;
228237

229238
return new_data;
230239
}
@@ -241,7 +250,8 @@ bool flow_insensitive_analysis_baset::do_function_call(
241250
l_begin->function == f_it->first, "function names have to match");
242251

243252
// do the edge from the call site to the beginning of the function
244-
new_data=state.transform(ns, l_call, l_begin);
253+
new_data =
254+
state.transform(ns, calling_function, l_call, f_it->first, l_begin);
245255

246256
// do each function at least once
247257
if(functions_done.find(f_it->first)==
@@ -255,7 +265,7 @@ bool flow_insensitive_analysis_baset::do_function_call(
255265
if(new_data)
256266
{
257267
// recursive call
258-
fixedpoint(goto_function.body, goto_functions);
268+
fixedpoint(f_it->first, goto_function.body, goto_functions);
259269
new_data=true; // could be reset by fixedpoint
260270
}
261271
}
@@ -269,13 +279,16 @@ bool flow_insensitive_analysis_baset::do_function_call(
269279
// do edge from end of function to instruction after call
270280
locationt l_next=l_call;
271281
l_next++;
272-
new_data = state.transform(ns, l_end, l_next) || new_data;
282+
new_data =
283+
state.transform(ns, f_it->first, l_end, calling_function, l_next) ||
284+
new_data;
273285
}
274286

275287
return new_data;
276288
}
277289

278290
bool flow_insensitive_analysis_baset::do_function_call_rec(
291+
const irep_idt &calling_function,
279292
locationt l_call,
280293
const exprt &function,
281294
const exprt::operandst &arguments,
@@ -302,13 +315,8 @@ bool flow_insensitive_analysis_baset::do_function_call_rec(
302315
if(it==goto_functions.function_map.end())
303316
throw "failed to find function "+id2string(identifier);
304317

305-
new_data =
306-
do_function_call(
307-
l_call,
308-
goto_functions,
309-
it,
310-
arguments,
311-
state);
318+
new_data = do_function_call(
319+
calling_function, l_call, goto_functions, it, arguments, state);
312320

313321
recursion_set.erase(identifier);
314322
}
@@ -317,12 +325,21 @@ bool flow_insensitive_analysis_baset::do_function_call_rec(
317325
const auto &if_expr = to_if_expr(function);
318326

319327
new_data = do_function_call_rec(
320-
l_call, if_expr.true_case(), arguments, state, goto_functions);
328+
calling_function,
329+
l_call,
330+
if_expr.true_case(),
331+
arguments,
332+
state,
333+
goto_functions);
321334

322-
new_data =
323-
do_function_call_rec(
324-
l_call, if_expr.false_case(), arguments, state, goto_functions) ||
325-
new_data;
335+
new_data = do_function_call_rec(
336+
calling_function,
337+
l_call,
338+
if_expr.false_case(),
339+
arguments,
340+
state,
341+
goto_functions) ||
342+
new_data;
326343
}
327344
else if(function.id()==ID_dereference)
328345
{
@@ -344,13 +361,14 @@ bool flow_insensitive_analysis_baset::do_function_call_rec(
344361

345362
if(it!=goto_functions.function_map.end())
346363
{
347-
new_data =
348-
do_function_call_rec(
349-
l_call,
350-
o.object(),
351-
arguments,
352-
state,
353-
goto_functions) || new_data;
364+
new_data = do_function_call_rec(
365+
calling_function,
366+
l_call,
367+
o.object(),
368+
arguments,
369+
state,
370+
goto_functions) ||
371+
new_data;
354372
}
355373
}
356374
}
@@ -393,7 +411,7 @@ bool flow_insensitive_analysis_baset::fixedpoint(
393411
const goto_functionst &goto_functions)
394412
{
395413
functions_done.insert(it->first);
396-
return fixedpoint(it->second.body, goto_functions);
414+
return fixedpoint(it->first, it->second.body, goto_functions);
397415
}
398416

399417
void flow_insensitive_analysis_baset::update(const goto_functionst &)

src/analyses/flow_insensitive_analysis.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ class flow_insensitive_abstract_domain_baset
4747

4848
virtual bool transform(
4949
const namespacet &ns,
50+
const irep_idt &function_from,
5051
locationt from,
51-
locationt to)=0;
52+
const irep_idt &function_to,
53+
locationt to) = 0;
5254

5355
virtual ~flow_insensitive_abstract_domain_baset()
5456
{
@@ -126,8 +128,8 @@ class flow_insensitive_analysis_baset
126128

127129
virtual void update(const goto_functionst &goto_functions);
128130

129-
virtual void operator()(
130-
const goto_programt &goto_program);
131+
virtual void
132+
operator()(const irep_idt &function_id, const goto_programt &goto_program);
131133

132134
virtual void operator()(
133135
const goto_functionst &goto_functions);
@@ -146,20 +148,13 @@ class flow_insensitive_analysis_baset
146148
std::ostream &out);
147149

148150
virtual void output(
151+
const irep_idt &function_id,
149152
const goto_programt &goto_program,
150-
std::ostream &out)
151-
{
152-
output(goto_program, "", out);
153-
}
153+
std::ostream &out);
154154

155155
protected:
156156
const namespacet &ns;
157157

158-
virtual void output(
159-
const goto_programt &goto_program,
160-
const irep_idt &identifier,
161-
std::ostream &out) const;
162-
163158
typedef std::priority_queue<locationt> working_sett;
164159

165160
locationt get_next(working_sett &working_set);
@@ -173,6 +168,7 @@ class flow_insensitive_analysis_baset
173168

174169
// true = found something new
175170
bool fixedpoint(
171+
const irep_idt &function_id,
176172
const goto_programt &goto_program,
177173
const goto_functionst &goto_functions);
178174

@@ -185,6 +181,7 @@ class flow_insensitive_analysis_baset
185181

186182
// true = found something new
187183
bool visit(
184+
const irep_idt &function_id,
188185
locationt l,
189186
working_sett &working_set,
190187
const goto_programt &goto_program,
@@ -206,13 +203,15 @@ class flow_insensitive_analysis_baset
206203

207204
// function calls
208205
bool do_function_call_rec(
206+
const irep_idt &calling_function,
209207
locationt l_call,
210208
const exprt &function,
211209
const exprt::operandst &arguments,
212210
statet &new_state,
213211
const goto_functionst &goto_functions);
214212

215213
bool do_function_call(
214+
const irep_idt &calling_function,
216215
locationt l_call,
217216
const goto_functionst &goto_functions,
218217
const goto_functionst::function_mapt::const_iterator f_it,

src/analyses/goto_rw.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ void rw_range_set_value_sett::get_objects_dereference(
626626
size);
627627

628628
exprt object=deref;
629-
dereference(target, object, ns, value_sets);
629+
dereference(function, target, object, ns, value_sets);
630630

631631
auto type_bits = pointer_offset_bits(object.type(), ns);
632632

src/goto-instrument/rw_set.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ void _rw_set_loct::read_write_rec(
159159
read_write_rec(*it, r, w, suffix, guard);
160160
}
161161
#else
162-
dereference(target, tmp, ns, value_sets);
162+
dereference(function_id, target, tmp, ns, value_sets);
163163

164164
read_write_rec(tmp, r, w, suffix, guard);
165165
#endif

src/goto-symex/precondition.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ void preconditiont::compute_rec(exprt &dest)
113113
// aliasing may happen here
114114

115115
value_setst::valuest expr_set;
116-
value_sets.get_values(target, deref_expr.pointer(), expr_set);
116+
value_sets.get_values(
117+
SSA_step.source.function, target, deref_expr.pointer(), expr_set);
117118
std::unordered_set<irep_idt> symbols;
118119

119120
for(value_setst::valuest::const_iterator
@@ -127,7 +128,7 @@ void preconditiont::compute_rec(exprt &dest)
127128
// may alias!
128129
exprt tmp;
129130
tmp.swap(deref_expr.pointer());
130-
dereference(target, tmp, ns, value_sets);
131+
dereference(SSA_step.source.function, target, tmp, ns, value_sets);
131132
deref_expr.swap(tmp);
132133
compute_rec(deref_expr);
133134
}

src/pointer-analysis/goto_program_dereference.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ void goto_program_dereferencet::get_value_set(
236236
const exprt &expr,
237237
value_setst::valuest &dest)
238238
{
239-
value_sets.get_values(current_target, expr, dest);
239+
value_sets.get_values(current_function, current_target, expr, dest);
240240
}
241241

242242
/// Remove dereference expressions contained in `expr`.
@@ -367,9 +367,11 @@ void goto_program_dereferencet::dereference_instruction(
367367

368368
/// Set the current target to `target` and remove derefence from expr.
369369
void goto_program_dereferencet::dereference_expression(
370+
const irep_idt &function_id,
370371
goto_programt::const_targett target,
371372
exprt &expr)
372373
{
374+
current_function = function_id;
373375
current_target=target;
374376
#if 0
375377
valid_local_variables=&target->local_variables;
@@ -458,6 +460,7 @@ void pointer_checks(
458460
/// Remove dereferences in `expr` using `value_sets` to determine to what
459461
/// objects the pointers may be pointing to.
460462
void dereference(
463+
const irep_idt &function_id,
461464
goto_programt::const_targett target,
462465
exprt &expr,
463466
const namespacet &ns,
@@ -467,5 +470,5 @@ void dereference(
467470
symbol_tablet new_symbol_table;
468471
goto_program_dereferencet
469472
goto_program_dereference(ns, new_symbol_table, options, value_sets);
470-
goto_program_dereference.dereference_expression(target, expr);
473+
goto_program_dereference.dereference_expression(function_id, target, expr);
471474
}

0 commit comments

Comments
 (0)