@@ -17,10 +17,67 @@ Author: Daniel Kroening, kroening@kroening.com
1717#include < util/rename.h>
1818#include < util/base_type.h>
1919#include < util/std_expr.h>
20+ #include < util/std_code.h>
2021#include < util/byte_operators.h>
2122
2223#include < util/c_types.h>
2324
25+ void goto_symext::havoc_rec (
26+ statet &state,
27+ const guardt &guard,
28+ const exprt &dest)
29+ {
30+ if (dest.id ()==ID_symbol)
31+ {
32+ exprt lhs;
33+
34+ if (guard.is_true ())
35+ lhs=dest;
36+ else
37+ lhs=if_exprt (
38+ guard.as_expr (), dest, exprt (" NULL-object" , dest.type ()));
39+
40+ code_assignt assignment;
41+ assignment.lhs ()=lhs;
42+ assignment.rhs ()=side_effect_expr_nondett (dest.type ());
43+
44+ symex_assign (state, assignment);
45+ }
46+ else if (dest.id ()==ID_byte_extract_little_endian ||
47+ dest.id ()==ID_byte_extract_big_endian)
48+ {
49+ havoc_rec (state, guard, to_byte_extract_expr (dest).op ());
50+ }
51+ else if (dest.id ()==ID_if)
52+ {
53+ const if_exprt &if_expr=to_if_expr (dest);
54+
55+ guardt guard_t =state.guard ;
56+ guard_t .add (if_expr.cond ());
57+ havoc_rec (state, guard_t , if_expr.true_case ());
58+
59+ guardt guard_f=state.guard ;
60+ guard_f.add (not_exprt (if_expr.cond ()));
61+ havoc_rec (state, guard_f, if_expr.false_case ());
62+ }
63+ else if (dest.id ()==ID_typecast)
64+ {
65+ havoc_rec (state, guard, to_typecast_expr (dest).op ());
66+ }
67+ else if (dest.id ()==ID_index)
68+ {
69+ havoc_rec (state, guard, to_index_expr (dest).array ());
70+ }
71+ else if (dest.id ()==ID_member)
72+ {
73+ havoc_rec (state, guard, to_member_expr (dest).struct_op ());
74+ }
75+ else
76+ {
77+ // consider printing a warning
78+ }
79+ }
80+
2481void goto_symext::symex_other (
2582 const goto_functionst &goto_functions,
2683 statet &state)
@@ -213,6 +270,17 @@ void goto_symext::symex_other(
213270 {
214271 target.memory_barrier (state.guard .as_expr (), state.source );
215272 }
273+ else if (statement==ID_havoc_object)
274+ {
275+ DATA_INVARIANT (code.operands ().size ()==1 ,
276+ " havoc_object must have one operand" );
277+
278+ // we need to add dereferencing for the first operand
279+ exprt object=dereference_exprt (code.op0 (), empty_typet ());
280+ clean_expr (object, state, true );
281+
282+ havoc_rec (state, guardt (), object);
283+ }
216284 else
217285 throw " unexpected statement: " +id2string (statement);
218286}
0 commit comments