Skip to content

Commit 2e2df0d

Browse files
author
kroening
committed
Results of transform for function call and function return must end up as
transforming target state, not source state. git-svn-id: svn+ssh://svn.cprover.org/srv/svn/cbmc/trunk@5783 6afb6bc1-c8e4-404c-8f48-9ae832c5b171
1 parent 9ead3dd commit 2e2df0d

File tree

3 files changed

+54
-26
lines changed

3 files changed

+54
-26
lines changed

src/analyses/ai.cpp

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,9 @@ bool ai_baset::visit(
260260
}
261261
else
262262
{
263+
// initialize state, if necessary
264+
get_state(to_l);
265+
263266
new_values.transform(l, to_l, *this, ns);
264267

265268
if(merge(new_values, l, to_l))
@@ -295,25 +298,48 @@ bool ai_baset::do_function_call(
295298
const exprt::operandst &arguments,
296299
const namespacet &ns)
297300
{
301+
// initialize state, if necessary
302+
get_state(l_return);
303+
298304
const goto_functionst::goto_functiont &goto_function=
299305
f_it->second;
300306

301307
if(!goto_function.body_available)
302-
return false; // do nothing, no change
308+
{
309+
std::unique_ptr<statet> tmp_state(make_temporary_state(get_state(l_call)));
310+
tmp_state->transform(l_call, l_return, *this, ns);
311+
312+
return merge(*tmp_state, l_call, l_return);
313+
}
303314

304315
assert(!goto_function.body.instructions.empty());
305316

306317
{
307318
// get the state at the beginning of the function
308319
locationt l_begin=goto_function.body.instructions.begin();
320+
// initialize state, if necessary
321+
get_state(l_begin);
309322

310323
// do the edge from the call site to the beginning of the function
311-
std::unique_ptr<statet> state(make_temporary_state(get_state(l_call)));
324+
std::unique_ptr<statet> tmp_state(make_temporary_state(get_state(l_call)));
325+
tmp_state->transform(l_call, l_begin, *this, ns);
326+
327+
bool new_data=false;
312328

313-
state->transform(l_call, l_begin, *this, ns);
314-
315329
// merge the new stuff
316-
if(merge(*state, l_call, l_begin))
330+
if(merge(*tmp_state, l_call, l_begin))
331+
new_data=true;
332+
333+
// do each function at least once
334+
if(functions_done.find(f_it->first)==
335+
functions_done.end())
336+
{
337+
new_data=true;
338+
functions_done.insert(f_it->first);
339+
}
340+
341+
// do we need to do the fixedpoint of the body?
342+
if(new_data)
317343
{
318344
// also do the fixedpoint of the body via a recursive call
319345
fixedpoint(goto_function.body, goto_functions, ns);
@@ -326,15 +352,13 @@ bool ai_baset::do_function_call(
326352
assert(l_end->is_end_function());
327353

328354
// do edge from end of function to instruction after call
329-
locationt l_next=l_call;
330-
l_next++;
331-
332-
std::unique_ptr<statet> state(make_temporary_state(get_state(l_end)));
333-
334-
state->transform(l_end, l_next, *this, ns);
355+
std::unique_ptr<statet> tmp_state(make_temporary_state(get_state(l_end)));
356+
tmp_state->transform(l_end, l_return, *this, ns);
335357

336-
// Propagate those -- not exceedingly precise, this is.
337-
return merge(*state, l_end, l_next);
358+
// Propagate those -- not exceedingly precise, this is,
359+
// as still it contains all the state from the
360+
// call site
361+
return merge(*tmp_state, l_end, l_return);
338362
}
339363
}
340364

src/analyses/ai.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,10 @@ class ai_baset
172172
const goto_programt &goto_program,
173173
const goto_functionst &goto_functions,
174174
const namespacet &ns);
175-
176-
static locationt successor(locationt l)
177-
{
178-
l++;
179-
return l;
180-
}
181175

176+
typedef std::set<irep_idt> functions_donet;
177+
functions_donet functions_done;
178+
182179
typedef std::set<irep_idt> recursion_sett;
183180
recursion_sett recursion_set;
184181

src/analyses/static_analysis.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -444,14 +444,15 @@ void static_analysis_baset::do_function_call(
444444
locationt l_begin=goto_function.body.instructions.begin();
445445

446446
// do the edge from the call site to the beginning of the function
447-
new_state.transform(ns, l_call, l_begin);
447+
std::unique_ptr<statet> tmp_state(make_temporary_state(new_state));
448+
tmp_state->transform(ns, l_call, l_begin);
448449

449450
statet &begin_state=get_state(l_begin);
450451

451452
bool new_data=false;
452453

453454
// merge the new stuff
454-
if(merge(begin_state, new_state, l_begin))
455+
if(merge(begin_state, *tmp_state, l_begin))
455456
new_data=true;
456457

457458
// do each function at least once
@@ -479,14 +480,19 @@ void static_analysis_baset::do_function_call(
479480
statet &end_of_function=get_state(l_end);
480481

481482
// do edge from end of function to instruction after call
482-
locationt l_next=l_call;
483-
l_next++;
484-
end_of_function.transform(ns, l_end, l_next);
483+
std::unique_ptr<statet> tmp_state(
484+
make_temporary_state(end_of_function));
485+
tmp_state->transform(ns, l_end, l_return);
485486

486487
// propagate those -- not exceedingly precise, this is,
487488
// as still it contains all the state from the
488489
// call site
489-
merge(new_state, end_of_function, l_end);
490+
merge(new_state, *tmp_state, l_return);
491+
}
492+
493+
{
494+
// effect on current procedure (if any)
495+
new_state.transform(ns, l_call, l_return);
490496
}
491497
}
492498

@@ -585,7 +591,8 @@ void static_analysis_baset::do_function_call_rec(
585591
}
586592
}
587593
}
588-
else if(function.id()=="NULL-object")
594+
else if(function.id()=="NULL-object" ||
595+
function.id()==ID_integer_address)
589596
{
590597
// ignore, can't be a function
591598
}

0 commit comments

Comments
 (0)