@@ -1759,6 +1759,11 @@ interpretert::input_varst& interpretert::load_counter_example_inputs(
1759
1759
1760
1760
// First walk the trace forwards to initialise variable-length arrays
1761
1761
// 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;
1762
1767
1763
1768
for (const auto & step : trace.steps )
1764
1769
{
@@ -1776,11 +1781,14 @@ interpretert::input_varst& interpretert::load_counter_example_inputs(
1776
1781
std::vector<mp_integer> rhs;
1777
1782
evaluate (step.full_lhs_value ,rhs);
1778
1783
assign (address,rhs);
1784
+
1785
+ trace_eval.push_back (std::make_pair (address, rhs));
1779
1786
}
1780
1787
}
1781
1788
1782
1789
// Now walk backwards to find object states at their origin points.
1783
-
1790
+
1791
+ auto trace_eval_iter=trace_eval.rbegin ();
1784
1792
goto_tracet::stepst::const_reverse_iterator it=trace.steps .rbegin ();
1785
1793
if (it!=trace.steps .rend ()) targetAssert=it->pc ;
1786
1794
for (;it!=trace.steps .rend ();++it) {
@@ -1822,18 +1830,19 @@ interpretert::input_varst& interpretert::load_counter_example_inputs(
1822
1830
} // End if-is-function-call
1823
1831
else if (is_assign_step (*it))
1824
1832
{
1825
-
1826
- mp_integer address;
1827
1833
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 ;
1830
1839
1831
- address=evaluate_address (it->full_lhs );
1832
1840
assert (address!=0 );
1833
- std::vector<mp_integer> rhs;
1834
- evaluate (it->full_lhs_value ,rhs);
1835
1841
assign (address,rhs);
1836
1842
1843
+ symbol_exprt symbol_expr=get_assigned_symbol (*it);
1844
+ irep_idt id=symbol_expr.get_identifier ();
1845
+
1837
1846
mp_integer whole_lhs_object_address=evaluate_address (symbol_expr);
1838
1847
// The dynamic type and the static symbol type may differ for VLAs,
1839
1848
// where the symbol carries a size expression and the dynamic type
@@ -1851,6 +1860,10 @@ interpretert::input_varst& interpretert::load_counter_example_inputs(
1851
1860
1852
1861
}
1853
1862
}
1863
+
1864
+ assert (trace_eval_iter==trace_eval.rend () &&
1865
+ " Backward interpreter walk didn't consume all eval entries?" );
1866
+
1854
1867
prune_inputs (inputs,function_inputs,filtered);
1855
1868
print_inputs ();
1856
1869
show=true ;
0 commit comments