|
12 | 12 |
|
13 | 13 | #include <util/arith_tools.h>
|
14 | 14 | #include <util/byte_operators.h>
|
| 15 | +#include <util/pointer_offset_size.h> |
15 | 16 | #include <util/std_expr.h>
|
16 | 17 | #include <util/throw_with_nested.h>
|
17 | 18 |
|
@@ -78,6 +79,30 @@ bvt boolbvt::convert_byte_extract(const byte_extract_exprt &expr)
|
78 | 79 | if(width==0)
|
79 | 80 | return conversion_failed(expr);
|
80 | 81 |
|
| 82 | + // see if the byte number is constant and within bounds, else work from the |
| 83 | + // root object |
| 84 | + const mp_integer op_bytes = pointer_offset_size(expr.op().type(), ns); |
| 85 | + auto index = numeric_cast<mp_integer>(expr.offset()); |
| 86 | + if( |
| 87 | + (!index.has_value() || (*index < 0 || *index >= op_bytes)) && |
| 88 | + (expr.op().id() == ID_member || expr.op().id() == ID_index || |
| 89 | + expr.op().id() == ID_byte_extract_big_endian || |
| 90 | + expr.op().id() == ID_byte_extract_little_endian)) |
| 91 | + { |
| 92 | + object_descriptor_exprt o; |
| 93 | + o.build(expr.op(), ns); |
| 94 | + CHECK_RETURN(o.offset().id() != ID_unknown); |
| 95 | + if(o.offset().type() != expr.offset().type()) |
| 96 | + o.offset().make_typecast(expr.offset().type()); |
| 97 | + byte_extract_exprt be( |
| 98 | + expr.id(), |
| 99 | + o.root_object(), |
| 100 | + plus_exprt(o.offset(), expr.offset()), |
| 101 | + expr.type()); |
| 102 | + |
| 103 | + return convert_bv(be); |
| 104 | + } |
| 105 | + |
81 | 106 | const exprt &op=expr.op();
|
82 | 107 | const exprt &offset=expr.offset();
|
83 | 108 |
|
@@ -106,13 +131,12 @@ bvt boolbvt::convert_byte_extract(const byte_extract_exprt &expr)
|
106 | 131 | // see if the byte number is constant
|
107 | 132 | unsigned byte_width=8;
|
108 | 133 |
|
109 |
| - mp_integer index; |
110 |
| - if(!to_integer(offset, index)) |
| 134 | + if(index.has_value()) |
111 | 135 | {
|
112 |
| - if(index<0) |
| 136 | + if(*index < 0) |
113 | 137 | throw "byte_extract flatting with negative offset: "+expr.pretty();
|
114 | 138 |
|
115 |
| - mp_integer offset=index*byte_width; |
| 139 | + const mp_integer offset = *index * byte_width; |
116 | 140 |
|
117 | 141 | std::size_t offset_i=integer2unsigned(offset);
|
118 | 142 |
|
|
0 commit comments