CBMC
simplify_expr_pointer.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "simplify_expr_class.h"
10 
11 #include "arith_tools.h"
12 #include "c_types.h"
13 #include "config.h"
14 #include "expr_util.h"
15 #include "namespace.h"
16 #include "pointer_expr.h"
17 #include "pointer_offset_size.h"
18 #include "pointer_predicates.h"
19 #include "std_expr.h"
20 #include "string_constant.h"
21 
23  const exprt &expr,
24  mp_integer &address)
25 {
26  if(expr.id() == ID_dereference)
27  {
28  const auto &pointer = to_dereference_expr(expr).pointer();
29 
30  if(
31  pointer.id() == ID_typecast &&
32  to_typecast_expr(pointer).op().is_constant() &&
33  !to_integer(to_constant_expr(to_typecast_expr(pointer).op()), address))
34  {
35  return true;
36  }
37 
38  if(pointer.is_constant())
39  {
40  const constant_exprt &constant = to_constant_expr(pointer);
41 
42  if(is_null_pointer(constant))
43  {
44  address=0;
45  return true;
46  }
47  else if(!to_integer(constant, address))
48  return true;
49  }
50  }
51 
52  return false;
53 }
54 
57  const unary_exprt &expr)
58 {
59  const exprt &pointer = expr.op();
60  PRECONDITION(pointer.type().id() == ID_pointer);
61 
62  if(pointer.id() == ID_if)
63  {
64  if_exprt if_expr = lift_if(expr, 0);
65  return changed(simplify_if_preorder(if_expr));
66  }
67  else
68  {
69  auto r_it = simplify_rec(pointer); // recursive call
70  if(r_it.has_changed())
71  {
72  auto tmp = expr;
73  tmp.op() = r_it.expr;
74  return tmp;
75  }
76  }
77 
78  return unchanged(expr);
79 }
80 
83 {
84  if(expr.id()==ID_index)
85  {
86  auto new_index_expr = to_index_expr(expr);
87 
88  bool no_change = true;
89 
90  auto array_result = simplify_address_of_arg(new_index_expr.array());
91 
92  if(array_result.has_changed())
93  {
94  no_change = false;
95  new_index_expr.array() = array_result.expr;
96  }
97 
98  auto index_result = simplify_rec(new_index_expr.index());
99 
100  if(index_result.has_changed())
101  {
102  no_change = false;
103  new_index_expr.index() = index_result.expr;
104  }
105 
106  // rewrite (*(type *)int) [index] by
107  // pushing the index inside
108 
109  mp_integer address;
110  if(is_dereference_integer_object(new_index_expr.array(), address))
111  {
112  // push index into address
113  auto step_size = pointer_offset_size(new_index_expr.type(), ns);
114 
115  if(step_size.has_value())
116  {
117  const auto index = numeric_cast<mp_integer>(new_index_expr.index());
118 
119  if(index.has_value())
120  {
122  to_dereference_expr(new_index_expr.array()).pointer().type());
123  pointer_type.base_type() = new_index_expr.type();
124 
125  typecast_exprt typecast_expr(
126  from_integer((*step_size) * (*index) + address, c_index_type()),
127  pointer_type);
128 
129  return dereference_exprt{typecast_expr};
130  }
131  }
132  }
133 
134  if(!no_change)
135  return new_index_expr;
136  }
137  else if(expr.id()==ID_member)
138  {
139  auto new_member_expr = to_member_expr(expr);
140 
141  bool no_change = true;
142 
143  auto struct_op_result =
144  simplify_address_of_arg(new_member_expr.struct_op());
145 
146  if(struct_op_result.has_changed())
147  {
148  new_member_expr.struct_op() = struct_op_result.expr;
149  no_change = false;
150  }
151 
152  const typet &op_type = new_member_expr.struct_op().type();
153 
154  if(op_type.id() == ID_struct || op_type.id() == ID_struct_tag)
155  {
156  // rewrite NULL -> member by
157  // pushing the member inside
158 
159  mp_integer address;
160  if(is_dereference_integer_object(new_member_expr.struct_op(), address))
161  {
162  const struct_typet &struct_type =
163  op_type.id() == ID_struct_tag
164  ? ns.follow_tag(to_struct_tag_type(op_type))
165  : to_struct_type(op_type);
166  const irep_idt &member = to_member_expr(expr).get_component_name();
167  auto offset = member_offset(struct_type, member, ns);
168  if(offset.has_value())
169  {
171  to_dereference_expr(new_member_expr.struct_op()).pointer().type());
172  pointer_type.base_type() = new_member_expr.type();
173  typecast_exprt typecast_expr(
174  from_integer(address + *offset, c_index_type()), pointer_type);
175  return dereference_exprt{typecast_expr};
176  }
177  }
178  }
179 
180  if(!no_change)
181  return new_member_expr;
182  }
183  else if(expr.id()==ID_dereference)
184  {
185  auto new_expr = to_dereference_expr(expr);
186  auto r_pointer = simplify_rec(new_expr.pointer());
187  if(r_pointer.has_changed())
188  {
189  new_expr.pointer() = r_pointer.expr;
190  return std::move(new_expr);
191  }
192  }
193  else if(expr.id()==ID_if)
194  {
195  auto new_if_expr = to_if_expr(expr);
196 
197  bool no_change = true;
198 
199  auto r_cond = simplify_rec(new_if_expr.cond());
200  if(r_cond.has_changed())
201  {
202  new_if_expr.cond() = r_cond.expr;
203  no_change = false;
204  }
205 
206  auto true_result = simplify_address_of_arg(new_if_expr.true_case());
207  if(true_result.has_changed())
208  {
209  new_if_expr.true_case() = true_result.expr;
210  no_change = false;
211  }
212 
213  auto false_result = simplify_address_of_arg(new_if_expr.false_case());
214 
215  if(false_result.has_changed())
216  {
217  new_if_expr.false_case() = false_result.expr;
218  no_change = false;
219  }
220 
221  // condition is a constant?
222  if(new_if_expr.cond().is_true())
223  {
224  return new_if_expr.true_case();
225  }
226  else if(new_if_expr.cond().is_false())
227  {
228  return new_if_expr.false_case();
229  }
230 
231  if(!no_change)
232  return new_if_expr;
233  }
234 
235  return unchanged(expr);
236 }
237 
240 {
241  if(expr.type().id() != ID_pointer)
242  return unchanged(expr);
243 
244  auto new_object = simplify_address_of_arg(expr.object());
245 
246  if(new_object.expr.id() == ID_index)
247  {
248  auto index_expr = to_index_expr(new_object.expr);
249 
250  if(!index_expr.index().is_zero())
251  {
252  // we normalize &a[i] to (&a[0])+i
253  exprt offset = index_expr.op1();
254  index_expr.op1()=from_integer(0, offset.type());
255  auto new_address_of_expr = expr;
256  new_address_of_expr.object() = std::move(index_expr);
257  return plus_exprt(std::move(new_address_of_expr), offset);
258  }
259  }
260  else if(new_object.expr.id() == ID_dereference)
261  {
262  // simplify &*p to p
263  return to_dereference_expr(new_object.expr).pointer();
264  }
265 
266  if(new_object.has_changed())
267  {
268  auto new_expr = expr;
269  new_expr.object() = new_object;
270  return new_expr;
271  }
272  else
273  return unchanged(expr);
274 }
275 
278 {
279  const exprt &ptr = expr.pointer();
280 
281  if(ptr.type().id()!=ID_pointer)
282  return unchanged(expr);
283 
284  if(ptr.id()==ID_address_of)
285  {
286  auto offset = compute_pointer_offset(to_address_of_expr(ptr).object(), ns);
287 
288  if(offset.has_value())
289  return from_integer(*offset, expr.type());
290  }
291  else if(ptr.id()==ID_typecast) // pointer typecast
292  {
293  const auto &op = to_typecast_expr(ptr).op();
294  const typet &op_type = op.type();
295 
296  if(op_type.id()==ID_pointer)
297  {
298  // Cast from pointer to pointer.
299  // This just passes through, remove typecast.
300  auto new_expr = expr;
301  new_expr.op() = op;
302 
303  return changed(simplify_pointer_offset(new_expr)); // recursive call
304  }
305  else if(op_type.id()==ID_signedbv ||
306  op_type.id()==ID_unsignedbv)
307  {
308  // Cast from integer to pointer, say (int *)x.
309 
310  if(op.is_constant())
311  {
312  // (T *)0x1234 -> 0x1234
313  return changed(simplify_typecast(typecast_exprt{op, expr.type()}));
314  }
315  else
316  {
317  // We do a bit of special treatment for (TYPE *)(a+(int)&o),
318  // which is re-written to 'a'.
319 
320  typet type = expr.type();
321  exprt tmp = op;
322  if(tmp.id()==ID_plus && tmp.operands().size()==2)
323  {
324  const auto &plus_expr = to_plus_expr(tmp);
325 
326  if(
327  plus_expr.op0().id() == ID_typecast &&
328  to_typecast_expr(plus_expr.op0()).op().id() == ID_address_of)
329  {
330  auto new_expr =
331  typecast_exprt::conditional_cast(plus_expr.op1(), type);
332 
333  return changed(simplify_node(new_expr));
334  }
335  else if(
336  plus_expr.op1().id() == ID_typecast &&
337  to_typecast_expr(plus_expr.op1()).op().id() == ID_address_of)
338  {
339  auto new_expr =
340  typecast_exprt::conditional_cast(plus_expr.op0(), type);
341 
342  return changed(simplify_node(new_expr));
343  }
344  }
345  }
346  }
347  }
348  else if(ptr.id()==ID_plus) // pointer arithmetic
349  {
350  exprt::operandst ptr_expr;
351  exprt::operandst int_expr;
352 
353  for(const auto &op : ptr.operands())
354  {
355  if(op.type().id()==ID_pointer)
356  ptr_expr.push_back(op);
357  else if(!op.is_zero())
358  {
359  exprt tmp=op;
360  if(tmp.type()!=expr.type())
361  tmp = simplify_typecast(typecast_exprt(tmp, expr.type()));
362 
363  int_expr.push_back(tmp);
364  }
365  }
366 
367  if(ptr_expr.size()!=1 || int_expr.empty())
368  return unchanged(expr);
369 
370  typet pointer_base_type =
371  to_pointer_type(ptr_expr.front().type()).base_type();
372  if(pointer_base_type.id() == ID_empty)
373  pointer_base_type = char_type();
374 
375  auto element_size = pointer_offset_size(pointer_base_type, ns);
376 
377  if(!element_size.has_value())
378  return unchanged(expr);
379 
380  exprt pointer_offset_expr = simplify_pointer_offset(
381  pointer_offset_exprt(ptr_expr.front(), expr.type()));
382 
383  exprt sum;
384 
385  if(int_expr.size()==1)
386  sum=int_expr.front();
387  else
388  sum = simplify_plus(plus_exprt{int_expr, expr.type()});
389 
390  exprt size_expr = from_integer(*element_size, expr.type());
391 
392  exprt product = simplify_mult(mult_exprt{sum, size_expr});
393 
394  auto new_expr = plus_exprt(pointer_offset_expr, product);
395 
396  return changed(simplify_plus(new_expr));
397  }
398  else if(ptr.is_constant())
399  {
400  const constant_exprt &c_ptr = to_constant_expr(ptr);
401 
402  if(is_null_pointer(c_ptr))
403  {
404  return from_integer(0, expr.type());
405  }
406  else
407  {
408  // this is a pointer, we can't use to_integer
409  const auto width = to_pointer_type(ptr.type()).get_width();
410  mp_integer number = bvrep2integer(c_ptr.get_value(), width, false);
411  // a null pointer would have been caught above, return value 0
412  // will indicate that conversion failed
413  if(number==0)
414  return unchanged(expr);
415 
416  // The constant address consists of OBJECT-ID || OFFSET.
417  mp_integer offset_bits =
419  number%=power(2, offset_bits);
420 
421  return from_integer(number, expr.type());
422  }
423  }
424 
425  return unchanged(expr);
426 }
427 
429  const binary_relation_exprt &expr)
430 {
431  // the operands of the relation are both either one of
432  // a) an address_of_exprt
433  // b) a typecast_exprt with an address_of_exprt operand
434 
435  PRECONDITION(expr.id() == ID_equal || expr.id() == ID_notequal);
436 
437  // skip over the typecast
438  exprt tmp0 = skip_typecast(expr.op0());
439  PRECONDITION(tmp0.id() == ID_address_of);
440 
441  auto &tmp0_address_of = to_address_of_expr(tmp0);
442 
443  if(
444  tmp0_address_of.object().id() == ID_index &&
445  to_index_expr(tmp0_address_of.object()).index().is_zero())
446  {
447  tmp0_address_of =
448  address_of_exprt(to_index_expr(tmp0_address_of.object()).array());
449  }
450 
451  // skip over the typecast
452  exprt tmp1 = skip_typecast(expr.op1());
453  PRECONDITION(tmp1.id() == ID_address_of);
454 
455  auto &tmp1_address_of = to_address_of_expr(tmp1);
456 
457  if(
458  tmp1_address_of.object().id() == ID_index &&
459  to_index_expr(tmp1_address_of.object()).index().is_zero())
460  {
461  tmp1 = address_of_exprt(to_index_expr(tmp1_address_of.object()).array());
462  }
463 
464  const auto &tmp0_object = tmp0_address_of.object();
465  const auto &tmp1_object = tmp1_address_of.object();
466 
467  if(tmp0_object.id() == ID_symbol && tmp1_object.id() == ID_symbol)
468  {
469  bool equal = to_symbol_expr(tmp0_object).get_identifier() ==
470  to_symbol_expr(tmp1_object).get_identifier();
471 
472  return make_boolean_expr(expr.id() == ID_equal ? equal : !equal);
473  }
474  else if(
475  tmp0_object.id() == ID_dynamic_object &&
476  tmp1_object.id() == ID_dynamic_object)
477  {
478  bool equal = to_dynamic_object_expr(tmp0_object).get_instance() ==
479  to_dynamic_object_expr(tmp1_object).get_instance();
480 
481  return make_boolean_expr(expr.id() == ID_equal ? equal : !equal);
482  }
483  else if(
484  (tmp0_object.id() == ID_symbol && tmp1_object.id() == ID_dynamic_object) ||
485  (tmp0_object.id() == ID_dynamic_object && tmp1_object.id() == ID_symbol))
486  {
487  return make_boolean_expr(expr.id() != ID_equal);
488  }
489  else if(
490  tmp0_object.id() == ID_string_constant &&
491  tmp1_object.id() == ID_string_constant && tmp0_object == tmp1_object)
492  {
493  return make_boolean_expr(expr.id() == ID_equal);
494  }
495 
496  return unchanged(expr);
497 }
498 
500  const binary_relation_exprt &expr)
501 {
502  PRECONDITION(expr.id() == ID_equal || expr.id() == ID_notequal);
503  PRECONDITION(expr.is_boolean());
504 
505  exprt::operandst new_inequality_ops;
506  for(const auto &operand : expr.operands())
507  {
508  PRECONDITION(operand.id() == ID_pointer_object);
509  const exprt &op = to_pointer_object_expr(operand).pointer();
510 
511  if(op.id()==ID_address_of)
512  {
513  const auto &op_object = to_address_of_expr(op).object();
514 
515  if((op_object.id() != ID_symbol && op_object.id() != ID_dynamic_object &&
516  op_object.id() != ID_string_constant))
517  {
518  return unchanged(expr);
519  }
520  }
521  else if(!op.is_constant() || !op.is_zero())
522  {
523  return unchanged(expr);
524  }
525 
526  if(new_inequality_ops.empty())
527  new_inequality_ops.push_back(op);
528  else
529  {
530  new_inequality_ops.push_back(
532  op, new_inequality_ops.front().type())));
533  }
534  }
535 
536  auto new_expr = expr;
537 
538  new_expr.operands() = std::move(new_inequality_ops);
539 
540  return changed(simplify_inequality(new_expr));
541 }
542 
545 {
546  const exprt &op = expr.pointer();
547 
548  auto op_result = simplify_object(op);
549 
550  if(op_result.expr.id() == ID_if)
551  {
552  const if_exprt &if_expr = to_if_expr(op_result.expr);
553  exprt cond=if_expr.cond();
554 
555  auto p_o_false = expr;
556  p_o_false.op() = if_expr.false_case();
557 
558  auto p_o_true = expr;
559  p_o_true.op() = if_expr.true_case();
560 
561  auto new_expr = if_exprt(cond, p_o_true, p_o_false, expr.type());
562  return changed(simplify_rec(new_expr));
563  }
564 
565  if(op_result.has_changed())
566  {
567  auto new_expr = expr;
568  new_expr.op() = op_result;
569  return std::move(new_expr);
570  }
571  else
572  return unchanged(expr);
573 }
574 
577 {
578  auto new_expr = expr;
579  exprt &op = new_expr.op();
580 
581  bool no_change = true;
582 
583  auto op_result = simplify_object(op);
584 
585  if(op_result.has_changed())
586  {
587  op = op_result.expr;
588  no_change = false;
589  }
590 
591  // NULL is not dynamic
593  return false_exprt();
594 
595  // &something depends on the something
596  if(op.id() == ID_address_of)
597  {
598  const auto &op_object = to_address_of_expr(op).object();
599 
600  if(op_object.id() == ID_symbol)
601  {
602  const irep_idt identifier = to_symbol_expr(op_object).get_identifier();
603 
604  // this is for the benefit of symex
605  return make_boolean_expr(
606  identifier.starts_with(SYMEX_DYNAMIC_PREFIX "::"));
607  }
608  else if(op_object.id() == ID_string_constant)
609  {
610  return false_exprt();
611  }
612  else if(op_object.id() == ID_array)
613  {
614  return false_exprt();
615  }
616  }
617 
618  if(no_change)
619  return unchanged(expr);
620  else
621  return std::move(new_expr);
622 }
623 
626 {
627  auto new_expr = expr;
628  exprt &op = new_expr.op();
629  bool no_change = true;
630 
631  auto op_result = simplify_object(op);
632 
633  if(op_result.has_changed())
634  {
635  op = op_result.expr;
636  no_change = false;
637  }
638 
639  // NULL is not invalid
641  {
642  return false_exprt();
643  }
644 
645  // &anything is not invalid
646  if(op.id()==ID_address_of)
647  {
648  return false_exprt();
649  }
650 
651  if(no_change)
652  return unchanged(expr);
653  else
654  return std::move(new_expr);
655 }
656 
659 {
660  auto new_expr = expr;
661  bool no_change = true;
662  exprt &op = new_expr.pointer();
663  auto op_result = simplify_object(op);
664 
665  if(op_result.has_changed())
666  {
667  op = op_result.expr;
668  no_change = false;
669  }
670 
671  if(op.id() == ID_address_of)
672  {
673  const auto &op_object = to_address_of_expr(op).object();
674 
675  if(op_object.id() == ID_symbol)
676  {
677  // just get the type
678  auto size_opt = size_of_expr(op_object.type(), ns);
679 
680  if(size_opt.has_value())
681  {
682  const typet &expr_type = expr.type();
683  exprt size = size_opt.value();
684 
685  if(size.type() != expr_type)
686  size = simplify_typecast(typecast_exprt(size, expr_type));
687 
688  return size;
689  }
690  }
691  else if(op_object.id() == ID_string_constant)
692  {
693  typet type=expr.type();
694  return from_integer(
695  to_string_constant(op_object).value().size() + 1, type);
696  }
697  }
698 
699  if(no_change)
700  return unchanged(expr);
701  else
702  return std::move(new_expr);
703 }
704 
706  const prophecy_r_or_w_ok_exprt &expr)
707 {
708  exprt new_expr = simplify_rec(expr.lower(ns));
709  if(!new_expr.is_constant())
710  return unchanged(expr);
711  else
712  return std::move(new_expr);
713 }
714 
717 {
718  exprt new_expr = simplify_rec(expr.lower(ns));
719  if(!new_expr.is_constant())
720  return unchanged(expr);
721  else
722  return std::move(new_expr);
723 }
configt config
Definition: config.cpp:25
mp_integer bvrep2integer(const irep_idt &src, std::size_t width, bool is_signed)
convert a bit-vector representation (possibly signed) to integer
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
bool to_integer(const constant_exprt &expr, mp_integer &int_value)
Convert a constant expression expr to an arbitrary-precision integer.
Definition: arith_tools.cpp:20
mp_integer power(const mp_integer &base, const mp_integer &exponent)
A multi-precision implementation of the power operator.
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:235
bitvector_typet char_type()
Definition: c_types.cpp:106
bitvector_typet c_index_type()
Definition: c_types.cpp:16
Operator to return the address of an object.
Definition: pointer_expr.h:540
exprt & object()
Definition: pointer_expr.h:549
exprt & op1()
Definition: expr.h:136
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
std::size_t get_width() const
Definition: std_types.h:920
struct configt::bv_encodingt bv_encoding
A constant literal expression.
Definition: std_expr.h:2987
const irep_idt & get_value() const
Definition: std_expr.h:2995
Operator to dereference a pointer.
Definition: pointer_expr.h:834
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
bool starts_with(const char *s) const
equivalent of as_string().starts_with(s)
Definition: dstring.h:95
unsigned int get_instance() const
Base class for all expressions.
Definition: expr.h:56
std::vector< exprt > operandst
Definition: expr.h:58
exprt & op1()
Definition: expr.h:136
bool is_boolean() const
Return whether the expression represents a Boolean.
Definition: expr.h:224
bool is_zero() const
Return whether the expression is a constant representing 0.
Definition: expr.cpp:47
typet & type()
Return the type of the expression.
Definition: expr.h:84
bool is_constant() const
Return whether the expression is a constant.
Definition: expr.h:212
operandst & operands()
Definition: expr.h:94
The Boolean constant false.
Definition: std_expr.h:3064
The trinary if-then-else operator.
Definition: std_expr.h:2370
exprt & true_case()
Definition: std_expr.h:2397
exprt & false_case()
Definition: std_expr.h:2407
exprt & cond()
Definition: std_expr.h:2387
exprt & array()
Definition: std_expr.h:1495
exprt & index()
Definition: std_expr.h:1505
const irep_idt & id() const
Definition: irep.h:384
irep_idt get_component_name() const
Definition: std_expr.h:2863
Binary multiplication Associativity is not specified.
Definition: std_expr.h:1107
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition: namespace.cpp:63
Expression for finding the size (in bytes) of the object a pointer points to.
The plus expression Associativity is not specified.
Definition: std_expr.h:1002
A numerical identifier for the object a pointer points to.
The offset (in bytes) of a pointer relative to the object.
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
pointer_in_range (see pointer_in_range_exprt) with prophecy expressions to encode whether a pointer r...
Definition: pointer_expr.h:453
exprt lower(const namespacet &ns) const
A base class for a predicate that indicates that an address range is ok to read or write or both.
exprt lower(const namespacet &ns) const
Lower an r_or_w_ok_exprt to arithmetic and logic expressions.
const namespacet & ns
resultt simplify_inequality_address_of(const binary_relation_exprt &)
resultt simplify_prophecy_r_or_w_ok(const prophecy_r_or_w_ok_exprt &)
Try to simplify prophecy_{r,w,rw}_ok to a constant expression.
static resultt changed(resultt<> result)
resultt simplify_unary_pointer_predicate_preorder(const unary_exprt &)
resultt simplify_address_of(const address_of_exprt &)
resultt simplify_node(const exprt &)
resultt simplify_prophecy_pointer_in_range(const prophecy_pointer_in_range_exprt &)
Try to simplify prophecy_pointer_in_range to a constant expression.
resultt simplify_rec(const exprt &)
resultt simplify_typecast(const typecast_exprt &)
resultt simplify_pointer_object(const pointer_object_exprt &)
resultt simplify_object(const exprt &)
resultt simplify_mult(const mult_exprt &)
resultt simplify_address_of_arg(const exprt &)
resultt simplify_inequality(const binary_relation_exprt &)
simplifies inequalities !=, <=, <, >=, >, and also ==
resultt simplify_inequality_pointer_object(const binary_relation_exprt &)
static resultt unchanged(exprt expr)
resultt simplify_is_invalid_pointer(const unary_exprt &)
resultt simplify_pointer_offset(const pointer_offset_exprt &)
resultt simplify_plus(const plus_exprt &)
resultt simplify_if_preorder(const if_exprt &expr)
resultt simplify_is_dynamic_object(const unary_exprt &)
resultt simplify_object_size(const object_size_exprt &)
Structure type, corresponds to C style structs.
Definition: std_types.h:231
const irep_idt & get_identifier() const
Definition: std_expr.h:160
Semantic type conversion.
Definition: std_expr.h:2068
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2076
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
constant_exprt make_boolean_expr(bool value)
returns true_exprt if given true and false_exprt otherwise
Definition: expr_util.cpp:338
const exprt & skip_typecast(const exprt &expr)
find the expression nested inside typecasts, if any
Definition: expr_util.cpp:219
if_exprt lift_if(const exprt &src, std::size_t operand_number)
lift up an if_exprt one level
Definition: expr_util.cpp:203
bool is_null_pointer(const constant_exprt &expr)
Returns true if expr has a pointer type and a value NULL; it also returns true when expr has value ze...
Definition: expr_util.cpp:369
Deprecated expression utility functions.
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
const pointer_object_exprt & to_pointer_object_expr(const exprt &expr)
Cast an exprt to a pointer_object_exprt.
const dynamic_object_exprt & to_dynamic_object_expr(const exprt &expr)
Cast an exprt to a dynamic_object_exprt.
Definition: pointer_expr.h:315
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
Definition: pointer_expr.h:577
std::optional< mp_integer > compute_pointer_offset(const exprt &expr, const namespacet &ns)
std::optional< mp_integer > pointer_offset_bits(const typet &type, const namespacet &ns)
std::optional< exprt > size_of_expr(const typet &type, const namespacet &ns)
std::optional< mp_integer > member_offset(const struct_typet &type, const irep_idt &member, const namespacet &ns)
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.
Pointer Logic.
Various predicates over pointers in programs.
#define SYMEX_DYNAMIC_PREFIX
static bool is_dereference_integer_object(const exprt &expr, mp_integer &address)
BigInt mp_integer
Definition: smt_terms.h:17
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
API to expression classes.
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition: std_expr.h:2450
const constant_exprt & to_constant_expr(const exprt &expr)
Cast an exprt to a constant_exprt.
Definition: std_expr.h:3037
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:272
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2102
const plus_exprt & to_plus_expr(const exprt &expr)
Cast an exprt to a plus_exprt.
Definition: std_expr.h:1041
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2933
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1533
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
Definition: std_types.h:308
bool is_constant(const typet &type)
This method tests, if the given typet is a constant.
Definition: std_types.h:29
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
Definition: std_types.h:518
const string_constantt & to_string_constant(const exprt &expr)
std::size_t object_bits
Definition: config.h:351