CBMC
pointer_expr.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: API to expression classes for Pointers
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "pointer_expr.h"
10 
11 #include "arith_tools.h"
12 #include "byte_operators.h"
13 #include "c_types.h"
14 #include "expr_util.h"
15 #include "pointer_offset_size.h"
16 #include "pointer_predicates.h"
17 #include "simplify_expr.h"
18 
19 void dynamic_object_exprt::set_instance(unsigned int instance)
20 {
21  op0() = from_integer(instance, typet(ID_natural));
22 }
23 
25 {
26  return std::stoul(id2string(to_constant_expr(op0()).get_value()));
27 }
28 
31  const namespacet &ns,
32  const exprt &expr,
34 {
35  if(expr.id() == ID_index)
36  {
37  const index_exprt &index = to_index_expr(expr);
38 
39  build_object_descriptor_rec(ns, index.array(), dest);
40 
41  auto sub_size = size_of_expr(expr.type(), ns);
42 
43  if(sub_size.has_value())
44  {
45  dest.offset() = plus_exprt(
46  dest.offset(),
47  mult_exprt(
49  typecast_exprt::conditional_cast(sub_size.value(), c_index_type())));
50  }
51  else
52  {
53  dest.offset() = exprt(ID_unknown);
54  }
55  }
56  else if(expr.id() == ID_member)
57  {
58  const member_exprt &member = to_member_expr(expr);
59  const exprt &struct_op = member.struct_op();
60 
61  build_object_descriptor_rec(ns, struct_op, dest);
62 
63  auto offset = member_offset_expr(member, ns);
64  CHECK_RETURN(offset.has_value());
65 
66  dest.offset() = plus_exprt(
67  dest.offset(),
69  }
70  else if(
71  expr.id() == ID_byte_extract_little_endian ||
72  expr.id() == ID_byte_extract_big_endian)
73  {
74  const byte_extract_exprt &be = to_byte_extract_expr(expr);
75 
76  dest.object() = be.op();
77 
78  build_object_descriptor_rec(ns, be.op(), dest);
79 
80  dest.offset() = plus_exprt(
81  dest.offset(),
83  to_byte_extract_expr(expr).offset(), c_index_type()));
84  }
85  else if(expr.id() == ID_typecast)
86  {
87  const typecast_exprt &tc = to_typecast_expr(expr);
88 
89  dest.object() = tc.op();
90 
91  build_object_descriptor_rec(ns, tc.op(), dest);
92  }
93  else if(const auto deref = expr_try_dynamic_cast<dereference_exprt>(expr))
94  {
95  const exprt &pointer = skip_typecast(deref->pointer());
96  if(const auto address_of = expr_try_dynamic_cast<address_of_exprt>(pointer))
97  {
98  dest.object() = address_of->object();
99  build_object_descriptor_rec(ns, address_of->object(), dest);
100  }
101  }
102  else if(const auto address_of = expr_try_dynamic_cast<address_of_exprt>(expr))
103  {
104  const exprt &object = skip_typecast(address_of->object());
105  if(const auto deref = expr_try_dynamic_cast<dereference_exprt>(object))
106  {
107  dest.object() = deref->pointer();
108  build_object_descriptor_rec(ns, deref->pointer(), dest);
109  }
110  }
111 }
112 
114 void object_descriptor_exprt::build(const exprt &expr, const namespacet &ns)
115 {
116  PRECONDITION(object().id() == ID_unknown);
117  object() = expr;
118 
119  if(offset().id() == ID_unknown)
120  offset() = from_integer(0, c_index_type());
121 
122  build_object_descriptor_rec(ns, expr, *this);
123  simplify(offset(), ns);
124 }
125 
127  : unary_exprt(ID_address_of, _op, pointer_type(_op.type()))
128 {
129 }
130 
132  : object_address_exprt(object, pointer_type(object.type()))
133 {
134 }
135 
137  const symbol_exprt &object,
138  pointer_typet type)
139  : nullary_exprt(ID_object_address, std::move(type))
140 {
141  set(ID_identifier, object.get_identifier());
142 }
143 
145 {
146  return symbol_exprt(object_identifier(), to_pointer_type(type()).base_type());
147 }
148 
150  exprt compound_ptr,
151  const irep_idt &component_name,
152  pointer_typet _type)
153  : unary_exprt(ID_field_address, std::move(compound_ptr), std::move(_type))
154 {
155  const auto &base_type = field_address_exprt::base().type();
156  PRECONDITION(base_type.id() == ID_pointer);
157  const auto &compound_type = to_pointer_type(base_type).base_type();
158  PRECONDITION(
159  compound_type.id() == ID_struct || compound_type.id() == ID_struct_tag ||
160  compound_type.id() == ID_union || compound_type.id() == ID_union_tag);
161  set(ID_component_name, component_name);
162 }
163 
166  base,
167  std::move(index),
169  to_pointer_type(base.type()).base_type(),
170  to_pointer_type(base.type()).get_width()))
171 {
172 }
173 
175  exprt base,
176  exprt index,
177  pointer_typet type)
178  : binary_exprt(
179  std::move(base),
180  ID_element_address,
181  std::move(index),
182  std::move(type))
183 {
184 }
185 
187 {
188  const exprt *p = &expr;
189 
190  while(true)
191  {
192  if(p->id() == ID_member)
193  p = &to_member_expr(*p).compound();
194  else if(p->id() == ID_index)
195  p = &to_index_expr(*p).array();
196  else
197  break;
198  }
199 
200  return *p;
201 }
202 
211  const exprt &expr,
212  const namespacet &ns,
213  const validation_modet vm)
214 {
215  check(expr, vm);
216 
217  const auto &dereference_expr = to_dereference_expr(expr);
218 
219  const typet &type_of_operand = dereference_expr.pointer().type();
220 
221  const pointer_typet *pointer_type =
222  type_try_dynamic_cast<pointer_typet>(type_of_operand);
223 
224  DATA_CHECK(
225  vm,
226  pointer_type,
227  "dereference expression's operand must have a pointer type");
228 
229  DATA_CHECK(
230  vm,
231  dereference_expr.type() == pointer_type->base_type(),
232  "dereference expression's type must match the base type of the type of its "
233  "operand");
234 }
235 
237 {
238  return and_exprt(
239  {same_object(op0(), op1()),
240  same_object(op1(), op2()),
241  r_ok_exprt(
245  pointer_offset(op1()), ID_le, pointer_offset(op2()))});
246 }
247 
249 {
250  return and_exprt{
257 }
258 
260 {
261  return and_exprt{
262  {same_object(op0(), op1()),
263  same_object(op1(), op2()),
265  op0(),
267  deallocated_ptr(),
268  dead_ptr())
269  .lower(ns),
272  pointer_offset(op1()), ID_le, pointer_offset(op2()))}};
273 }
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
bitvector_typet c_index_type()
Definition: c_types.cpp:16
address_of_exprt(const exprt &op)
Boolean AND.
Definition: std_expr.h:2125
A base class for binary expressions.
Definition: std_expr.h:638
exprt & op0()
Definition: expr.h:133
A base class for relations, i.e., binary predicates whose two operands have the same type.
Definition: std_expr.h:762
Expression of type type extracted from some object op starting at position offset (given in number of...
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
Definition: pointer_expr.h:857
static void validate(const exprt &expr, const namespacet &ns, const validation_modet vm=validation_modet::INVARIANT)
Check that the dereference expression has the right number of operands, refers to something with a po...
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
unsigned int get_instance() const
void set_instance(unsigned int instance)
Operator to return the address of an array element relative to a base address.
Definition: pointer_expr.h:748
element_address_exprt(const exprt &base, exprt index)
constructor for element addresses.
exprt & op1()
Definition: expr.h:136
exprt & op2()
Definition: expr.h:139
exprt & op0()
Definition: expr.h:133
Base class for all expressions.
Definition: expr.h:56
typet & type()
Return the type of the expression.
Definition: expr.h:84
const typet & compound_type() const
Definition: pointer_expr.h:699
const irep_idt & component_name() const
Definition: pointer_expr.h:704
field_address_exprt(exprt base, const irep_idt &component_name, pointer_typet type)
constructor for field addresses.
Array index operator.
Definition: std_expr.h:1470
exprt & array()
Definition: std_expr.h:1500
exprt & index()
Definition: std_expr.h:1510
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:412
const irep_idt & id() const
Definition: irep.h:388
Extract member of struct or union.
Definition: std_expr.h:2849
const exprt & compound() const
Definition: std_expr.h:2898
const exprt & struct_op() const
Definition: std_expr.h:2887
Binary minus.
Definition: std_expr.h:1061
Binary multiplication Associativity is not specified.
Definition: std_expr.h:1107
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
The NIL expression.
Definition: std_expr.h:3086
Boolean negation.
Definition: std_expr.h:2332
An expression without operands.
Definition: std_expr.h:22
Operator to return the address of an object.
Definition: pointer_expr.h:596
symbol_exprt object_expr() const
const pointer_typet & type() const
Definition: pointer_expr.h:607
irep_idt object_identifier() const
Definition: pointer_expr.h:602
object_address_exprt(const symbol_exprt &)
Split an expression into a base object and a (byte) offset.
Definition: pointer_expr.h:181
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...
const exprt & root_object() const
Definition: pointer_expr.h:218
The plus expression Associativity is not specified.
Definition: std_expr.h:1002
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:24
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
const exprt & dead_ptr() const
Definition: pointer_expr.h:495
const exprt & deallocated_ptr() const
Definition: pointer_expr.h:490
exprt lower(const namespacet &ns) const
A predicate that indicates that an address range is ok to read.
const exprt & dead_ptr() const
exprt lower(const namespacet &ns) const
Lower an r_or_w_ok_exprt to arithmetic and logic expressions.
const exprt & size() const
const exprt & pointer() const
const exprt & deallocated_ptr() const
A predicate that indicates that an address range is ok to read.
Definition: pointer_expr.h:960
Expression to hold a symbol (variable)
Definition: std_expr.h:131
exprt & op1()
Definition: expr.h:136
exprt & op2()
Definition: expr.h:139
exprt & op0()
Definition: expr.h:133
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
Generic base class for unary expressions.
Definition: std_expr.h:361
const exprt & op() const
Definition: std_expr.h:391
const exprt & skip_typecast(const exprt &expr)
find the expression nested inside typecasts, if any
Definition: expr_util.cpp:193
Deprecated expression utility functions.
const std::string & id2string(const irep_idt &d)
Definition: irep.h:44
static void build_object_descriptor_rec(const namespacet &ns, const exprt &expr, object_descriptor_exprt &dest)
Build an object_descriptor_exprt from a given expr.
API to expression classes for Pointers.
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:890
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:93
std::optional< exprt > size_of_expr(const typet &type, const namespacet &ns)
std::optional< exprt > member_offset_expr(const member_exprt &member_expr, const namespacet &ns)
Pointer Logic.
exprt pointer_offset(const exprt &pointer)
exprt object_upper_bound(const exprt &pointer, const exprt &access_size)
exprt same_object(const exprt &p1, const exprt &p2)
exprt null_object(const exprt &pointer)
exprt object_lower_bound(const exprt &pointer, const exprt &offset)
Various predicates over pointers in programs.
bool simplify(exprt &expr, const namespacet &ns)
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:3050
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2107
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2941
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1538
#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