|
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