Skip to content

Commit 66133a6

Browse files
committed
Symex: always generate an assumption when truncating a path
Whenever we truncate a particular execution path, whether due to --unwind or --depth settings, we should generate an assumption so that it is not necessary to record the rejected path in the state guard. For example, before if we exceeded the depth limit then we would set the guard to false, and rely on carrying this missing path forwards to any future assume or assert statement. By emitting an assume we explicitly make a constraint ruling this path out, meaning that downstream guards no longer need to carry that information (for example, where before we might have had guard `x` and VCCs `!x => y` and `!x => z`, we can now emit a constraint `!x`, restore the guard to `true` and produce VCCs `y` and `z`). Note this commit does not actually change when the guard is set false and when it is not, as this will have additional performance consequences and should be benchmarked independently.
1 parent ef6005d commit 66133a6

File tree

3 files changed

+16
-6
lines changed

3 files changed

+16
-6
lines changed

src/goto-symex/symex_function_call.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,10 @@ void goto_symext::symex_function_call_code(
258258
if(symex_config.unwinding_assertions)
259259
vcc(false_exprt(), "recursion unwinding assertion", state);
260260

261-
// add to state guard to prevent further assignments
261+
// Rule out this path:
262+
symex_assume_l2(state, false_exprt());
263+
// Disable processing instructions until we next encounter one reachable
264+
// without passing this instruction:
262265
state.guard.add(false_exprt());
263266
}
264267

src/goto-symex/symex_goto.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -795,15 +795,16 @@ void goto_symext::loop_bound_exceeded(
795795
negated_cond,
796796
"unwinding assertion loop " + std::to_string(loop_number),
797797
state);
798+
}
799+
800+
// generate unwinding assumption, unless we permit partial loops
801+
symex_assume_l2(state, negated_cond);
798802

803+
if(symex_config.unwinding_assertions)
804+
{
799805
// add to state guard to prevent further assignments
800806
state.guard.add(negated_cond);
801807
}
802-
else
803-
{
804-
// generate unwinding assumption, unless we permit partial loops
805-
symex_assume_l2(state, negated_cond);
806-
}
807808
}
808809
}
809810

src/goto-symex/symex_main.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,13 @@ void goto_symext::execute_next_instruction(
528528

529529
// depth exceeded?
530530
if(symex_config.max_depth != 0 && state.depth > symex_config.max_depth)
531+
{
532+
// Rule out this path:
533+
symex_assume_l2(state, false_exprt());
534+
// Disable processing instructions until we next encounter one reachable
535+
// without passing this instruction:
531536
state.guard.add(false_exprt());
537+
}
532538
state.depth++;
533539

534540
// actually do instruction

0 commit comments

Comments
 (0)