@@ -108,75 +108,34 @@ exprt pointer_logict::pointer_expr(
108
108
109
109
const exprt &object_expr=objects[pointer.object ];
110
110
111
- exprt deep_object=object_rec (pointer.offset , type, object_expr);
112
-
113
- return address_of_exprt (deep_object, type);
114
- }
115
-
116
- exprt pointer_logict::object_rec (
117
- const mp_integer &offset,
118
- const typet &pointer_type,
119
- const exprt &src) const
120
- {
121
- if (src.type ().id ()==ID_array)
111
+ typet subtype = type.subtype ();
112
+ // This is a gcc extension.
113
+ // https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
114
+ if (subtype.id () == ID_empty)
115
+ subtype = char_type ();
116
+ exprt deep_object = get_subexpression_at_offset (
117
+ object_expr, pointer.offset , subtype, ID_unknown, ns);
118
+ CHECK_RETURN (deep_object.is_not_nil ());
119
+ if (deep_object.id () != ID_unknown)
120
+ return address_of_exprt (deep_object, type);
121
+
122
+ if (deep_object.op1 ().is_zero ())
123
+ return address_of_exprt (deep_object.op0 (), type);
124
+
125
+ const mp_integer subtype_bytes = pointer_offset_size (subtype, ns);
126
+ CHECK_RETURN (subtype_bytes > 0 );
127
+ if (subtype_bytes > pointer.offset )
122
128
{
123
- mp_integer size=
124
- pointer_offset_size (src.type ().subtype (), ns);
125
-
126
- if (size<=0 )
127
- return src;
128
-
129
- mp_integer index =offset/size;
130
- mp_integer rest=offset%size;
131
- if (rest<0 )
132
- rest=-rest;
133
-
134
- index_exprt tmp (src.type ().subtype ());
135
- tmp.index ()=from_integer (index , typet (ID_integer));
136
- tmp.array ()=src;
137
-
138
- return object_rec (rest, pointer_type, tmp);
129
+ return plus_exprt (
130
+ address_of_exprt (deep_object.op0 (), pointer_type (char_type ())),
131
+ from_integer (pointer.offset , index_type ()));
139
132
}
140
- else if (src. type (). id ()==ID_struct)
133
+ else
141
134
{
142
- const struct_typet::componentst &components=
143
- to_struct_type (src.type ()).components ();
144
-
145
- if (offset<0 )
146
- return src;
147
-
148
- mp_integer current_offset=0 ;
149
-
150
- for (const auto &c : components)
151
- {
152
- assert (offset>=current_offset);
153
-
154
- const typet &subtype=c.type ();
155
-
156
- mp_integer sub_size=pointer_offset_size (subtype, ns);
157
- assert (sub_size>0 );
158
- mp_integer new_offset=current_offset+sub_size;
159
-
160
- if (new_offset>offset)
161
- {
162
- // found it
163
- member_exprt tmp (src, c);
164
-
165
- return object_rec (
166
- offset-current_offset, pointer_type, tmp);
167
- }
168
-
169
- assert (new_offset<=offset);
170
- current_offset=new_offset;
171
- assert (current_offset<=offset);
172
- }
173
-
174
- return src;
135
+ return plus_exprt (
136
+ address_of_exprt (deep_object.op0 (), pointer_type (char_type ())),
137
+ from_integer (pointer.offset / subtype_bytes, index_type ()));
175
138
}
176
- else if (src.type ().id ()==ID_union)
177
- return src;
178
-
179
- return src;
180
139
}
181
140
182
141
pointer_logict::pointer_logict (const namespacet &_ns):ns(_ns)
0 commit comments