CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
boolbv_byte_extract.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#include "boolbv.h"
10
11#include <util/arith_tools.h>
12#include <util/byte_operators.h>
13#include <util/pointer_expr.h>
15#include <util/std_expr.h>
16
17bvt map_bv(const endianness_mapt &map, const bvt &src)
18{
19 PRECONDITION(map.number_of_bits() == src.size());
20 bvt result;
21 result.reserve(src.size());
22
23 for(std::size_t i=0; i<src.size(); i++)
24 {
25 const size_t mapped_index = map.map_bit(i);
26 CHECK_RETURN(mapped_index < src.size());
27 result.push_back(src[mapped_index]);
28 }
29
30 return result;
31}
32
34{
35 // array logic does not handle byte operators, thus lower when operating on
36 // unbounded arrays
37 if(is_unbounded_array(expr.op().type()))
38 {
39 return convert_bv(lower_byte_extract(expr, ns));
40 }
41
42 const std::size_t width = boolbv_width(expr.type());
43
44 // special treatment for bit-fields and big-endian:
45 // we need byte granularity
46 #if 0
47 if(expr.id()==ID_byte_extract_big_endian &&
48 expr.type().id()==ID_c_bit_field &&
49 (width%expr.get_bits_per_byte())!=0)
50 {
52 // round up
53 to_c_bit_field_type(tmp.type()).set_width(
54 width+expr.get_bits_per_byte()-width%expr.get_bits_per_byte());
56 bv.resize(width); // chop down
57 return;
58 }
59 #endif
60
61 // see if the byte number is constant and within bounds, else work from the
62 // root object
63 const auto op_bytes_opt = pointer_offset_size(expr.op().type(), ns);
64 auto index = numeric_cast<mp_integer>(expr.offset());
65
66 if(
67 (!index.has_value() || !op_bytes_opt.has_value() ||
69 (expr.op().id() == ID_member ||
70 expr.op().id() == ID_index ||
71 expr.op().id() == ID_byte_extract_big_endian ||
73 {
75 o.build(expr.op(), ns);
77
78 o.offset() =
80
82 expr.id(),
83 o.root_object(),
84 plus_exprt(o.offset(), expr.offset()),
85 expr.get_bits_per_byte(),
86 expr.type());
87
88 return convert_bv(be);
89 }
90
91 const exprt &op=expr.op();
95 const bool little_endian = expr.id() == ID_byte_extract_little_endian;
96
97 // first do op0
98 const endianness_mapt op_map = endianness_map(op.type(), little_endian);
99 const bvt op_bv=map_bv(op_map, convert_bv(op));
100
101 // do result
102 endianness_mapt result_map = endianness_map(expr.type(), little_endian);
103 bvt bv;
104 bv.resize(width);
105
106 // see if the byte number is constant
107 if(index.has_value())
108 {
109 const mp_integer offset = *index * expr.get_bits_per_byte();
110
111 for(std::size_t i=0; i<width; i++)
112 // out of bounds?
113 if(offset + i < 0 || offset + i >= op_bv.size())
114 bv[i]=prop.new_variable();
115 else
116 bv[i] = op_bv[numeric_cast_v<std::size_t>(offset + i)];
117 }
118 else
119 {
120 std::size_t bytes = op_bv.size() / expr.get_bits_per_byte();
121
122 if(prop.has_set_to())
123 {
124 // free variables
125 bv = prop.new_variables(width);
126
127 // add implications
128
129 // type of index operand
130 const typet &constant_type = expr.offset().type();
131
133 equal_bv.resize(width);
134
135 for(std::size_t i=0; i<bytes; i++)
136 {
137 std::size_t offset = i * expr.get_bits_per_byte();
138
139 for(std::size_t j=0; j<width; j++)
140 if(offset+j<op_bv.size())
141 equal_bv[j]=prop.lequal(bv[j], op_bv[offset+j]);
142 else
143 equal_bv[j]=const_literal(true);
144
147 prop.land(equal_bv)));
148 }
149 }
150 else
151 {
152 // type of index operand
153 const typet &constant_type = expr.offset().type();
154
155 for(std::size_t i=0; i<bytes; i++)
156 {
157 literalt e =
159
160 std::size_t offset = i * expr.get_bits_per_byte();
161
162 for(std::size_t j=0; j<width; j++)
163 {
164 literalt l;
165
166 if(offset+j<op_bv.size())
167 l=op_bv[offset+j];
168 else
169 l=const_literal(false);
170
171 if(i==0)
172 bv[j]=l;
173 else
174 bv[j]=prop.lselect(e, l, bv[j]);
175 }
176 }
177 }
178 }
179
180 // shuffle the result
181 bv=map_bv(result_map, bv);
182
183 return bv;
184}
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
bvt map_bv(const endianness_mapt &map, const bvt &src)
Expression classes for byte-level operators.
exprt lower_byte_extract(const byte_extract_exprt &src, const namespacet &ns)
Rewrite a byte extract expression to more fundamental operations.
const c_bit_field_typet & to_c_bit_field_type(const typet &type)
Cast a typet to a c_bit_field_typet.
Definition c_types.h:80
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
const namespacet & ns
Definition arrays.h:56
virtual const bvt & convert_bv(const exprt &expr, const std::optional< std::size_t > expected_width={})
Convert expression to vector of literalts, using an internal cache to speed up conversion if availabl...
Definition boolbv.cpp:39
virtual bvt convert_byte_extract(const byte_extract_exprt &expr)
bool is_unbounded_array(const typet &type) const override
Definition boolbv.cpp:538
virtual endianness_mapt endianness_map(const typet &type, bool little_endian) const
Definition boolbv.h:109
virtual std::size_t boolbv_width(const typet &type) const
Definition boolbv.h:103
Expression of type type extracted from some object op starting at position offset (given in number of...
std::size_t get_bits_per_byte() const
Maps a big-endian offset to a little-endian offset.
size_t number_of_bits() const
size_t map_bit(size_t bit) const
Equality.
Definition std_expr.h:1366
Base class for all expressions.
Definition expr.h:56
typet & type()
Return the type of the expression.
Definition expr.h:84
const irep_idt & id() const
Definition irep.h:388
Split an expression into a base object and a (byte) offset.
void build(const exprt &expr, const namespacet &ns)
Given an expression expr, attempt to find the underlying object it represents by skipping over type c...
static const exprt & root_object(const exprt &expr)
The plus expression Associativity is not specified.
Definition std_expr.h:1002
literalt convert(const exprt &expr) override
Convert a Boolean expression and return the corresponding literal.
void l_set_to_true(literalt a)
Definition prop.h:52
virtual literalt land(literalt a, literalt b)=0
virtual literalt limplies(literalt a, literalt b)=0
virtual literalt lselect(literalt a, literalt b, literalt c)=0
virtual bvt new_variables(std::size_t width)
generates a bitvector of given width with new variables
Definition prop.cpp:30
virtual literalt new_variable()=0
virtual literalt lequal(literalt a, literalt b)=0
virtual bool has_set_to() const
Definition prop.h:81
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition std_expr.h:2081
The type of an expression, extends irept.
Definition type.h:29
std::vector< literalt > bvt
Definition literal.h:201
literalt const_literal(bool value)
Definition literal.h:188
API to expression classes for Pointers.
std::optional< mp_integer > pointer_offset_size(const typet &type, const namespacet &ns)
Compute the size of a type in bytes, rounding up to full bytes.
Pointer Logic.
BigInt mp_integer
Definition smt_terms.h:17
#define CHECK_RETURN(CONDITION)
Definition invariant.h:495
#define PRECONDITION(CONDITION)
Definition invariant.h:463
API to expression classes.