@@ -17,6 +17,7 @@ Author: Daniel Kroening, kroening@kroening.com
17
17
#include < util/invariant.h>
18
18
#include < util/pointer_offset_size.h>
19
19
#include < util/prefix.h>
20
+ #include < util/simplify_expr.h>
20
21
#include < util/std_expr.h>
21
22
22
23
bool pointer_logict::is_dynamic_object (const exprt &expr) const
@@ -104,29 +105,40 @@ exprt pointer_logict::pointer_expr(
104
105
// https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
105
106
if (subtype.id () == ID_empty)
106
107
subtype = char_type ();
107
- const exprt deep_object =
108
+ exprt deep_object =
108
109
get_subexpression_at_offset (object_expr, pointer.offset , subtype, ns);
109
110
CHECK_RETURN (deep_object.is_not_nil ());
111
+ simplify (deep_object, ns);
110
112
if (deep_object.id () != byte_extract_id ())
111
- return address_of_exprt (deep_object, type);
113
+ return typecast_exprt::conditional_cast (
114
+ address_of_exprt (deep_object), type);
112
115
113
116
const byte_extract_exprt &be = to_byte_extract_expr (deep_object);
117
+ const address_of_exprt base (be.op ());
114
118
if (be.offset ().is_zero ())
115
- return address_of_exprt (be. op () , type);
119
+ return typecast_exprt::conditional_cast (base , type);
116
120
117
- const auto subtype_bytes = pointer_offset_size (subtype, ns);
118
- CHECK_RETURN (subtype_bytes.has_value () && *subtype_bytes > 0 );
119
- if (*subtype_bytes > pointer.offset )
121
+ const auto object_size = pointer_offset_size (be.op ().type (), ns);
122
+ if (object_size.has_value () && *object_size <= 1 )
120
123
{
121
- return plus_exprt (
122
- address_of_exprt (be.op (), pointer_type (char_type ())),
123
- from_integer (pointer.offset , index_type ()));
124
+ return typecast_exprt::conditional_cast (
125
+ plus_exprt (base, from_integer (pointer.offset , pointer_diff_type ())),
126
+ type);
127
+ }
128
+ else if (object_size.has_value () && pointer.offset % *object_size == 0 )
129
+ {
130
+ return typecast_exprt::conditional_cast (
131
+ plus_exprt (
132
+ base, from_integer (pointer.offset / *object_size, pointer_diff_type ())),
133
+ type);
124
134
}
125
135
else
126
136
{
127
- return plus_exprt (
128
- address_of_exprt (be.op (), pointer_type (char_type ())),
129
- from_integer (pointer.offset / *subtype_bytes, index_type ()));
137
+ return typecast_exprt::conditional_cast (
138
+ plus_exprt (
139
+ typecast_exprt (base, pointer_type (char_type ())),
140
+ from_integer (pointer.offset , pointer_diff_type ())),
141
+ type);
130
142
}
131
143
}
132
144
0 commit comments