CBMC
Loading...
Searching...
No Matches
std_types.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Pre-defined types
4
5Author: Daniel Kroening, kroening@kroening.com
6 Maria Svorenova, maria.svorenova@diffblue.com
7
8\*******************************************************************/
9
12
13#include "std_types.h"
14
15#include "arith_tools.h"
16#include "c_types.h"
17#include "namespace.h"
18#include "std_expr.h"
19
20void array_typet::check(const typet &type, const validation_modet vm)
21{
22 PRECONDITION(type.id() == ID_array);
24 const array_typet &array_type = static_cast<const array_typet &>(type);
25 if(array_type.size().is_nil())
26 {
28 vm,
29 array_type.size() == nil_exprt{},
30 "nil array size must be exactly nil");
31 }
32}
33
35{
36 // For backwards compatibility, allow the case that the array type is
37 // not annotated with an index type.
38 const auto &annotated_type =
39 static_cast<const typet &>(find(ID_C_index_type));
40 if(annotated_type.is_nil())
41 return c_index_type();
42 else
43 return annotated_type;
44}
45
48 const irep_idt &component_name) const
49{
50 std::size_t number=0;
51
52 for(const auto &c : components())
53 {
54 if(c.get_name() == component_name)
55 return number;
56
57 number++;
58 }
59
61}
62
65 const irep_idt &component_name) const
66{
67 for(const auto &c : components())
68 {
69 if(c.get_name() == component_name)
70 return c;
71 }
72
73 return static_cast<const componentt &>(get_nil_irep());
74}
75
76const typet &
77struct_union_typet::component_type(const irep_idt &component_name) const
78{
79 const auto &c = get_component(component_name);
80 CHECK_RETURN(c.is_not_nil());
81 return c.type();
82}
83
88
93
98
100{
101 bases().push_back(baset(base));
102}
103
104std::optional<struct_typet::baset>
106{
107 for(const auto &b : bases())
108 {
109 if(to_struct_tag_type(b.type()).get_identifier() == id)
110 return b;
111 }
112 return {};
113}
114
120{
121 const componentst &ot_components=other.components();
123
124 if(ot_components.size()<
125 tt_components.size())
126 return false;
127
128 componentst::const_iterator
129 ot_it=ot_components.begin();
130
131 for(const auto &tt_c : tt_components)
132 {
133 if(ot_it->type() != tt_c.type() || ot_it->get_name() != tt_c.get_name())
134 {
135 return false; // they just don't match
136 }
137
138 ot_it++;
139 }
140
141 return true; // ok, *this is a prefix of ot
142}
143
145bool is_reference(const typet &type)
146{
147 return type.id()==ID_pointer &&
149}
150
152bool is_rvalue_reference(const typet &type)
153{
154 return type.id()==ID_pointer &&
156}
157
158std::size_t bitvector_typet::width() const
159{
160 return get_size_t(ID_width);
161}
162
164{
165 set_width(numeric_cast_v<std::size_t>(width));
166}
167
178 const typet &type,
179 const namespacet &ns)
180{
181 // Helper function to avoid the code duplication in the branches
182 // below.
183 const auto has_constant_components = [&ns](const typet &subtype) -> bool {
184 if(subtype.id() == ID_struct || subtype.id() == ID_union)
185 {
186 const auto &struct_union_type = to_struct_union_type(subtype);
187 for(const auto &component : struct_union_type.components())
188 {
190 return true;
191 }
192 }
193 return false;
194 };
195
196 // There are 4 possibilities the code below is handling.
197 // The possibilities are enumerated as comments, to show
198 // what each code is supposed to be handling. For more
199 // comprehensive test case for this, take a look at
200 // regression/cbmc/no_nondet_static/main.c
201
202 // const int a;
203 if(type.get_bool(ID_C_constant))
204 return true;
205
206 // This is a termination condition to break the recursion
207 // for recursive types such as the following:
208 // struct list { const int datum; struct list * next; };
209 // NOTE: the difference between this condition and the previous
210 // one is that this one always returns.
211 if(type.id() == ID_pointer)
212 return type.get_bool(ID_C_constant);
213
214 // When we have a case like the following, we don't immediately
215 // see the struct t. Instead, we only get to see symbol t1, which
216 // we have to use the namespace to resolve to its definition:
217 // struct t { const int a; };
218 // struct t t1;
219 if(type.id() == ID_struct_tag)
220 {
221 const auto &resolved_type = ns.follow_tag(to_struct_tag_type(type));
223 }
224 else if(type.id() == ID_union_tag)
225 {
226 const auto &resolved_type = ns.follow_tag(to_union_tag_type(type));
228 }
229
230 // In a case like this, where we see an array (b[3] here), we know that
231 // the array contains subtypes. We get the first one, and
232 // then resolve it to its definition through the usage of the namespace.
233 // struct contains_constant_pointer { int x; int * const p; };
234 // struct contains_constant_pointer b[3] = { {23, &y}, {23, &y}, {23, &y} };
235 if(type.has_subtype())
236 {
237 const auto &subtype = to_type_with_subtype(type).subtype();
238 return is_constant_or_has_constant_components(subtype, ns);
239 }
240
241 return false;
242}
243
247 constant_exprt _size)
249{
250 index_type_nonconst() = std::move(_index_type);
251 size() = std::move(_size);
252}
253
255{
256 // For backwards compatibility, allow the case that the array type is
257 // not annotated with an index type.
258 const auto &annotated_type =
259 static_cast<const typet &>(find(ID_C_index_type));
260 if(annotated_type.is_nil())
261 return c_index_type();
262 else
263 return annotated_type;
264}
265
267{
268 return static_cast<const constant_exprt &>(find(ID_size));
269}
270
272{
273 return static_cast<constant_exprt &>(add(ID_size));
274}
bitvector_typet c_index_type()
Definition c_types.cpp:16
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:566
Arrays with given size.
Definition std_types.h:806
static void check(const typet &type, const validation_modet vm=validation_modet::INVARIANT)
Definition std_types.cpp:20
typet index_type() const
The type of the index expressions into any instance of this type.
Definition std_types.cpp:34
std::size_t width() const
A constant literal expression.
Definition std_expr.h:3007
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:57
typet & type()
Return the type of the expression.
Definition expr.h:85
bool get_bool(const irep_idt &name) const
Definition irep.cpp:57
std::size_t get_size_t(const irep_idt &name) const
Definition irep.cpp:67
const irept & find(const irep_idt &name) const
Definition irep.cpp:93
const irep_idt & id() const
Definition irep.h:388
irept & add(const irep_idt &name)
Definition irep.cpp:103
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition namespace.cpp:49
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
The NIL expression.
Definition std_expr.h:3144
A struct tag type, i.e., struct_typet with an identifier.
Definition std_types.h:492
Base class or struct that a class or struct inherits from.
Definition std_types.h:251
baset(struct_tag_typet base)
Definition std_types.cpp:94
struct_tag_typet & type()
Definition std_types.cpp:84
Structure type, corresponds to C style structs.
Definition std_types.h:230
const basest & bases() const
Get the collection of base classes/structs.
Definition std_types.h:261
std::optional< baset > get_base(const irep_idt &id) const
Return the base with the given name, if exists.
bool is_prefix_of(const struct_typet &other) const
Returns true if the struct is a prefix of other, i.e., if this struct has n components then the compo...
void add_base(const struct_tag_typet &base)
Add a base class/struct.
Definition std_types.cpp:99
const typet & component_type(const irep_idt &component_name) const
Definition std_types.cpp:77
const componentst & components() const
Definition std_types.h:146
const componentt & get_component(const irep_idt &component_name) const
Get the reference to a component with given name.
Definition std_types.cpp:64
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:139
Type with a single subtype.
Definition type.h:180
static void check(const typet &type, const validation_modet vm=validation_modet::INVARIANT)
Definition type.h:199
The type of an expression, extends irept.
Definition type.h:29
bool has_subtype() const
Definition type.h:64
vector_typet(typet index_type, typet element_type, constant_exprt size)
const constant_exprt & size() const
typet & index_type_nonconst()
The type of any index expression into an instance of this type.
Definition std_types.h:964
typet index_type() const
The type of any index expression into an instance of this type.
const irept & get_nil_irep()
Definition irep.cpp:19
STL namespace.
bool is_reference(const typet &type)
Returns true if the type is a reference.
bool is_rvalue_reference(const typet &type)
Returns if the type is an R value reference.
#define CHECK_RETURN(CONDITION)
Definition invariant.h:495
#define UNREACHABLE
This should be used to mark dead code.
Definition invariant.h:525
#define PRECONDITION(CONDITION)
Definition invariant.h:463
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
Definition std_expr.cpp:291
API to expression classes.
Pre-defined types.
bool is_constant_or_has_constant_components(const typet &type, const namespacet &ns)
Identify whether a given type is constant itself or contains constant components.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition std_types.h:517
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
Definition std_types.h:213
const type_with_subtypet & to_type_with_subtype(const typet &type)
Definition type.h:208
#define DATA_CHECK(vm, condition, message)
This macro takes a condition which denotes a well-formedness criterion on goto programs,...
Definition validate.h:22
validation_modet