CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
boolbv_width.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module:
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
9#include "boolbv_width.h"
10
11#include <algorithm>
12
13#include <util/arith_tools.h>
14#include <util/c_types.h>
15#include <util/invariant.h>
16#include <util/namespace.h>
17#include <util/std_types.h>
18
22
24{
25 // check cache first
26
27 std::pair<cachet::iterator, bool> cache_result =
28 cache.emplace(type, entryt{});
29
30 auto &cache_entry = cache_result.first->second;
31
32 if(!cache_result.second) // found!
33 return cache_entry;
34
35 const irep_idt type_id=type.id();
36
38 {
39 const struct_typet::componentst &components=
40 to_struct_type(type).components();
41
42 std::size_t offset=0;
43 defined_entryt entry{0};
44 entry.members.resize(components.size());
45
46 for(std::size_t i=0; i<entry.members.size(); i++)
47 {
48 auto sub_width = get_width_opt(components[i].type());
49 if(!sub_width.has_value())
50 return cache_entry;
51 entry.members[i].offset=offset;
52 entry.members[i].width = *sub_width;
53 offset += *sub_width;
54 }
55
56 entry.total_width=offset;
57
58 cache_entry = std::move(entry);
59 }
60 else if(type_id==ID_union)
61 {
62 const union_typet::componentst &components=
63 to_union_type(type).components();
64
65 defined_entryt entry{0};
66 entry.members.resize(components.size());
67
68 std::size_t max_width=0;
69
70 for(std::size_t i=0; i<entry.members.size(); i++)
71 {
72 auto sub_width = get_width_opt(components[i].type());
73 if(!sub_width.has_value())
74 return cache_entry;
75 entry.members[i].width = *sub_width;
76 max_width = std::max(max_width, *sub_width);
77 }
78
79 entry.total_width=max_width;
80
81 cache_entry = std::move(entry);
82 }
83 else if(type_id==ID_bool)
84 {
86 }
87 else if(type_id==ID_c_bool)
88 {
89 cache_entry = defined_entryt{to_c_bool_type(type).get_width()};
90 }
91 else if(type_id==ID_signedbv)
92 {
93 cache_entry = defined_entryt{to_signedbv_type(type).get_width()};
94 }
95 else if(type_id==ID_unsignedbv)
96 {
98 }
99 else if(type_id==ID_floatbv)
100 {
101 cache_entry = defined_entryt{to_floatbv_type(type).get_width()};
102 }
103 else if(type_id==ID_fixedbv)
104 {
105 cache_entry = defined_entryt{to_fixedbv_type(type).get_width()};
106 }
107 else if(type_id==ID_bv)
108 {
109 cache_entry = defined_entryt{to_bv_type(type).get_width()};
110 }
111 else if(type_id==ID_verilog_signedbv ||
113 {
114 // we encode with two bits
115 std::size_t size = to_bitvector_type(type).get_width();
117 size > 0, "verilog bitvector width shall be greater than zero");
118 cache_entry = defined_entryt{size * 2};
119 }
120 else if(type_id==ID_range)
121 {
124
125 mp_integer size=to-from+1;
126
127 if(size < 0)
128 return cache_entry;
129 else if(size == 0)
131 else
133 }
134 else if(type_id==ID_array)
135 {
137 auto sub_width = get_width_opt(array_type.element_type());
138 if(!sub_width.has_value())
139 return cache_entry;
140
142
143 if(!array_size.has_value() || *array_size < 0)
144 return cache_entry;
145
146 mp_integer total = *array_size * *sub_width;
147 if(total > (1 << 30)) // realistic limit
148 throw analysis_exceptiont("array too large for flattening");
149 else
151 }
152 else if(type_id==ID_complex)
153 {
154 auto sub_width = get_width_opt(to_complex_type(type).subtype());
155 if(!sub_width.has_value())
156 return cache_entry;
159 }
160 else if(type_id==ID_code)
161 {
163 }
164 else if(type_id==ID_enumeration)
165 {
166 // get number of necessary bits
167 std::size_t size=to_enumeration_type(type).elements().size();
168 if(size == 0)
170 else
172 }
173 else if(type_id==ID_c_enum)
174 {
175 // these have a subtype
177 to_bitvector_type(to_c_enum_type(type).underlying_type()).get_width()};
178 CHECK_RETURN(cache_entry->total_width > 0);
179 }
180 else if(type_id==ID_pointer)
181 {
184 }
185 else if(type_id==ID_struct_tag)
186 {
187 cache_entry = get_entry(ns.follow_tag(to_struct_tag_type(type)));
188 }
189 else if(type_id==ID_union_tag)
190 {
191 cache_entry = get_entry(ns.follow_tag(to_union_tag_type(type)));
192 }
193 else if(type_id==ID_c_enum_tag)
194 {
195 cache_entry = get_entry(ns.follow_tag(to_c_enum_tag_type(type)));
196 }
197 else if(type_id==ID_c_bit_field)
198 {
200 }
201 else if(type_id==ID_string)
202 {
204 }
205 else if(type_id == ID_empty)
206 {
208 }
209 else
210 {
212 "boolbv_widtht::get_entry(" + id2string(type_id) + ")");
213 }
214
215 return cache_entry;
216}
217
219 const struct_typet &type,
220 const irep_idt &member) const
221{
222 const auto &entry_opt = get_entry(type);
223 CHECK_RETURN(entry_opt.has_value());
224 std::size_t component_number=type.component_number(member);
225 PRECONDITION(entry_opt->members.size() > component_number);
226
227 return entry_opt->members[component_number];
228}
std::size_t address_bits(const mp_integer &size)
ceil(log2(size))
const bv_typet & to_bv_type(const typet &type)
Cast a typet to a bv_typet.
const fixedbv_typet & to_fixedbv_type(const typet &type)
Cast a typet to a fixedbv_typet.
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
const floatbv_typet & to_floatbv_type(const typet &type)
Cast a typet to a floatbv_typet.
const unsignedbv_typet & to_unsignedbv_type(const typet &type)
Cast a typet to an unsignedbv_typet.
const signedbv_typet & to_signedbv_type(const typet &type)
Cast a typet to a signedbv_typet.
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
const c_enum_typet & to_c_enum_type(const typet &type)
Cast a typet to a c_enum_typet.
Definition c_types.h:335
const c_enum_tag_typet & to_c_enum_tag_type(const typet &type)
Cast a typet to a c_enum_tag_typet.
Definition c_types.h:377
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition c_types.h:184
const c_bool_typet & to_c_bool_type(const typet &type)
Cast a typet to a c_bool_typet.
Definition c_types.h:128
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
Thrown when an unexpected error occurs during the analysis (e.g., when the SAT solver returns an erro...
Arrays with given size.
Definition std_types.h:807
boolbv_widtht(const namespacet &_ns)
const namespacet & ns
const entryt & get_entry(const typet &type) const
std::optional< defined_entryt > entryt
virtual std::optional< std::size_t > get_width_opt(const typet &type) const
const membert & get_member(const struct_typet &type, const irep_idt &member) const
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
const irep_idt & id() const
Definition irep.h:388
const std::string & get_string(const irep_idt &name) const
Definition irep.h:401
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
Structure type, corresponds to C style structs.
Definition std_types.h:231
std::size_t component_number(const irep_idt &component_name) const
Return the sequence number of the component with given name.
Definition std_types.cpp:47
std::vector< componentt > componentst
Definition std_types.h:140
The type of an expression, extends irept.
Definition type.h:29
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
const mp_integer string2integer(const std::string &n, unsigned base)
Definition mp_arith.cpp:54
#define UNIMPLEMENTED_FEATURE(FEATURE)
Definition invariant.h:549
#define CHECK_RETURN(CONDITION)
Definition invariant.h:495
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
#define PRECONDITION(CONDITION)
Definition invariant.h:463
Pre-defined types.
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition std_types.h:308
const enumeration_typet & to_enumeration_type(const typet &type)
Cast a typet to a enumeration_typet.
Definition std_types.h:568
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 complex_typet & to_complex_type(const typet &type)
Cast a typet to a complex_typet.
Definition std_types.h:1158
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888
std::vector< membert > members