Skip to content

Commit 04fac41

Browse files
authored
Merge pull request #3865 from tautschnig/function-value_sets
value_sets now have function identifiers [blocks: #3126]
2 parents f3db3f0 + 61557dc commit 04fac41

18 files changed

+163
-121
lines changed

src/analyses/flow_insensitive_analysis.cpp

Lines changed: 59 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ void flow_insensitive_analysis_baset::operator()(
5353
fixedpoint(goto_functions);
5454
}
5555

56-
void flow_insensitive_analysis_baset::operator()(
57-
const goto_programt &goto_program)
56+
void flow_insensitive_analysis_baset::
57+
operator()(const irep_idt &function_id, const goto_programt &goto_program)
5858
{
5959
initialize(goto_program);
6060
goto_functionst goto_functions;
61-
fixedpoint(goto_program, goto_functions);
61+
fixedpoint(function_id, goto_program, 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,
@@ -221,9 +224,15 @@ bool flow_insensitive_analysis_baset::do_function_call(
221224
t->location_number=1;
222225

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

228237
return new_data;
229238
}
@@ -240,7 +249,8 @@ bool flow_insensitive_analysis_baset::do_function_call(
240249
l_begin->function == f_it->first, "function names have to match");
241250

242251
// do the edge from the call site to the beginning of the function
243-
new_data=state.transform(ns, l_call, l_begin);
252+
new_data =
253+
state.transform(ns, calling_function, l_call, f_it->first, l_begin);
244254

245255
// do each function at least once
246256
if(functions_done.find(f_it->first)==
@@ -254,7 +264,7 @@ bool flow_insensitive_analysis_baset::do_function_call(
254264
if(new_data)
255265
{
256266
// recursive call
257-
fixedpoint(goto_function.body, goto_functions);
267+
fixedpoint(f_it->first, goto_function.body, goto_functions);
258268
new_data=true; // could be reset by fixedpoint
259269
}
260270
}
@@ -268,13 +278,16 @@ bool flow_insensitive_analysis_baset::do_function_call(
268278
// do edge from end of function to instruction after call
269279
locationt l_next=l_call;
270280
l_next++;
271-
new_data = state.transform(ns, l_end, l_next) || new_data;
281+
new_data =
282+
state.transform(ns, f_it->first, l_end, calling_function, l_next) ||
283+
new_data;
272284
}
273285

274286
return new_data;
275287
}
276288

277289
bool flow_insensitive_analysis_baset::do_function_call_rec(
290+
const irep_idt &calling_function,
278291
locationt l_call,
279292
const exprt &function,
280293
const exprt::operandst &arguments,
@@ -301,13 +314,8 @@ bool flow_insensitive_analysis_baset::do_function_call_rec(
301314
if(it==goto_functions.function_map.end())
302315
throw "failed to find function "+id2string(identifier);
303316

304-
new_data =
305-
do_function_call(
306-
l_call,
307-
goto_functions,
308-
it,
309-
arguments,
310-
state);
317+
new_data = do_function_call(
318+
calling_function, l_call, goto_functions, it, arguments, state);
311319

312320
recursion_set.erase(identifier);
313321
}
@@ -316,12 +324,21 @@ bool flow_insensitive_analysis_baset::do_function_call_rec(
316324
const auto &if_expr = to_if_expr(function);
317325

318326
new_data = do_function_call_rec(
319-
l_call, if_expr.true_case(), arguments, state, goto_functions);
327+
calling_function,
328+
l_call,
329+
if_expr.true_case(),
330+
arguments,
331+
state,
332+
goto_functions);
320333

321-
new_data =
322-
do_function_call_rec(
323-
l_call, if_expr.false_case(), arguments, state, goto_functions) ||
324-
new_data;
334+
new_data = do_function_call_rec(
335+
calling_function,
336+
l_call,
337+
if_expr.false_case(),
338+
arguments,
339+
state,
340+
goto_functions) ||
341+
new_data;
325342
}
326343
else if(function.id()==ID_dereference)
327344
{
@@ -343,13 +360,14 @@ bool flow_insensitive_analysis_baset::do_function_call_rec(
343360

344361
if(it!=goto_functions.function_map.end())
345362
{
346-
new_data =
347-
do_function_call_rec(
348-
l_call,
349-
o.object(),
350-
arguments,
351-
state,
352-
goto_functions) || new_data;
363+
new_data = do_function_call_rec(
364+
calling_function,
365+
l_call,
366+
o.object(),
367+
arguments,
368+
state,
369+
goto_functions) ||
370+
new_data;
353371
}
354372
}
355373
}
@@ -392,7 +410,7 @@ bool flow_insensitive_analysis_baset::fixedpoint(
392410
const goto_functionst &goto_functions)
393411
{
394412
functions_done.insert(it->first);
395-
return fixedpoint(it->second.body, goto_functions);
413+
return fixedpoint(it->first, it->second.body, goto_functions);
396414
}
397415

398416
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_id, 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_id, 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
@@ -227,7 +227,7 @@ void goto_program_dereferencet::get_value_set(
227227
const exprt &expr,
228228
value_setst::valuest &dest)
229229
{
230-
value_sets.get_values(current_target, expr, dest);
230+
value_sets.get_values(current_function, current_target, expr, dest);
231231
}
232232

233233
/// Remove dereference expressions contained in `expr`.
@@ -357,9 +357,11 @@ void goto_program_dereferencet::dereference_instruction(
357357

358358
/// Set the current target to `target` and remove derefence from expr.
359359
void goto_program_dereferencet::dereference_expression(
360+
const irep_idt &function_id,
360361
goto_programt::const_targett target,
361362
exprt &expr)
362363
{
364+
current_function = function_id;
363365
current_target=target;
364366
#if 0
365367
valid_local_variables=&target->local_variables;
@@ -448,6 +450,7 @@ void pointer_checks(
448450
/// Remove dereferences in `expr` using `value_sets` to determine to what
449451
/// objects the pointers may be pointing to.
450452
void dereference(
453+
const irep_idt &function_id,
451454
goto_programt::const_targett target,
452455
exprt &expr,
453456
const namespacet &ns,
@@ -457,5 +460,5 @@ void dereference(
457460
symbol_tablet new_symbol_table;
458461
goto_program_dereferencet
459462
goto_program_dereference(ns, new_symbol_table, options, value_sets);
460-
goto_program_dereference.dereference_expression(target, expr);
463+
goto_program_dereference.dereference_expression(function_id, target, expr);
461464
}

src/pointer-analysis/goto_program_dereference.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class goto_program_dereferencet:protected dereference_callbackt
5252
void pointer_checks(goto_functionst &goto_functions);
5353

5454
void dereference_expression(
55+
const irep_idt &function_id,
5556
goto_programt::const_targett target,
5657
exprt &expr);
5758

@@ -93,6 +94,7 @@ class goto_program_dereferencet:protected dereference_callbackt
9394
#if 0
9495
const std::set<irep_idt> *valid_local_variables;
9596
#endif
97+
irep_idt current_function;
9698
goto_programt::const_targett current_target;
9799

98100
/// Unused
@@ -106,6 +108,7 @@ class goto_program_dereferencet:protected dereference_callbackt
106108
};
107109

108110
void dereference(
111+
const irep_idt &function_id,
109112
goto_programt::const_targett target,
110113
exprt &expr,
111114
const namespacet &,

0 commit comments

Comments
 (0)