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 "simplify_expr.h"
17 
18 void dynamic_object_exprt::set_instance(unsigned int instance)
19 {
20  op0() = from_integer(instance, typet(ID_natural));
21 }
22 
24 {
25  return std::stoul(id2string(to_constant_expr(op0()).get_value()));
26 }
27 
30  const namespacet &ns,
31  const exprt &expr,
33 {
34  if(expr.id() == ID_index)
35  {
36  const index_exprt &index = to_index_expr(expr);
37 
38  build_object_descriptor_rec(ns, index.array(), dest);
39 
40  auto sub_size = size_of_expr(expr.type(), ns);
41  CHECK_RETURN(sub_size.has_value());
42 
43  dest.offset() = plus_exprt(
44  dest.offset(),
45  mult_exprt(
47  typecast_exprt::conditional_cast(sub_size.value(), c_index_type())));
48  }
49  else if(expr.id() == ID_member)
50  {
51  const member_exprt &member = to_member_expr(expr);
52  const exprt &struct_op = member.struct_op();
53 
54  build_object_descriptor_rec(ns, struct_op, dest);
55 
56  auto offset = member_offset_expr(member, ns);
57  CHECK_RETURN(offset.has_value());
58 
59  dest.offset() = plus_exprt(
60  dest.offset(),
62  }
63  else if(
64  expr.id() == ID_byte_extract_little_endian ||
65  expr.id() == ID_byte_extract_big_endian)
66  {
67  const byte_extract_exprt &be = to_byte_extract_expr(expr);
68 
69  dest.object() = be.op();
70 
71  build_object_descriptor_rec(ns, be.op(), dest);
72 
73  dest.offset() = plus_exprt(
74  dest.offset(),
76  to_byte_extract_expr(expr).offset(), c_index_type()));
77  }
78  else if(expr.id() == ID_typecast)
79  {
80  const typecast_exprt &tc = to_typecast_expr(expr);
81 
82  dest.object() = tc.op();
83 
84  build_object_descriptor_rec(ns, tc.op(), dest);
85  }
86  else if(const auto deref = expr_try_dynamic_cast<dereference_exprt>(expr))
87  {
88  const exprt &pointer = skip_typecast(deref->pointer());
89  if(const auto address_of = expr_try_dynamic_cast<address_of_exprt>(pointer))
90  {
91  dest.object() = address_of->object();
92  build_object_descriptor_rec(ns, address_of->object(), dest);
93  }
94  }
95  else if(const auto address_of = expr_try_dynamic_cast<address_of_exprt>(expr))
96  {
97  const exprt &object = skip_typecast(address_of->object());
98  if(const auto deref = expr_try_dynamic_cast<dereference_exprt>(object))
99  {
100  dest.object() = deref->pointer();
101  build_object_descriptor_rec(ns, deref->pointer(), dest);
102  }
103  }
104 }
105 
107 void object_descriptor_exprt::build(const exprt &expr, const namespacet &ns)
108 {
109  PRECONDITION(object().id() == ID_unknown);
110  object() = expr;
111 
112  if(offset().id() == ID_unknown)
113  offset() = from_integer(0, c_index_type());
114 
115  build_object_descriptor_rec(ns, expr, *this);
116  simplify(offset(), ns);
117 }
118 
120  : unary_exprt(ID_address_of, _op, pointer_type(_op.type()))
121 {
122 }
123 
125  : object_address_exprt(object, pointer_type(object.type()))
126 {
127 }
128 
130  const symbol_exprt &object,
131  pointer_typet type)
132  : nullary_exprt(ID_object_address, std::move(type))
133 {
134  set(ID_identifier, object.get_identifier());
135 }
136 
138 {
139  return symbol_exprt(object_identifier(), to_pointer_type(type()).base_type());
140 }
141 
143  exprt compound_ptr,
144  const irep_idt &component_name,
145  pointer_typet _type)
146  : unary_exprt(ID_field_address, std::move(compound_ptr), std::move(_type))
147 {
148  const auto &base_type = field_address_exprt::base().type();
149  PRECONDITION(base_type.id() == ID_pointer);
150  const auto &compound_type = to_pointer_type(base_type).base_type();
151  PRECONDITION(
152  compound_type.id() == ID_struct || compound_type.id() == ID_struct_tag ||
153  compound_type.id() == ID_union || compound_type.id() == ID_union_tag);
154  set(ID_component_name, component_name);
155 }
156 
158  : binary_exprt(
159  base,
160  ID_element_address,
161  std::move(index),
163  to_pointer_type(base.type()).base_type(),
164  to_pointer_type(base.type()).get_width()))
165 {
166 }
167 
169 {
170  const exprt *p = &expr;
171 
172  while(true)
173  {
174  if(p->id() == ID_member)
175  p = &to_member_expr(*p).compound();
176  else if(p->id() == ID_index)
177  p = &to_index_expr(*p).array();
178  else
179  break;
180  }
181 
182  return *p;
183 }
184 
193  const exprt &expr,
194  const namespacet &ns,
195  const validation_modet vm)
196 {
197  check(expr, vm);
198 
199  const auto &dereference_expr = to_dereference_expr(expr);
200 
201  const typet &type_of_operand = dereference_expr.pointer().type();
202 
203  const pointer_typet *pointer_type =
204  type_try_dynamic_cast<pointer_typet>(type_of_operand);
205 
206  DATA_CHECK(
207  vm,
208  pointer_type,
209  "dereference expression's operand must have a pointer type");
210 
211  DATA_CHECK(
212  vm,
213  dereference_expr.type() == pointer_type->base_type(),
214  "dereference expression's type must match the base type of the type of its "
215  "operand");
216 }
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
pointer_offset_size.h
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
DATA_CHECK
#define DATA_CHECK(vm, condition, message)
This macro takes a condition which denotes a well-formedness criterion on goto programs,...
Definition: validate.h:22
skip_typecast
const exprt & skip_typecast(const exprt &expr)
find the expression nested inside typecasts, if any
Definition: expr_util.cpp:217
field_address_exprt::base
exprt & base()
Definition: pointer_expr.h:504
arith_tools.h
object_descriptor_exprt::build
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...
Definition: pointer_expr.cpp:107
to_dereference_expr
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:716
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
typet
The type of an expression, extends irept.
Definition: type.h:28
to_byte_extract_expr
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
Definition: byte_operators.h:57
to_index_expr
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1478
object_descriptor_exprt
Split an expression into a base object and a (byte) offset.
Definition: pointer_expr.h:166
dereference_exprt::validate
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...
Definition: pointer_expr.cpp:192
object_address_exprt::object_address_exprt
object_address_exprt(const symbol_exprt &)
Definition: pointer_expr.cpp:124
field_address_exprt::field_address_exprt
field_address_exprt(exprt base, const irep_idt &component_name, pointer_typet type)
constructor for field addresses.
Definition: pointer_expr.cpp:142
address_of_exprt::address_of_exprt
address_of_exprt(const exprt &op)
Definition: pointer_expr.cpp:119
plus_exprt
The plus expression Associativity is not specified.
Definition: std_expr.h:946
exprt
Base class for all expressions.
Definition: expr.h:55
object_address_exprt::object_identifier
irep_idt object_identifier() const
Definition: pointer_expr.h:433
unary_exprt
Generic base class for unary expressions.
Definition: std_expr.h:313
binary_exprt
A base class for binary expressions.
Definition: std_expr.h:582
object_descriptor_exprt::root_object
const exprt & root_object() const
Definition: pointer_expr.h:204
exprt::op0
exprt & op0()
Definition: expr.h:125
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:112
object_address_exprt::object_expr
symbol_exprt object_expr() const
Definition: pointer_expr.cpp:137
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
nullary_exprt
An expression without operands.
Definition: std_expr.h:21
dynamic_object_exprt::get_instance
unsigned int get_instance() const
Definition: pointer_expr.cpp:23
byte_operators.h
Expression classes for byte-level operators.
object_address_exprt
Operator to return the address of an object.
Definition: pointer_expr.h:426
object_address_exprt::type
const pointer_typet & type() const
Definition: pointer_expr.h:438
element_address_exprt::element_address_exprt
element_address_exprt(const exprt &base, exprt index)
constructor for element addresses.
Definition: pointer_expr.cpp:157
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
byte_extract_exprt::op
exprt & op()
Definition: byte_operators.h:43
member_exprt::compound
const exprt & compound() const
Definition: std_expr.h:2843
get_identifier
static optionalt< smt_termt > get_identifier(const exprt &expr, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_handle_identifiers, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers)
Definition: smt2_incremental_decision_procedure.cpp:328
irept::set
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
member_exprt::struct_op
const exprt & struct_op() const
Definition: std_expr.h:2832
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
pointer_expr.h
simplify
bool simplify(exprt &expr, const namespacet &ns)
Definition: simplify_expr.cpp:2926
mult_exprt
Binary multiplication Associativity is not specified.
Definition: std_expr.h:1051
to_pointer_type
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:79
index_exprt::index
exprt & index()
Definition: std_expr.h:1450
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
index_exprt::array
exprt & array()
Definition: std_expr.h:1440
validation_modet
validation_modet
Definition: validation_mode.h:12
irept::id
const irep_idt & id() const
Definition: irep.h:396
unary_exprt::op
const exprt & op() const
Definition: std_expr.h:326
field_address_exprt::component_name
const irep_idt & component_name() const
Definition: pointer_expr.h:535
simplify_expr.h
member_exprt
Extract member of struct or union.
Definition: std_expr.h:2793
expr_util.h
Deprecated expression utility functions.
dynamic_object_exprt::set_instance
void set_instance(unsigned int instance)
Definition: pointer_expr.cpp:18
build_object_descriptor_rec
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.
Definition: pointer_expr.cpp:29
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
to_typecast_expr
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2051
pointer_typet::base_type
const typet & base_type() const
The type of the data what we point to.
Definition: pointer_expr.h:35
byte_extract_exprt
Expression of type type extracted from some object op starting at position offset (given in number of...
Definition: byte_operators.h:28
size_of_expr
optionalt< exprt > size_of_expr(const typet &type, const namespacet &ns)
Definition: pointer_offset_size.cpp:280
to_member_expr
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2886
index_exprt
Array index operator.
Definition: std_expr.h:1409
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
pointer_typet
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:23
field_address_exprt::compound_type
const typet & compound_type() const
Definition: pointer_expr.h:530
object_descriptor_exprt::object
exprt & object()
Definition: pointer_expr.h:193
member_offset_expr
optionalt< exprt > member_offset_expr(const member_exprt &member_expr, const namespacet &ns)
Definition: pointer_offset_size.cpp:221
c_index_type
bitvector_typet c_index_type()
Definition: c_types.cpp:16
c_types.h
dereference_exprt::check
static void check(const exprt &expr, const validation_modet vm=validation_modet::INVARIANT)
Definition: pointer_expr.h:683
to_constant_expr
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:2992
object_descriptor_exprt::offset
exprt & offset()
Definition: pointer_expr.h:209