ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
dereference.h
Go to the documentation of this file.
1#ifndef CPROVER_POINTER_ANALYSIS_DEREFERENCE_H
2#define CPROVER_POINTER_ANALYSIS_DEREFERENCE_H
3
5#include <set>
6#include <util/irep/expr.h>
7#include <irep2/irep2_guard.h>
10
88
96{
97public:
98 virtual ~dereference_callbackt() = default;
99
109 const std::string &property,
110 const std::string &msg,
111 const guard2tc &guard) = 0;
112
113 virtual void dereference_assume(const guard2tc &guard) = 0;
114
119 virtual void
120 get_value_set(const expr2tc &expr, value_setst::valuest &value_set) = 0;
121
124 virtual bool
125 has_failed_symbol(const expr2tc &expr, const symbolt *&symbol) = 0;
126
140 virtual void rename(expr2tc &expr [[maybe_unused]])
141 {
142 }
143
150
152 const std::list<struct internal_item> &data [[maybe_unused]])
153 {
154 }
155
163 virtual bool is_live_variable(const expr2tc &sym) = 0;
164};
165
173{
174public:
184 const namespacet &_ns,
185 contextt &_new_context,
186 const optionst &_options,
187 dereference_callbackt &_dereference_callback)
188 : ns(_ns),
189 new_context(_new_context),
190 options(_options),
191 dereference_callback(_dereference_callback),
192 block_assertions(false)
193 {
194 is_big_endian =
195 (config.ansi_c.endianess == configt::ansi_ct::IS_BIG_ENDIAN);
196 }
197
198 virtual ~dereferencet() = default;
199
201 struct modet
202 {
203 enum : unsigned
204 {
209 } op : 2;
210
215 unsigned unaligned : 1;
216
217 /* Intentionally provide no comparison operators in order to avoid counter-
218 * intuitive results when comparing, e.g., an unaligned mode with one of
219 * the (!unaligned) dereferencet::(READ|WRITE|FREE|INTERNAL) constants.
220 *
221 * For that the below predicates exist. */
222
223 friend bool is_read(const modet &m)
224 {
225 return m.op == READ;
226 }
227
228 friend bool is_write(const modet &m)
229 {
230 return m.op == WRITE;
231 }
232
233 friend bool is_free(const modet &m)
234 {
235 return m.op == FREE;
236 }
237
238 friend bool is_internal(const modet &m)
239 {
240 return m.op == INTERNAL;
241 }
242 };
243
244 static const constexpr modet READ = {modet::READ, false};
245 static const constexpr modet WRITE = {modet::WRITE, false};
246 static const constexpr modet FREE = {modet::FREE, false};
247 static const constexpr modet INTERNAL = {modet::INTERNAL, false};
248
262 virtual void dereference_expr(expr2tc &expr, guard2tc &guard, modet mode);
263
264 virtual expr2tc dereference(
265 const expr2tc &dest,
266 const type2tc &type,
267 const guard2tc &guard,
268 modet mode,
269 const expr2tc &extra_offset);
270
275 bool has_dereference(const expr2tc &expr) const;
276
280 static void reset_object_counter();
281
282private:
284 const namespacet &ns;
286 contextt &new_context;
288 const optionst &options;
290 dereference_callbackt &dereference_callback;
295 static thread_local unsigned invalid_counter;
298 bool is_big_endian;
303 std::list<dereference_callbackt::internal_item> internal_items;
305 bool block_assertions;
306
313 virtual void
314 dereference_guard_expr(expr2tc &expr, guard2tc &guard, modet mode);
315
323 virtual void
324 dereference_addrof_expr(expr2tc &expr, guard2tc &guard, modet mode);
325
351 virtual expr2tc dereference_expr_nonscalar(
352 expr2tc &expr,
353 guard2tc &guard,
354 modet mode,
355 const expr2tc &base);
356
362 expr2tc
363 resolve_nonscalar_if(const expr2tc &expr, guard2tc &guard, modet mode);
364
381 void check_pointer_alignment(
382 modet mode,
383 const type2tc &type,
384 const expr2tc &deref_expr,
385 const guard2tc &guard,
386 const expr2tc &what);
387
398 expr2tc create_pointer_offset_bits(const expr2tc &deref_expr);
399
409 bool dereference_type_compare(
410 expr2tc &object,
411 const type2tc &dereference_type) const;
412
419 expr2tc make_failed_symbol(const type2tc &out_type);
420
447 expr2tc build_reference_to(
448 const expr2tc &what,
449 modet mode,
450 const expr2tc &deref_expr,
451 const type2tc &type,
452 const guard2tc &guard,
453 const expr2tc &lexical_offset,
454 expr2tc &pointer_guard);
455
456 void deref_invalid_ptr(
457 const expr2tc &deref_expr,
458 const guard2tc &guard,
459 modet mode,
460 const expr2tc &resolved = expr2tc());
461
462 static const expr2tc &get_symbol(const expr2tc &object);
463 void bounds_check(
464 const expr2tc &expr,
465 const expr2tc &offset,
466 const type2tc &type,
467 const guard2tc &guard,
468 const expr2tc &deref = expr2tc());
469 void valid_check(const expr2tc &expr, const guard2tc &guard, modet mode);
470 std::vector<expr2tc> extract_bytes(
471 const expr2tc &object,
472 unsigned int bytes,
473 const expr2tc &offset) const;
474 expr2tc stitch_together_from_byte_array(
475 unsigned int num_bytes,
476 const std::vector<expr2tc> &bytes);
477 expr2tc stitch_together_from_byte_array(
478 const type2tc &type,
479 const expr2tc &byte_array,
480 const expr2tc &offset_bits);
481 void dereference_failure(
482 const std::string &error_class,
483 const std::string &error_name,
484 const guard2tc &guard);
485 void alignment_failure(const std::string &error_name, const guard2tc &guard);
486
487 void bad_base_type_failure(
488 const guard2tc &guard,
489 const std::string &wants,
490 const std::string &have);
491
492 bool check_code_access(
493 expr2tc &value,
494 const expr2tc &offset,
495 const type2tc &type,
496 const guard2tc &guard,
497 modet mode);
498 void check_data_obj_access(
499 const expr2tc &value,
500 const expr2tc &offset,
501 const type2tc &type,
502 const guard2tc &guard,
503 modet mode);
507 void check_alignment(
508 BigInt minwidth,
509 const expr2tc &offset,
510 const guard2tc &guard,
511 const expr2tc &object);
515 BigInt object_base_alignment(const expr2tc &object) const;
516 unsigned int static compute_num_bytes_to_extract(
517 const expr2tc &offset,
518 unsigned long num_bits);
519 static expr2tc extract_bits_from_byte_array(
520 const expr2tc &value,
521 const expr2tc &offset,
522 unsigned long num_bits);
523
524public:
526 expr2tc &value,
527 const expr2tc &offset,
528 const type2tc &type,
529 const guard2tc &guard,
530 modet mode,
531 unsigned long alignment = 0);
532
533private:
534 void construct_from_const_offset(
535 expr2tc &value,
536 const expr2tc &offset,
537 const type2tc &type);
538 void construct_from_dyn_offset(
539 expr2tc &value,
540 const expr2tc &offset,
541 const type2tc &type);
542 void construct_from_const_struct_offset(
543 expr2tc &value,
544 const expr2tc &offset,
545 const type2tc &type,
546 const guard2tc &guard,
547 modet mode);
548 void construct_from_dyn_struct_offset(
549 expr2tc &value,
550 const expr2tc &offset,
551 const type2tc &type,
552 const guard2tc &guard,
553 unsigned long alignment,
554 modet mode,
555 const expr2tc *failed_symbol = nullptr);
556 void construct_from_multidir_array(
557 expr2tc &value,
558 const expr2tc &offset,
559 const type2tc &type,
560 const guard2tc &guard,
561 unsigned long alignment,
562 modet mode);
563 void construct_struct_ref_from_const_offset_array(
564 expr2tc &value,
565 const expr2tc &offs,
566 const type2tc &type,
567 const guard2tc &guard,
568 modet mode,
569 unsigned long alignment);
570 void construct_struct_ref_from_const_offset(
571 expr2tc &value,
572 const expr2tc &offs,
573 const type2tc &type,
574 const guard2tc &guard,
575 modet mode);
576 void construct_struct_ref_from_dyn_offset(
577 expr2tc &value,
578 const expr2tc &offs,
579 const type2tc &type,
580 const guard2tc &guard,
581 modet mode);
582 void construct_struct_ref_from_dyn_offs_rec(
583 const expr2tc &value,
584 const expr2tc &offs,
585 const type2tc &type,
586 const guard2tc &guard,
587 const expr2tc &accuml_guard,
588 modet mode,
589 std::list<std::pair<expr2tc, expr2tc>> &output);
590 void construct_struct_ref_from_dyn_offs_members(
591 const expr2tc &value,
592 const expr2tc &offs,
593 const type2tc &type,
594 const guard2tc &guard,
595 const expr2tc &accuml_guard,
596 modet mode,
597 std::list<std::pair<expr2tc, expr2tc>> &output);
598 void construct_struct_member_from_byte_array(
599 expr2tc &value,
600 const expr2tc &offset,
601 const type2tc &type,
602 const guard2tc &guard,
603 modet mode);
604 void construct_from_array(
605 expr2tc &value,
606 const expr2tc &offset,
607 const type2tc &type,
608 const guard2tc &guard,
609 modet mode,
610 unsigned long alignment = 0);
612 bool construct_value_ref(
613 expr2tc &value,
614 const expr2tc &offset,
615 const type2tc &type,
616 const guard2tc &guard,
617 modet mode,
618 unsigned long alignment);
619 void construct_vector_ref(
620 expr2tc &value,
621 const expr2tc &offset,
622 const type2tc &type,
623 const guard2tc &guard,
624 modet mode,
625 unsigned long alignment);
626 void construct_array_ref(
627 expr2tc &value,
628 const expr2tc &offset,
629 const type2tc &type,
630 const guard2tc &guard,
631 modet mode,
632 unsigned long alignment);
633 class quantifier_scopet;
634
638 std::multiset<irep_idt> quantifier_bound_vars;
639 unsigned opaque_binders = 0;
640
642 bool mentions_bound_var(const expr2tc &expr) const;
643
646 bool may_fold_index(const expr2tc &index) const;
647
648public:
650 {
651 block_assertions = true;
652 }
653
655 {
656 block_assertions = false;
657 }
658};
659
660#endif
static const twodig_t base
Definition bigint.cpp:28
Definition bigint.hh:58
Definition context.h:57
Class providing interface to value set tracking code.
Definition dereference.h:96
virtual ~dereference_callbackt()=default
virtual void dump_internal_state(const std::list< struct internal_item > &data)
Definition dereference.h:151
virtual bool has_failed_symbol(const expr2tc &expr, const symbolt *&symbol)=0
Check whether a failed symbol already exists for the given symbol.
virtual void dereference_assume(const guard2tc &guard)=0
virtual void get_value_set(const expr2tc &expr, value_setst::valuest &value_set)=0
Fetch the set of values that the given pointer variable can point at.
virtual void dereference_failure(const std::string &property, const std::string &msg, const guard2tc &guard)=0
Encode a dereference failure assertion.
virtual void rename(expr2tc &expr)
Rename the given expression into the callback's current execution context.
Definition dereference.h:140
virtual bool is_live_variable(const expr2tc &sym)=0
Determine whether variable is "alive".
static const constexpr modet READ
Definition dereference.h:244
static void reset_object_counter()
Zero the failed-symbol counter.
Definition dereference.cpp:26
dereferencet(const namespacet &_ns, contextt &_new_context, const optionst &_options, dereference_callbackt &_dereference_callback)
Primary constructor.
Definition dereference.h:183
static const constexpr modet FREE
Definition dereference.h:246
void set_block_assertions(void)
Definition dereference.h:649
virtual void dereference_expr(expr2tc &expr, guard2tc &guard, modet mode)
Take an expression and dereference it.
Definition dereference.cpp:217
virtual ~dereferencet()=default
void build_reference_rec(expr2tc &value, const expr2tc &offset, const type2tc &type, const guard2tc &guard, modet mode, unsigned long alignment=0)
Definition dereference.cpp:1269
void clear_block_assertions(void)
Definition dereference.h:654
static const constexpr modet INTERNAL
Definition dereference.h:247
virtual expr2tc dereference(const expr2tc &dest, const type2tc &type, const guard2tc &guard, modet mode, const expr2tc &extra_offset)
Definition dereference.cpp:639
static const constexpr modet WRITE
Definition dereference.h:245
bool has_dereference(const expr2tc &expr) const
Does the given expression have a dereference in it somewhere?
Definition dereference.cpp:109
Path-condition guard container.
Definition irep2_guard.h:32
Definition namespace.h:10
Definition options.h:11
Definition symbol.h:12
std::list< expr2tc > valuest
Definition value_sets.h:15
Definition toml.hpp:1531
configt config
Definition config.cpp:8
irep_container< type2t > type2tc
Definition irep2.h:430
irep_container< expr2t > expr2tc
Definition irep2.h:431
Definition enum.py:1
#define false
Definition stdbool.h:10
@ IS_BIG_ENDIAN
Definition config.h:147
Definition dereference.h:145
expr2tc offset
Definition dereference.h:147
expr2tc guard
Definition dereference.h:148
expr2tc object
Definition dereference.h:146
The different ways in which a pointer may be accessed.
Definition dereference.h:202
friend bool is_write(const modet &m)
Definition dereference.h:228
unsigned unaligned
Whether the access is performed in a non-standard, known-unaligned way as for, e.g....
Definition dereference.h:215
enum dereferencet::modet::@064115070053313312275356267176237112014342131337 op
friend bool is_internal(const modet &m)
Definition dereference.h:238
friend bool is_free(const modet &m)
Definition dereference.h:233
@ WRITE
The result of the expression is only read.
Definition dereference.h:206
@ READ
Definition dereference.h:205
@ INTERNAL
The referred to object will be freed.
Definition dereference.h:208
@ FREE
The result of the expression will be written to.
Definition dereference.h:207
friend bool is_read(const modet &m)
Definition dereference.h:223
BigInt alignment(const typet &type, const namespacet &ns)
Definition type_byte_size.cpp:664
BigInt object_base_alignment(const typet &type, const expr2tc &size, const namespacet &ns)
Definition type_byte_size.cpp:781