Skip to content

Commit e16a10a

Browse files
committed
Switch to evaluating all interpreter expressions forwards, then re-using the results during the backward walk.
1 parent 26a9d70 commit e16a10a

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

src/goto-programs/interpreter.cpp

+21-8
Original file line numberDiff line numberDiff line change
@@ -1759,6 +1759,11 @@ interpretert::input_varst& interpretert::load_counter_example_inputs(
17591759

17601760
// First walk the trace forwards to initialise variable-length arrays
17611761
// whose size-expressions depend on context (e.g. int x = 5; int[] y = new int[x];)
1762+
// We also take the opportunity to save the results of evaluate_address and evaluate
1763+
// such that any non-constant expressions (e.g. the occasional byte_extract(..., i, ...)
1764+
// creeps in that needs the current value of local 'i') will be evaluated correctly.
1765+
1766+
std::vector<std::pair<mp_integer, std::vector<mp_integer> > > trace_eval;
17621767

17631768
for(const auto& step : trace.steps)
17641769
{
@@ -1776,11 +1781,14 @@ interpretert::input_varst& interpretert::load_counter_example_inputs(
17761781
std::vector<mp_integer> rhs;
17771782
evaluate(step.full_lhs_value,rhs);
17781783
assign(address,rhs);
1784+
1785+
trace_eval.push_back(std::make_pair(address, rhs));
17791786
}
17801787
}
17811788

17821789
// Now walk backwards to find object states at their origin points.
1783-
1790+
1791+
auto trace_eval_iter=trace_eval.rbegin();
17841792
goto_tracet::stepst::const_reverse_iterator it=trace.steps.rbegin();
17851793
if(it!=trace.steps.rend()) targetAssert=it->pc;
17861794
for(;it!=trace.steps.rend();++it) {
@@ -1822,18 +1830,19 @@ interpretert::input_varst& interpretert::load_counter_example_inputs(
18221830
} // End if-is-function-call
18231831
else if(is_assign_step(*it))
18241832
{
1825-
1826-
mp_integer address;
18271833

1828-
symbol_exprt symbol_expr=get_assigned_symbol(*it);
1829-
irep_idt id=symbol_expr.get_identifier();
1834+
assert(trace_eval_iter!=trace_eval.rend() &&
1835+
"Assign steps failed to line up between fw and bw passes?");
1836+
const auto& eval_result=*(trace_eval_iter++);
1837+
const auto& address=eval_result.first;
1838+
const auto& rhs=eval_result.second;
18301839

1831-
address=evaluate_address(it->full_lhs);
18321840
assert(address!=0);
1833-
std::vector<mp_integer> rhs;
1834-
evaluate(it->full_lhs_value,rhs);
18351841
assign(address,rhs);
18361842

1843+
symbol_exprt symbol_expr=get_assigned_symbol(*it);
1844+
irep_idt id=symbol_expr.get_identifier();
1845+
18371846
mp_integer whole_lhs_object_address=evaluate_address(symbol_expr);
18381847
// The dynamic type and the static symbol type may differ for VLAs,
18391848
// where the symbol carries a size expression and the dynamic type
@@ -1851,6 +1860,10 @@ interpretert::input_varst& interpretert::load_counter_example_inputs(
18511860

18521861
}
18531862
}
1863+
1864+
assert(trace_eval_iter==trace_eval.rend() &&
1865+
"Backward interpreter walk didn't consume all eval entries?");
1866+
18541867
prune_inputs(inputs,function_inputs,filtered);
18551868
print_inputs();
18561869
show=true;

0 commit comments

Comments
 (0)