CBMC
pointer_logic.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Pointer Logic
4 
5 Author: 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 &&
29  has_prefix(
32 }
33 
34 void 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  {
79  null_pointer_exprt null(type);
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 =
95  objects[numeric_cast_v<std::size_t>(pointer.object)];
96 
97  typet subtype = type.base_type();
98  // This is a gcc extension.
99  // https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html
100  if(subtype.id() == ID_empty)
101  subtype = char_type();
102  if(object_expr.id() == ID_string_constant)
103  {
104  subtype = object_expr.type();
105 
106  // a string constant must be array-typed with fixed size
107  const array_typet &array_type = to_array_type(object_expr.type());
108  mp_integer array_size =
109  numeric_cast_v<mp_integer>(to_constant_expr(array_type.size()));
110  if(array_size > pointer.offset)
111  {
112  to_array_type(subtype).size() =
113  from_integer(array_size - pointer.offset, array_type.size().type());
114  }
115  }
116  auto deep_object_opt =
117  get_subexpression_at_offset(object_expr, pointer.offset, subtype, ns);
118  CHECK_RETURN(deep_object_opt.has_value());
119  exprt deep_object = deep_object_opt.value();
120  simplify(deep_object, ns);
121  if(
122  deep_object.id() != ID_byte_extract_little_endian &&
123  deep_object.id() != ID_byte_extract_big_endian)
124  {
126  address_of_exprt(deep_object), type);
127  }
128 
129  const byte_extract_exprt &be = to_byte_extract_expr(deep_object);
130  const address_of_exprt base(be.op());
131  if(be.offset().is_zero())
132  return typecast_exprt::conditional_cast(base, type);
133 
134  const auto object_size = pointer_offset_size(be.op().type(), ns);
135  if(object_size.has_value() && *object_size <= 1)
136  {
138  plus_exprt(base, from_integer(pointer.offset, pointer_diff_type())),
139  type);
140  }
141  else if(object_size.has_value() && pointer.offset % *object_size == 0)
142  {
144  plus_exprt(
145  base, from_integer(pointer.offset / *object_size, pointer_diff_type())),
146  type);
147  }
148  else
149  {
151  plus_exprt(
154  type);
155  }
156 }
157 
159 {
160  // add NULL
161  null_object=objects.number(exprt(ID_NULL));
163 
164  // add INVALID
165  invalid_object=objects.number(exprt("INVALID"));
166 }
167 
169 {
170 }
pointer_offset_size.h
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
mp_integer
BigInt mp_integer
Definition: smt_terms.h:17
arith_tools.h
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
pointer_logict::get_dynamic_objects
void get_dynamic_objects(std::vector< mp_integer > &objects) const
Definition: pointer_logic.cpp:34
to_index_expr
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1478
pointer_predicates.h
prefix.h
invariant.h
plus_exprt
The plus expression Associativity is not specified.
Definition: std_expr.h:946
exprt
Base class for all expressions.
Definition: expr.h:55
pointer_logict::pointer_logict
pointer_logict(const namespacet &_ns)
Definition: pointer_logic.cpp:158
numberingt::cbegin
const_iterator cbegin() const
Definition: numbering.h:93
pointer_logict::ns
const namespacet & ns
Definition: pointer_logic.h:72
pointer_logict::~pointer_logict
~pointer_logict()
Definition: pointer_logic.cpp:168
array_typet::size
const exprt & size() const
Definition: std_types.h:800
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
pointer_logic.h
byte_operators.h
Expression classes for byte-level operators.
has_prefix
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
null_pointer_exprt
The null pointer constant.
Definition: pointer_expr.h:734
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
byte_extract_exprt::op
exprt & op()
Definition: byte_operators.h:43
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
SYMEX_DYNAMIC_PREFIX
#define SYMEX_DYNAMIC_PREFIX
Definition: pointer_predicates.h:17
pointer_logict::pointert::offset
mp_integer offset
Definition: pointer_logic.h:30
pointer_logict::null_object
mp_integer null_object
Definition: pointer_logic.h:73
pointer_expr.h
simplify
bool simplify(exprt &expr, const namespacet &ns)
Definition: simplify_expr.cpp:2926
pointer_logict::invalid_object
mp_integer invalid_object
Definition: pointer_logic.h:73
pointer_type
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:253
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
object_size
exprt object_size(const exprt &pointer)
Definition: pointer_predicates.cpp:33
irept::id
const irep_idt & id() const
Definition: irep.h:396
pointer_logict::objects
numberingt< exprt, irep_hash > objects
Definition: pointer_logic.h:26
pointer_logict::pointert::object
mp_integer object
Definition: pointer_logic.h:30
char_type
bitvector_typet char_type()
Definition: c_types.cpp:124
simplify_expr.h
byte_extract_exprt::offset
exprt & offset()
Definition: byte_operators.h:44
exprt::is_zero
bool is_zero() const
Return whether the expression is a constant representing 0.
Definition: expr.cpp:65
numberingt::size
size_type size() const
Definition: numbering.h:66
pointer_offset_size
optionalt< mp_integer > pointer_offset_size(const typet &type, const namespacet &ns)
Compute the size of a type in bytes, rounding up to full bytes.
Definition: pointer_offset_size.cpp:90
array_typet
Arrays with given size.
Definition: std_types.h:762
pointer_logict::is_dynamic_object
bool is_dynamic_object(const exprt &expr) const
Definition: pointer_logic.cpp:25
numberingt::cend
const_iterator cend() const
Definition: numbering.h:106
numberingt::number
number_type number(const key_type &a)
Definition: numbering.h:37
from_integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
Definition: arith_tools.cpp:100
get_subexpression_at_offset
optionalt< exprt > get_subexpression_at_offset(const exprt &expr, const mp_integer &offset_bytes, const typet &target_type_raw, const namespacet &ns)
Definition: pointer_offset_size.cpp:568
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
to_array_type
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition: std_types.h:844
to_member_expr
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2886
pointer_logict::add_object
mp_integer add_object(const exprt &expr)
Definition: pointer_logic.cpp:44
address_of_exprt
Operator to return the address of an object.
Definition: pointer_expr.h:370
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
pointer_diff_type
signedbv_typet pointer_diff_type()
Definition: c_types.cpp:238
pointer_typet
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:23
constant_exprt
A constant literal expression.
Definition: std_expr.h:2941
std_expr.h
c_types.h
irept::get_bool
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:58
pointer_logict::pointert
Definition: pointer_logic.h:28
pointer_logict::pointer_expr
exprt pointer_expr(const pointert &pointer, const pointer_typet &type) const
Convert an (object,offset) pair to an expression.
Definition: pointer_logic.cpp:67
to_constant_expr
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:2992
integer2string
const std::string integer2string(const mp_integer &n, unsigned base)
Definition: mp_arith.cpp:103