File tree 3 files changed +24
-3
lines changed
regression/cbmc/double_deref 3 files changed +24
-3
lines changed Original file line number Diff line number Diff line change @@ -20,7 +20,7 @@ result = (derefd_pointer == &o3 ? o3 : derefd_pointer == &o4 ? o4 : derefd_point
20
20
21
21
The tests in this directory check that auxiliary let-expressions like this are only used when appropriate by inspecting formula VCCs:
22
22
double_deref.desc -- a directly nested double-dereference, should not use a let-expression
23
- double_deref_with_cast.desc -- a double-deref with an intervening cast (*(int*)*p for example), should use a let-expression
23
+ double_deref_with_cast.desc -- a double-deref with an intervening cast (*(int*)*p for example), should not use a let-expression
24
24
double_deref_with_member.desc -- a double-deref with an intervening member expression (p->field1->field2), should use a let-expression
25
25
double_deref_with_pointer_arithmetic.desc -- a double-deref with intervening pointer arithmetic (p[idx1][idx2]), should use a let-expression
26
26
*_single_alias.desc -- variants of the above where the first dereference points to a single possible object, so no let-expression is necessary
Original file line number Diff line number Diff line change 1
1
CORE
2
2
double_deref_with_cast.c
3
3
--show-vcc
4
- ^\{-[0-9]+\} derefd_pointer::derefd_pointer!0#1 =
5
- ^\{1\} \(derefd_pointer::derefd_pointer!0#1 = address_of\(symex_dynamic::dynamic_object[1-9]+\) \? main::argc!0@1#1 = [12] : main::argc!0@1#1 = [12]
4
+ \{1\} \(cast\(main::1::pptr!0@1#2, signedbv\[32\]\*\*\) = address_of\(main::1::ptr2!0@1\) \? main::argc!0@1#1 = 2 \: main::argc!0@1#1 = 1\)
6
5
^EXIT=0$
7
6
^SIGNAL=0$
8
7
--
8
+ derefd_pointer::derefd_pointer
9
9
--
10
10
See README for details about these tests
Original file line number Diff line number Diff line change @@ -72,6 +72,27 @@ exprt value_set_dereferencet::dereference(const exprt &pointer)
72
72
exprt false_case = dereference (if_expr.false_case ());
73
73
return if_exprt (if_expr.cond (), true_case, false_case);
74
74
}
75
+ else if (pointer.id () == ID_typecast)
76
+ {
77
+ const exprt *underlying = &pointer;
78
+ // Note this isn't quite the same as skip_typecast, which would also skip
79
+ // things such as int-to-ptr typecasts which we shouldn't ignore
80
+ while (
81
+ underlying->id () == ID_typecast && underlying->type ().id () == ID_pointer)
82
+ {
83
+ underlying = &to_typecast_expr (*underlying).op ();
84
+ }
85
+
86
+ if (underlying->id () == ID_if && underlying->type ().id () == ID_pointer)
87
+ {
88
+ const auto &if_expr = to_if_expr (*underlying);
89
+ return
90
+ if_exprt (
91
+ if_expr.cond (),
92
+ dereference (typecast_exprt (if_expr.true_case (), pointer.type ())),
93
+ dereference (typecast_exprt (if_expr.false_case (), pointer.type ())));
94
+ }
95
+ }
75
96
76
97
// type of the object
77
98
const typet &type=pointer.type ().subtype ();
You can’t perform that action at this time.
0 commit comments