cprover
goto_symex_state.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Symbolic Execution
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #ifndef CPROVER_GOTO_SYMEX_GOTO_SYMEX_STATE_H
13 #define CPROVER_GOTO_SYMEX_GOTO_SYMEX_STATE_H
14 
15 #include <functional>
16 #include <memory>
17 #include <unordered_set>
18 
19 #include <analyses/guard.h>
20 
22 #include <util/invariant.h>
23 #include <util/make_unique.h>
24 #include <util/nodiscard.h>
25 #include <util/ssa_expr.h>
26 #include <util/std_expr.h>
27 
28 #include "call_stack.h"
29 #include "field_sensitivity.h"
30 #include "frame.h"
31 #include "goto_state.h"
32 #include "renaming_level.h"
33 #include "symex_target_equation.h"
34 
35 class incremental_dirtyt;
36 
45 class goto_symex_statet final : public goto_statet
46 {
47 public:
49  const symex_targett::sourcet &,
50  std::size_t max_field_sensitive_array_size,
51  guard_managert &manager,
52  std::function<std::size_t(const irep_idt &)> fresh_l2_name_provider);
54 
57  const goto_symex_statet &other,
58  symex_target_equationt *const target)
59  : goto_symex_statet(other) // NOLINT
60  {
61  symex_target = target;
62  }
63 
65 
70 
71  // Manager is required to be able to resize the thread vector
74 
76 
101  template <levelt level = L2>
103 
106  template <levelt level>
108  rename_ssa(ssa_exprt ssa, const namespacet &ns);
109 
110  template <levelt level = L2>
111  void rename(typet &type, const irep_idt &l1_identifier, const namespacet &ns);
112 
113  NODISCARD exprt l2_rename_rvalues(exprt lvalue, const namespacet &ns);
114 
117  ssa_exprt lhs, // L0/L1
118  const exprt &rhs, // L2
119  const namespacet &ns,
120  bool rhs_is_simplified,
121  bool record_value,
122  bool allow_pointer_unsoundness = false);
123 
125 
126 protected:
127  template <levelt>
128  void rename_address(exprt &expr, const namespacet &ns);
129 
131  template <levelt level>
133  set_indices(ssa_exprt expr, const namespacet &ns);
134 
135  // this maps L1 names to (L2) types
136  typedef std::unordered_map<irep_idt, typet> l1_typest;
138 
139 public:
140  // guards
142  {
143  static irep_idt id = "goto_symex::\\guard";
144  return id;
145  }
146 
148  {
150  return threads[source.thread_nr].call_stack;
151  }
152 
153  const call_stackt &call_stack() const
154  {
156  return threads[source.thread_nr].call_stack;
157  }
158 
166  const symbol_exprt &expr,
167  std::function<std::size_t(const irep_idt &)> index_generator,
168  const namespacet &ns);
169 
174  ssa_exprt declare(ssa_exprt ssa, const namespacet &ns);
175 
176  void print_backtrace(std::ostream &) const;
177 
178  // threads
179  typedef std::pair<unsigned, std::list<guardt> > a_s_r_entryt;
180  typedef std::list<guardt> a_s_w_entryt;
181  std::unordered_map<ssa_exprt, a_s_r_entryt, irep_hash> read_in_atomic_section;
182  std::unordered_map<ssa_exprt, a_s_w_entryt, irep_hash>
184 
185  struct threadt
186  {
190  std::map<irep_idt, unsigned> function_frame;
191  unsigned atomic_section_id = 0;
194  {
195  }
196  };
197 
198  std::vector<threadt> threads;
199 
201  {
202  NOT_SHARED,
204  SHARED
205  };
206 
207  bool l2_thread_read_encoding(ssa_exprt &expr, const namespacet &ns);
208  bool l2_thread_write_encoding(const ssa_exprt &expr, const namespacet &ns);
210  write_is_shared(const ssa_exprt &expr, const namespacet &ns) const;
211 
212  std::stack<bool> record_events;
213 
214  const incremental_dirtyt *dirty = nullptr;
215 
217 
220 
224 
227 
228  unsigned total_vccs = 0;
229  unsigned remaining_vccs = 0;
230 
232  void drop_existing_l1_name(const irep_idt &l1_identifier)
233  {
234  level2.current_names.erase(l1_identifier);
235  }
236 
238  void drop_l1_name(const irep_idt &l1_identifier)
239  {
240  level2.current_names.erase_if_exists(l1_identifier);
241  }
242 
243  std::function<std::size_t(const irep_idt &)> get_l2_name_provider() const
244  {
245  return fresh_l2_name_provider;
246  }
247 
249  static bool is_read_only_object(const exprt &lvalue)
250  {
251  // Note ID_constant can occur due to a partial write to a string constant,
252  // (i.e. something like byte_extract int from "hello" offset 2), which
253  // simplifies to a plain constant.
254  return lvalue.id() == ID_string_constant || lvalue.id() == ID_null_object ||
255  lvalue.id() == "zero_string" || lvalue.id() == "is_zero_string" ||
256  lvalue.id() == "zero_string_length" || lvalue.id() == ID_constant;
257  }
258 
259 private:
260  std::function<std::size_t(const irep_idt &)> fresh_l2_name_provider;
261 
272  goto_symex_statet(const goto_symex_statet &other) = default;
273 };
274 
275 #endif // CPROVER_GOTO_SYMEX_GOTO_SYMEX_STATE_H
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:37
Base class for all expressions.
Definition: expr.h:54
Control granularity of object accesses.
instructionst::const_iterator const_targett
Definition: goto_program.h:551
Container for data that varies per program point, e.g.
Definition: goto_state.h:32
symex_level2t level2
Definition: goto_state.h:38
Central data structure: state.
ssa_exprt declare(ssa_exprt ssa, const namespacet &ns)
Add invalid (or a failed symbol) to the value_set if ssa is a pointer, ensure that level2 index of sy...
goto_programt::const_targett saved_target
ssa_exprt add_object(const symbol_exprt &expr, std::function< std::size_t(const irep_idt &)> index_generator, const namespacet &ns)
Instantiate the object expr.
std::pair< unsigned, std::list< guardt > > a_s_r_entryt
std::stack< bool > record_events
bool l2_thread_write_encoding(const ssa_exprt &expr, const namespacet &ns)
thread encoding
NODISCARD renamedt< exprt, level > rename(exprt expr, const namespacet &ns)
Rewrites symbol expressions in exprt, applying a suffix to each symbol reflecting its most recent ver...
goto_symex_statet(const goto_symex_statet &other, symex_target_equationt *const target)
Fake "copy constructor" that initializes the symex_target member.
NODISCARD exprt l2_rename_rvalues(exprt lvalue, const namespacet &ns)
static irep_idt guard_identifier()
call_stackt & call_stack()
const incremental_dirtyt * dirty
goto_symex_statet(const symex_targett::sourcet &, std::size_t max_field_sensitive_array_size, guard_managert &manager, std::function< std::size_t(const irep_idt &)> fresh_l2_name_provider)
std::unordered_map< ssa_exprt, a_s_r_entryt, irep_hash > read_in_atomic_section
std::unordered_map< ssa_exprt, a_s_w_entryt, irep_hash > written_in_atomic_section
symex_level1t level1
void rename_address(exprt &expr, const namespacet &ns)
NODISCARD renamedt< ssa_exprt, L2 > assignment(ssa_exprt lhs, const exprt &rhs, const namespacet &ns, bool rhs_is_simplified, bool record_value, bool allow_pointer_unsoundness=false)
guard_managert & guard_manager
NODISCARD renamedt< ssa_exprt, level > rename_ssa(ssa_exprt ssa, const namespacet &ns)
Version of rename which is specialized for SSA exprt.
bool l2_thread_read_encoding(ssa_exprt &expr, const namespacet &ns)
thread encoding
const call_stackt & call_stack() const
void print_backtrace(std::ostream &) const
Dumps the current state of symex, printing the function name and location number for each stack frame...
symex_target_equationt * symex_target
std::unordered_map< irep_idt, typet > l1_typest
symbol_tablet symbol_table
contains symbols that are minted during symbolic execution, such as dynamically created objects etc.
std::list< guardt > a_s_w_entryt
void drop_l1_name(const irep_idt &l1_identifier)
Drops an L1 name from the local L2 map.
static bool is_read_only_object(const exprt &lvalue)
Returns true if lvalue is a read-only object, such as the null object.
field_sensitivityt field_sensitivity
write_is_shared_resultt write_is_shared(const ssa_exprt &expr, const namespacet &ns) const
NODISCARD renamedt< ssa_exprt, level > set_indices(ssa_exprt expr, const namespacet &ns)
Update values up to level.
symex_targett::sourcet source
bool has_saved_jump_target
This state is saved, with the PC pointing to the target of a GOTO.
std::function< std::size_t(const irep_idt &)> get_l2_name_provider() const
goto_symex_statet(const goto_symex_statet &other)=default
Dangerous, do not use.
bool run_validation_checks
Should the additional validation checks be run?
std::vector< threadt > threads
std::function< std::size_t(const irep_idt &)> fresh_l2_name_provider
bool has_saved_next_instruction
This state is saved, with the PC pointing to the next instruction of a GOTO.
void drop_existing_l1_name(const irep_idt &l1_identifier)
Drops an L1 name from the local L2 map.
Wrapper for dirtyt that permits incremental population, ensuring each function is analysed exactly on...
Definition: dirty.h:119
const irep_idt & id() const
Definition: irep.h:407
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:92
Wrapper for expressions or types which have been renamed up to a given level.
Definition: renamed.h:27
void erase_if_exists(const key_type &k)
Erase element if it exists.
Definition: sharing_map.h:274
void erase(const key_type &k)
Erase element, element must exist in map.
Definition: sharing_map.h:1201
Expression providing an SSA-renamed symbol of expressions.
Definition: ssa_expr.h:17
Expression to hold a symbol (variable)
Definition: std_expr.h:81
The symbol table.
Definition: symbol_table.h:20
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
The Boolean constant true.
Definition: std_expr.h:2717
The type of an expression, extends irept.
Definition: type.h:28
Class for stack frames.
Goto Function.
goto_statet class definition
Guard Data Structure.
#define NODISCARD
Definition: nodiscard.h:22
Renaming levels.
#define PRECONDITION(CONDITION)
Definition: invariant.h:464
API to expression classes.
threadt(guard_managert &guard_manager)
std::map< irep_idt, unsigned > function_frame
goto_programt::const_targett pc
This is unused by this implementation of guards, but can be used by other implementations of the same...
Definition: guard_expr.h:23
Functor to set the level 1 renaming of SSA expressions.
symex_renaming_levelt current_names
Identifies source in the context of symbolic execution.
Definition: symex_target.h:38
Generate Equation using Symbolic Execution.