CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
pointer_logic.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Pointer Logic
4
5Author: Daniel Kroening, kroening@kroening.com
6
7\*******************************************************************/
8
11
12#include "pointer_logic.h"
13
14#include <util/arith_tools.h>
15#include <util/byte_operators.h>
16#include <util/c_types.h>
17#include <util/invariant.h>
18#include <util/pointer_expr.h>
21#include <util/prefix.h>
22#include <util/simplify_expr.h>
23#include <util/std_expr.h>
24
26{
27 return expr.type().get_bool(ID_C_dynamic) ||
28 (expr.id() == ID_symbol &&
30 id2string(to_symbol_expr(expr).get_identifier()),
32}
33
34void pointer_logict::get_dynamic_objects(std::vector<mp_integer> &o) const
35{
36 o.clear();
37 mp_integer nr = 0;
38
39 for(auto it = objects.cbegin(); it != objects.cend(); ++it, ++nr)
40 if(is_dynamic_object(*it))
41 o.push_back(nr);
42}
43
45{
46 // remove any index/member
47
48 if(expr.id()==ID_index)
49 {
50 return add_object(to_index_expr(expr).array());
51 }
52 else if(expr.id()==ID_member)
53 {
54 return add_object(to_member_expr(expr).compound());
55 }
56
57 return objects.number(expr);
58}
59
61 const mp_integer &object,
62 const pointer_typet &type) const
63{
64 return pointer_expr({object, 0}, type);
65}
66
68 const pointert &pointer,
69 const pointer_typet &type) const
70{
71 if(pointer.object==null_object) // NULL?
72 {
73 if(pointer.offset==0)
74 {
75 return null_pointer_exprt(type);
76 }
77 else
78 {
80 return plus_exprt(null,
82 }
83 }
84 else if(pointer.object==invalid_object) // INVALID?
85 {
86 return constant_exprt("INVALID", type);
87 }
88
89 if(pointer.object>=objects.size())
90 {
91 return constant_exprt("INVALID-" + integer2string(pointer.object), type);
92 }
93
94 const exprt &object_expr =
96
97 typet subtype = type.base_type();
98 // In a counterexample we may up with void pointers with an offset; handle
99 // this just like GCC does and treat them as char pointers:
100 // https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
101 if(subtype.id() == ID_empty)
102 subtype = char_type();
103 if(object_expr.id() == ID_string_constant)
104 {
105 subtype = object_expr.type();
106
107 // a string constant must be array-typed with fixed size
108 const array_typet &array_type = to_array_type(object_expr.type());
111 if(array_size > pointer.offset)
112 {
113 to_array_type(subtype).size() =
114 from_integer(array_size - pointer.offset, array_type.size().type());
115 }
116 }
117 auto deep_object_opt =
118 get_subexpression_at_offset(object_expr, pointer.offset, subtype, ns);
119 CHECK_RETURN(deep_object_opt.has_value());
122 if(
125 {
128 }
129
131 const address_of_exprt base(be.op());
132 if(be.offset().is_zero())
133 return typecast_exprt::conditional_cast(base, type);
134
135 const auto object_size = pointer_offset_size(be.op().type(), ns);
136 if(object_size.has_value() && *object_size <= 1)
137 {
140 type);
141 }
142 else if(object_size.has_value() && pointer.offset % *object_size == 0)
143 {
146 base, from_integer(pointer.offset / *object_size, pointer_diff_type())),
147 type);
148 }
149 else
150 {
155 type);
156 }
157}
158
160{
161 // add NULL
164
165 // add INVALID
167}
168
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Expression classes for byte-level operators.
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
pointer_typet pointer_type(const typet &subtype)
Definition c_types.cpp:235
signedbv_typet pointer_diff_type()
Definition c_types.cpp:220
bitvector_typet char_type()
Definition c_types.cpp:106
Operator to return the address of an object.
virtual void clear()
Reset the abstract state.
Definition ai.h:265
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
Expression of type type extracted from some object op starting at position offset (given in number of...
A constant literal expression.
Definition std_expr.h:3117
Base class for all expressions.
Definition expr.h:56
typet & type()
Return the type of the expression.
Definition expr.h:84
bool get_bool(const irep_idt &name) const
Definition irep.cpp:57
const irep_idt & id() const
Definition irep.h:388
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
The null pointer constant.
number_type number(const key_type &a)
Definition numbering.h:37
const_iterator cend() const
Definition numbering.h:106
size_type size() const
Definition numbering.h:66
const_iterator cbegin() const
Definition numbering.h:93
The plus expression Associativity is not specified.
Definition std_expr.h:1002
mp_integer invalid_object
numberingt< exprt, irep_hash > objects
exprt pointer_expr(const pointert &pointer, const pointer_typet &type) const
Convert an (object,offset) pair to an expression.
mp_integer null_object
void get_dynamic_objects(std::vector< mp_integer > &objects) const
mp_integer add_object(const exprt &expr)
const namespacet & ns
bool is_dynamic_object(const exprt &expr) const
pointer_logict(const namespacet &_ns)
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
const typet & base_type() const
The type of the data what we point to.
Semantic type conversion.
Definition std_expr.h:2073
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
bool has_prefix(const std::string &s, const std::string &prefix)
Definition converter.cpp:13
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
const std::string integer2string(const mp_integer &n, unsigned base)
Definition mp_arith.cpp:103
API to expression classes for Pointers.
Pointer Logic.
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.
std::optional< exprt > get_subexpression_at_offset(const exprt &expr, const mp_integer &offset_bytes, const typet &target_type_raw, const namespacet &ns)
Pointer Logic.
exprt object_size(const exprt &pointer)
Various predicates over pointers in programs.
#define SYMEX_DYNAMIC_PREFIX
bool simplify(exprt &expr, const namespacet &ns)
BigInt mp_integer
Definition smt_terms.h:17
#define CHECK_RETURN(CONDITION)
Definition invariant.h:495
API to expression classes.
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition std_expr.h:1538
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition std_expr.h:3063
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition std_expr.h:3172
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:272
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888