@@ -12,6 +12,7 @@ Author: Daniel Kroening, kroening@kroening.com
1212#include " pointer_logic.h"
1313
1414#include < util/arith_tools.h>
15+ #include < util/byte_operators.h>
1516#include < util/c_types.h>
1617#include < util/invariant.h>
1718#include < util/pointer_offset_size.h>
@@ -98,76 +99,35 @@ exprt pointer_logict::pointer_expr(
9899
99100 const exprt &object_expr=objects[pointer.object ];
100101
101- exprt deep_object=object_rec (pointer.offset , type, object_expr);
102-
103- return address_of_exprt (deep_object, type);
104- }
105-
106- exprt pointer_logict::object_rec (
107- const mp_integer &offset,
108- const typet &pointer_type,
109- const exprt &src) const
110- {
111- if (src.type ().id ()==ID_array)
102+ typet subtype = type.subtype ();
103+ // This is a gcc extension.
104+ // https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
105+ if (subtype.id () == ID_empty)
106+ subtype = char_type ();
107+ const exprt deep_object = get_subexpression_at_offset (
108+ object_expr, pointer.offset , subtype, ns);
109+ CHECK_RETURN (deep_object.is_not_nil ());
110+ if (deep_object.id () != byte_extract_id ())
111+ return address_of_exprt (deep_object, type);
112+
113+ const byte_extract_exprt &be = to_byte_extract_expr (deep_object);
114+ if (be.offset ().is_zero ())
115+ return address_of_exprt (be.op (), type);
116+
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 )
112120 {
113- auto size = pointer_offset_size (src.type ().subtype (), ns);
114-
115- if (!size.has_value () || *size == 0 )
116- return src;
117-
118- mp_integer index = offset / (*size);
119- mp_integer rest = offset % (*size);
120- if (rest<0 )
121- rest=-rest;
122-
123- index_exprt tmp (src.type ().subtype ());
124- tmp.index ()=from_integer (index, typet (ID_integer));
125- tmp.array ()=src;
126-
127- return object_rec (rest, pointer_type, tmp);
121+ return plus_exprt (
122+ address_of_exprt (be.op (), pointer_type (char_type ())),
123+ from_integer (pointer.offset , index_type ()));
128124 }
129- else if (src. type (). id ()==ID_struct)
125+ else
130126 {
131- const struct_typet::componentst &components=
132- to_struct_type (src.type ()).components ();
133-
134- if (offset<0 )
135- return src;
136-
137- mp_integer current_offset=0 ;
138-
139- for (const auto &c : components)
140- {
141- INVARIANT (
142- offset >= current_offset,
143- " when the object has not been found yet its offset must not be smaller"
144- " than the offset of the current struct component" );
145-
146- const typet &subtype=c.type ();
147-
148- const auto sub_size = pointer_offset_size (subtype, ns);
149- CHECK_RETURN (sub_size.has_value () && *sub_size != 0 );
150-
151- mp_integer new_offset = current_offset + *sub_size;
152-
153- if (new_offset>offset)
154- {
155- // found it
156- member_exprt tmp (src, c);
157-
158- return object_rec (
159- offset-current_offset, pointer_type, tmp);
160- }
161-
162- current_offset=new_offset;
163- }
164-
165- return src;
127+ return plus_exprt (
128+ address_of_exprt (be.op (), pointer_type (char_type ())),
129+ from_integer (pointer.offset / *subtype_bytes, index_type ()));
166130 }
167- else if (src.type ().id ()==ID_union)
168- return src;
169-
170- return src;
171131}
172132
173133pointer_logict::pointer_logict (const namespacet &_ns):ns(_ns)
0 commit comments