|
12 | 12 | #include "pointer_logic.h"
|
13 | 13 |
|
14 | 14 | #include <util/arith_tools.h>
|
| 15 | +#include <util/byte_operators.h> |
15 | 16 | #include <util/c_types.h>
|
16 | 17 | #include <util/invariant.h>
|
17 | 18 | #include <util/pointer_offset_size.h>
|
@@ -98,76 +99,35 @@ exprt pointer_logict::pointer_expr(
|
98 | 99 |
|
99 | 100 | const exprt &object_expr=objects[pointer.object];
|
100 | 101 |
|
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 = |
| 108 | + get_subexpression_at_offset(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) |
112 | 120 | {
|
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())); |
128 | 124 | }
|
129 |
| - else if(src.type().id()==ID_struct) |
| 125 | + else |
130 | 126 | {
|
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())); |
166 | 130 | }
|
167 |
| - else if(src.type().id()==ID_union) |
168 |
| - return src; |
169 |
| - |
170 |
| - return src; |
171 | 131 | }
|
172 | 132 |
|
173 | 133 | pointer_logict::pointer_logict(const namespacet &_ns):ns(_ns)
|
|
0 commit comments