CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
boolbv_update.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/c_types.h>
13#include <util/namespace.h>
14
16{
17 const exprt::operandst &ops=expr.operands();
18
19 std::size_t width=boolbv_width(expr.type());
20
21 bvt bv=convert_bv(ops[0]);
22
23 if(bv.size()!=width)
24 throw "update: unexpected operand 0 width";
25
26 // start the recursion
28 expr.op1().operands(), 0, expr.type(), 0, expr.op2(), bv);
29
30 return bv;
31}
32
35 std::size_t d,
36 const typet &type,
37 std::size_t offset,
38 const exprt &new_value,
39 bvt &bv)
40{
41 if(d>=designators.size())
42 {
43 // done
44 bvt new_value_bv=convert_bv(new_value);
45 std::size_t new_value_width=boolbv_width(type);
46
48 throw "convert_update_rec: unexpected new_value size";
49
50 // update
51 for(std::size_t i=0; i<new_value_width; i++)
52 {
53 DATA_INVARIANT(offset + i < bv.size(), "update must be in bounds");
54 bv[offset+i]=new_value_bv[i];
55 }
56
57 return;
58 }
59
60 const exprt &designator=designators[d];
61
62 if(designator.id()==ID_index_designator)
63 {
64 if(type.id()!=ID_array)
65 throw "update: index designator needs array";
66
67 if(designator.operands().size()!=1)
68 throw "update: index designator takes one operand";
69
70 bvt index_bv = convert_bv(to_index_designator(designator).index());
71
73 const typet &subtype = array_type.element_type();
74 const exprt &size_expr = array_type.size();
75
76 std::size_t element_size=boolbv_width(subtype);
77
79 size_expr.is_constant(),
80 "array in update expression should be constant-sized");
81
82 // iterate over array
83 const std::size_t size =
85
86 bvt tmp_bv=bv;
87
88 for(std::size_t i = 0; i != size; ++i)
89 {
90 std::size_t new_offset=offset+i*element_size;
91
93 designators, d+1, subtype, new_offset, new_value, tmp_bv);
94
97
98 for(std::size_t j=0; j<element_size; j++)
99 {
100 std::size_t idx=new_offset+j;
101 DATA_INVARIANT(idx < bv.size(), "index must be in bounds");
102 bv[idx]=prop.lselect(equal, tmp_bv[idx], bv[idx]);
103 }
104 }
105 }
106 else if(designator.id()==ID_member_designator)
107 {
108 const irep_idt &component_name=designator.get(ID_component_name);
109
110 if(type.id() == ID_struct || type.id() == ID_struct_tag)
111 {
113 type.id() == ID_struct_tag ? ns.follow_tag(to_struct_tag_type(type))
114 : to_struct_type(type);
115
116 std::size_t struct_offset=0;
117
119 component.make_nil();
120
121 const struct_typet::componentst &components=
122 struct_type.components();
123
124 for(const auto &c : components)
125 {
126 const typet &subtype = c.type();
127 std::size_t sub_width=boolbv_width(subtype);
128
129 if(c.get_name() == component_name)
130 {
131 component = c;
132 break; // done
133 }
134
136 }
137
138 if(component.is_nil())
139 throw "update: failed to find struct component";
140
141 const typet &new_type = component.type();
142
143 std::size_t new_offset=offset+struct_offset;
144
145 // recursive call
147 designators, d+1, new_type, new_offset, new_value, bv);
148 }
149 else if(type.id() == ID_union || type.id() == ID_union_tag)
150 {
151 const union_typet &union_type = type.id() == ID_union_tag
152 ? ns.follow_tag(to_union_tag_type(type))
153 : to_union_type(type);
154
156 union_type.get_component(component_name);
157
158 if(component.is_nil())
159 throw "update: failed to find union component";
160
161 // this only adjusts the type, the offset stays as-is
162
163 const typet &new_type = component.type();
164
165 // recursive call
167 designators, d+1, new_type, offset, new_value, bv);
168 }
169 else
170 throw "update: member designator needs struct or union";
171 }
172 else
173 throw "update: unexpected designator";
174}
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition c_types.h:184
const union_tag_typet & to_union_tag_type(const typet &type)
Cast a typet to a union_tag_typet.
Definition c_types.h:224
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Arrays with given size.
Definition std_types.h:807
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
void convert_update_rec(const exprt::operandst &designator, std::size_t d, const typet &type, std::size_t offset, const exprt &new_value, bvt &bv)
virtual bvt convert_update(const update_exprt &)
bv_utilst bv_utils
Definition boolbv.h:118
virtual std::size_t boolbv_width(const typet &type) const
Definition boolbv.h:103
static bvt build_constant(const mp_integer &i, std::size_t width)
Definition bv_utils.cpp:14
literalt equal(const bvt &op0, const bvt &op1)
Bit-blasting ID_equal and use in other encodings.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
std::vector< exprt > operandst
Definition expr.h:58
typet & type()
Return the type of the expression.
Definition expr.h:84
operandst & operands()
Definition expr.h:94
const irep_idt & get(const irep_idt &name) const
Definition irep.cpp:44
const irep_idt & id() const
Definition irep.h:388
virtual literalt lselect(literalt a, literalt b, literalt c)=0
Structure type, corresponds to C style structs.
Definition std_types.h:231
std::vector< componentt > componentst
Definition std_types.h:140
exprt & op1()
Definition expr.h:136
exprt & op2()
Definition expr.h:139
The type of an expression, extends irept.
Definition type.h:29
The union type.
Definition c_types.h:147
Operator to update elements in structs and arrays.
Definition std_expr.h:2782
std::vector< literalt > bvt
Definition literal.h:201
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition std_expr.cpp:97
const index_designatort & to_index_designator(const exprt &expr)
Cast an exprt to an index_designatort.
Definition std_expr.h:2713
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition std_expr.h:3172
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition std_types.h:308
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition std_types.h:518
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888