@@ -108,75 +108,34 @@ exprt pointer_logict::pointer_expr(
108108
109109 const exprt &object_expr=objects[pointer.object ];
110110
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 )
122128 {
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 ()));
139132 }
140- else if (src. type (). id ()==ID_struct)
133+ else
141134 {
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 ()));
175138 }
176- else if (src.type ().id ()==ID_union)
177- return src;
178-
179- return src;
180139}
181140
182141pointer_logict::pointer_logict (const namespacet &_ns):ns(_ns)
0 commit comments