|
17 | 17 | #include <util/rename.h>
|
18 | 18 | #include <util/base_type.h>
|
19 | 19 | #include <util/std_expr.h>
|
| 20 | +#include <util/std_code.h> |
20 | 21 | #include <util/byte_operators.h>
|
21 | 22 |
|
22 | 23 | #include <util/c_types.h>
|
23 | 24 |
|
| 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 | + |
24 | 81 | void goto_symext::symex_other(
|
25 | 82 | const goto_functionst &goto_functions,
|
26 | 83 | statet &state)
|
@@ -213,6 +270,17 @@ void goto_symext::symex_other(
|
213 | 270 | {
|
214 | 271 | target.memory_barrier(state.guard.as_expr(), state.source);
|
215 | 272 | }
|
| 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 | + } |
216 | 284 | else
|
217 | 285 | throw "unexpected statement: "+id2string(statement);
|
218 | 286 | }
|
0 commit comments