Skip to content

Commit 087f5ca

Browse files
committed
CSVSA: retain state at top and bottom of functions
This prevents the fixpoint algorithm from ending up in a loop when working over recursive functions -- the top of a function is a control-flow merge point in this case, so it must obviously be retained to determine when the loop should terminate, and the end-of-function state must be retained to prevent a directly recursive function from infinitely analysing the path between a recursive call and its own end. The final state must be set "seen" when it is analysed, as static_analysist does when visiting "normal" states, for this check to take effect.
1 parent f8f51d2 commit 087f5ca

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/pointer-analysis/context_sensitive_value_set_analysis.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ void csvsa_function_contextt::csvsa_visit(locationt l)
6262
{
6363
// Function returns are special-- if anything changed,
6464
// queue all of this context's callsites' successors:
65-
const auto &end_state = (*this)[l];
65+
auto &end_state = (*this)[l];
66+
end_state.set_seen();
67+
6668
std::unique_ptr<const domaint> end_state_without_locals;
6769
for(const auto &caller : callers)
6870
{

src/pointer-analysis/context_sensitive_value_set_analysis.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,19 @@ class csvsa_function_contextt :
381381
callers.insert({caller, callsite});
382382
}
383383

384-
static bool is_virtual_callsite(locationt instruction)
384+
static bool csvsa_must_retain_domain(locationt instruction)
385385
{
386+
// Retain start of function, in case of a recursive edge:
387+
if(instruction->incoming_edges.size() == 0)
388+
return true;
389+
390+
// Retain the END_FUNCTION instruction, to provide a stopping point for
391+
// the otherwise apparently infinite loop of a recursive function whose
392+
// return values propagate to a callsite within its own body.
393+
if(instruction->is_end_function())
394+
return true;
395+
396+
// Retain virtual callsites, for the specialiser to consult later.
386397
return instruction->type == FUNCTION_CALL &&
387398
to_code_function_call(instruction->code).function().id() ==
388399
ID_virtual_function;
@@ -408,7 +419,7 @@ class csvsa_function_contextt :
408419
context_sensitive_value_set_analysis_drivert &driver,
409420
context_indext parent,
410421
const locationt &parent_loc)
411-
: csvsa_value_set_analysist(ns, is_virtual_callsite),
422+
: csvsa_value_set_analysist(ns, csvsa_must_retain_domain),
412423
get_goto_program(get_goto_program),
413424
function_name(function_name),
414425
goto_program(get_goto_program(function_name)),
@@ -431,7 +442,7 @@ class csvsa_function_contextt :
431442
get_goto_programt get_goto_program,
432443
const irep_idt &function_name,
433444
context_sensitive_value_set_analysis_drivert &driver)
434-
: csvsa_value_set_analysist(ns, is_virtual_callsite),
445+
: csvsa_value_set_analysist(ns, csvsa_must_retain_domain),
435446
get_goto_program(get_goto_program),
436447
function_name(function_name),
437448
goto_program(get_goto_program(function_name)),

0 commit comments

Comments
 (0)