@@ -46,19 +46,19 @@ exprt flow_insensitive_abstract_domain_baset::get_return_lhs(locationt to) const
46
46
return to_code_function_call (to->code ).lhs ();
47
47
}
48
48
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 )
51
51
{
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);
54
55
}
55
56
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 )
58
59
{
59
- initialize (goto_program);
60
- goto_functionst goto_functions;
61
- fixedpoint (goto_program, goto_functions);
60
+ initialize (goto_functions);
61
+ fixedpoint (goto_functions);
62
62
}
63
63
64
64
void flow_insensitive_analysis_baset::output (
@@ -69,14 +69,14 @@ void flow_insensitive_analysis_baset::output(
69
69
{
70
70
out << " ////\n " << " //// Function: " << f_it->first << " \n ////\n\n " ;
71
71
72
- output (f_it->second . body , f_it->first , out);
72
+ output (f_it->first , f_it->second . body , out);
73
73
}
74
74
}
75
75
76
76
void flow_insensitive_analysis_baset::output (
77
- const goto_programt &,
78
77
const irep_idt &,
79
- std::ostream &out) const
78
+ const goto_programt &,
79
+ std::ostream &out)
80
80
{
81
81
get_state ().output (ns, out);
82
82
}
@@ -99,6 +99,7 @@ flow_insensitive_analysis_baset::get_next(
99
99
}
100
100
101
101
bool flow_insensitive_analysis_baset::fixedpoint (
102
+ const irep_idt &function_id,
102
103
const goto_programt &goto_program,
103
104
const goto_functionst &goto_functions)
104
105
{
@@ -119,14 +120,15 @@ bool flow_insensitive_analysis_baset::fixedpoint(
119
120
{
120
121
locationt l=get_next (working_set);
121
122
122
- if (visit (l, working_set, goto_program, goto_functions))
123
+ if (visit (function_id, l, working_set, goto_program, goto_functions))
123
124
new_data=true ;
124
125
}
125
126
126
127
return new_data;
127
128
}
128
129
129
130
bool flow_insensitive_analysis_baset::visit (
131
+ const irep_idt &function_id,
130
132
locationt l,
131
133
working_sett &working_set,
132
134
const goto_programt &goto_program,
@@ -157,16 +159,16 @@ bool flow_insensitive_analysis_baset::visit(
157
159
// this is a big special case
158
160
const code_function_callt &code = to_code_function_call (l->code );
159
161
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);
167
169
}
168
170
else
169
- changed = get_state ().transform (ns, l , to_l);
171
+ changed = get_state ().transform (ns, function_id, l, function_id , to_l);
170
172
171
173
if (changed || !seen (to_l))
172
174
{
@@ -193,6 +195,7 @@ bool flow_insensitive_analysis_baset::visit(
193
195
}
194
196
195
197
bool flow_insensitive_analysis_baset::do_function_call (
198
+ const irep_idt &calling_function,
196
199
locationt l_call,
197
200
const goto_functionst &goto_functions,
198
201
const goto_functionst::function_mapt::const_iterator f_it,
@@ -222,9 +225,15 @@ bool flow_insensitive_analysis_baset::do_function_call(
222
225
t->location_number =1 ;
223
226
224
227
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;
228
237
229
238
return new_data;
230
239
}
@@ -241,7 +250,8 @@ bool flow_insensitive_analysis_baset::do_function_call(
241
250
l_begin->function == f_it->first , " function names have to match" );
242
251
243
252
// 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);
245
255
246
256
// do each function at least once
247
257
if (functions_done.find (f_it->first )==
@@ -255,7 +265,7 @@ bool flow_insensitive_analysis_baset::do_function_call(
255
265
if (new_data)
256
266
{
257
267
// recursive call
258
- fixedpoint (goto_function.body , goto_functions);
268
+ fixedpoint (f_it-> first , goto_function.body , goto_functions);
259
269
new_data=true ; // could be reset by fixedpoint
260
270
}
261
271
}
@@ -269,13 +279,16 @@ bool flow_insensitive_analysis_baset::do_function_call(
269
279
// do edge from end of function to instruction after call
270
280
locationt l_next=l_call;
271
281
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;
273
285
}
274
286
275
287
return new_data;
276
288
}
277
289
278
290
bool flow_insensitive_analysis_baset::do_function_call_rec (
291
+ const irep_idt &calling_function,
279
292
locationt l_call,
280
293
const exprt &function,
281
294
const exprt::operandst &arguments,
@@ -302,13 +315,8 @@ bool flow_insensitive_analysis_baset::do_function_call_rec(
302
315
if (it==goto_functions.function_map .end ())
303
316
throw " failed to find function " +id2string (identifier);
304
317
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);
312
320
313
321
recursion_set.erase (identifier);
314
322
}
@@ -317,12 +325,21 @@ bool flow_insensitive_analysis_baset::do_function_call_rec(
317
325
const auto &if_expr = to_if_expr (function);
318
326
319
327
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);
321
334
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;
326
343
}
327
344
else if (function.id ()==ID_dereference)
328
345
{
@@ -344,13 +361,14 @@ bool flow_insensitive_analysis_baset::do_function_call_rec(
344
361
345
362
if (it!=goto_functions.function_map .end ())
346
363
{
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;
354
372
}
355
373
}
356
374
}
@@ -393,7 +411,7 @@ bool flow_insensitive_analysis_baset::fixedpoint(
393
411
const goto_functionst &goto_functions)
394
412
{
395
413
functions_done.insert (it->first );
396
- return fixedpoint (it->second .body , goto_functions);
414
+ return fixedpoint (it->first , it-> second .body , goto_functions);
397
415
}
398
416
399
417
void flow_insensitive_analysis_baset::update (const goto_functionst &)
0 commit comments