cprover
symex_main.cpp
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 #include "goto_symex.h"
13 
14 #include <memory>
15 
17 
18 #include <util/exception_utils.h>
19 #include <util/expr_iterator.h>
20 #include <util/expr_util.h>
21 #include <util/invariant.h>
22 #include <util/make_unique.h>
23 #include <util/mathematical_expr.h>
24 #include <util/replace_symbol.h>
25 #include <util/std_expr.h>
26 #include <util/string2int.h>
27 #include <util/symbol_table.h>
28 
29 #include <util/format.h>
30 #include <util/format_expr.h>
31 #include <util/format_type.h>
32 #include <util/std_types.h>
33 
35  : max_depth(options.get_unsigned_int_option("depth")),
36  doing_path_exploration(options.is_set("paths")),
37  allow_pointer_unsoundness(
38  options.get_bool_option("allow-pointer-unsoundness")),
39  constant_propagation(options.get_bool_option("propagation")),
40  self_loops_to_assumptions(
41  options.get_bool_option("self-loops-to-assumptions")),
42  simplify_opt(options.get_bool_option("simplify")),
43  unwinding_assertions(options.get_bool_option("unwinding-assertions")),
44  partial_loops(options.get_bool_option("partial-loops")),
45  havoc_undefined_functions(
46  options.get_bool_option("havoc-undefined-functions")),
47  debug_level(unsafe_string2int(options.get_option("debug-level"))),
48  run_validation_checks(options.get_bool_option("validate-ssa-equation")),
49  show_symex_steps(options.get_bool_option("show-goto-symex-steps")),
50  show_points_to_sets(options.get_bool_option("show-points-to-sets")),
51  max_field_sensitivity_array_size(
52  options.is_set("no-array-field-sensitivity")
53  ? 0
54  : options.is_set("max-field-sensitivity-array-size")
55  ? options.get_unsigned_int_option(
56  "max-field-sensitivity-array-size")
58  complexity_limits_active(
59  options.get_signed_int_option("symex-complexity-limit") > 0),
60  cache_dereferences{options.get_bool_option("symex-cache-dereferences")}
61 {
62 }
63 
67 static void pop_exited_loops(
69  std::vector<framet::active_loop_infot> &active_loops)
70 {
71  while(!active_loops.empty())
72  {
73  if(!active_loops.back().loop.contains(to))
74  active_loops.pop_back();
75  else
76  break;
77  }
78 }
79 
81  goto_symext::statet &state,
83  bool is_backwards_goto)
84 {
85  if(!state.call_stack().empty())
86  {
87  // initialize the loop counter of any loop we are newly entering
88  // upon this transition; we are entering a loop if
89  // 1. the transition from state.source.pc to "to" is not a backwards goto
90  // or
91  // 2. we are arriving from an outer loop
92 
93  // TODO: This should all be replaced by natural loop analysis.
94  // This is because the way we detect loops is pretty imprecise.
95 
96  framet &frame = state.call_stack().top();
97  const goto_programt::instructiont &instruction=*to;
98  for(const auto &i_e : instruction.incoming_edges)
99  {
100  if(
101  i_e->is_backwards_goto() && i_e->get_target() == to &&
102  (!is_backwards_goto ||
103  state.source.pc->location_number > i_e->location_number))
104  {
105  const auto loop_id =
107  auto &current_loop_info = frame.loop_iterations[loop_id];
108  current_loop_info.count = 0;
109 
110  // We've found a loop, put it on the stack and say it's our current
111  // active loop.
112  if(
113  frame.loops_info && frame.loops_info->loop_map.find(to) !=
114  frame.loops_info->loop_map.end())
115  {
116  frame.active_loops.emplace_back(frame.loops_info->loop_map[to]);
117  }
118  }
119  }
120 
121  // Only do this if we have active loop analysis going.
122  if(!frame.active_loops.empty())
123  {
124  // Otherwise if we find we're transitioning out of a loop, make sure
125  // to remove any loops we're not currently iterating over.
126 
127  // Match the do-while pattern.
128  if(
129  state.source.pc->is_backwards_goto() &&
130  state.source.pc->location_number < to->location_number)
131  {
132  pop_exited_loops(to, frame.active_loops);
133  }
134 
135  // Match for-each or while.
136  for(const auto &incoming_edge : state.source.pc->incoming_edges)
137  {
138  if(
139  incoming_edge->is_backwards_goto() &&
140  incoming_edge->location_number < to->location_number)
141  {
142  pop_exited_loops(to, frame.active_loops);
143  }
144  }
145  }
146  }
147 
148  state.source.pc=to;
149 }
150 
152 {
154  ++next;
155  symex_transition(state, next, false);
156 }
157 
159  const goto_programt::instructiont &instruction,
160  statet &state)
161 {
162  exprt condition = clean_expr(instruction.get_condition(), state, false);
163 
164  // First, push negations in and perhaps convert existential quantifiers into
165  // universals:
166  if(has_subexpr(condition, ID_exists) || has_subexpr(condition, ID_forall))
167  do_simplify(condition);
168 
169  // Second, L2-rename universal quantifiers:
170  if(has_subexpr(condition, ID_forall))
171  rewrite_quantifiers(condition, state);
172 
173  // now rename, enables propagation
174  exprt l2_condition = state.rename(std::move(condition), ns).get();
175 
176  // now try simplifier on it
177  do_simplify(l2_condition);
178 
179  std::string msg = id2string(instruction.source_location.get_comment());
180  if(msg.empty())
181  msg = "assertion";
182 
183  vcc(l2_condition, msg, state);
184 }
185 
187  const exprt &condition,
188  const std::string &msg,
189  statet &state)
190 {
191  state.total_vccs++;
193 
194  if(condition.is_true())
195  return;
196 
197  const exprt guarded_condition = state.guard.guard_expr(condition);
198 
199  state.remaining_vccs++;
200  target.assertion(state.guard.as_expr(), guarded_condition, msg, state.source);
201 }
202 
203 void goto_symext::symex_assume(statet &state, const exprt &cond)
204 {
205  exprt simplified_cond = clean_expr(cond, state, false);
206  simplified_cond = state.rename(std::move(simplified_cond), ns).get();
207  do_simplify(simplified_cond);
208 
209  // It would be better to call try_filter_value_sets after apply_condition,
210  // but it is not currently possible. See the comment at the beginning of
211  // \ref apply_goto_condition for more information.
212 
214  state, cond, state.value_set, &state.value_set, nullptr, ns);
215 
216  // apply_condition must come after rename because it might change the
217  // constant propagator and the value-set and we read from those in rename
218  state.apply_condition(simplified_cond, state, ns);
219 
220  symex_assume_l2(state, simplified_cond);
221 }
222 
223 void goto_symext::symex_assume_l2(statet &state, const exprt &cond)
224 {
225  if(cond.is_true())
226  return;
227 
228  if(cond.is_false())
229  state.reachable = false;
230 
231  // we are willing to re-write some quantified expressions
232  exprt rewritten_cond = cond;
233  if(has_subexpr(rewritten_cond, ID_exists))
234  rewrite_quantifiers(rewritten_cond, state);
235 
236  if(state.threads.size()==1)
237  {
238  exprt tmp = state.guard.guard_expr(rewritten_cond);
239  target.assumption(state.guard.as_expr(), tmp, state.source);
240  }
241  // symex_target_equationt::convert_assertions would fail to
242  // consider assumptions of threads that have a thread-id above that
243  // of the thread containing the assertion:
244  // T0 T1
245  // x=0; assume(x==1);
246  // assert(x!=42); x=42;
247  else
248  state.guard.add(rewritten_cond);
249 
250  if(state.atomic_section_id!=0 &&
251  state.guard.is_false())
252  symex_atomic_end(state);
253 }
254 
256 {
257  const bool is_assert = state.source.pc->is_assert();
258 
259  if(
260  (is_assert && expr.id() == ID_forall) ||
261  (!is_assert && expr.id() == ID_exists))
262  {
263  // for assertions e can rewrite "forall X. P" to "P", and
264  // for assumptions we can rewrite "exists X. P" to "P"
265  // we keep the quantified variable unique by means of L2 renaming
266  auto &quant_expr = to_quantifier_expr(expr);
267  symbol_exprt tmp0 =
268  to_symbol_expr(to_ssa_expr(quant_expr.symbol()).get_original_expr());
269  symex_decl(state, tmp0);
270  instruction_local_symbols.push_back(tmp0);
271  exprt tmp = quant_expr.where();
272  rewrite_quantifiers(tmp, state);
273  quant_expr.swap(tmp);
274  }
275  else if(expr.id() == ID_or || expr.id() == ID_and)
276  {
277  for(auto &op : expr.operands())
278  rewrite_quantifiers(op, state);
279  }
280 }
281 
282 static void
283 switch_to_thread(goto_symex_statet &state, const unsigned int thread_nb)
284 {
285  PRECONDITION(state.source.thread_nr < state.threads.size());
286  PRECONDITION(thread_nb < state.threads.size());
287 
288  // save PC
289  state.threads[state.source.thread_nr].pc = state.source.pc;
290  state.threads[state.source.thread_nr].atomic_section_id =
291  state.atomic_section_id;
292 
293  // get new PC
294  state.source.thread_nr = thread_nb;
295  state.source.pc = state.threads[thread_nb].pc;
296 
297  state.guard = state.threads[thread_nb].guard;
298  // A thread's initial state is certainly reachable:
299  state.reachable = true;
300 }
301 
303  statet &state, const get_goto_functiont &get_goto_function)
304 {
306 
307  _total_vccs = state.total_vccs;
309 
311  return;
312 
313  // is there another thread to execute?
314  if(state.call_stack().empty() &&
315  state.source.thread_nr+1<state.threads.size())
316  {
317  unsigned t=state.source.thread_nr+1;
318 #if 0
319  std::cout << "********* Now executing thread " << t << '\n';
320 #endif
321  switch_to_thread(state, t);
322  symex_transition(state, state.source.pc, false);
323  }
324 }
325 
327  statet &state,
328  const get_goto_functiont &get_goto_function,
329  symbol_tablet &new_symbol_table)
330 {
331  // resets the namespace to only wrap a single symbol table, and does so upon
332  // destruction of an object of this type; instantiating the type is thus all
333  // that's needed to achieve a reset upon exiting this method
334  struct reset_namespacet
335  {
336  explicit reset_namespacet(namespacet &ns) : ns(ns)
337  {
338  }
339 
340  ~reset_namespacet()
341  {
342  // Get symbol table 1, the outer symbol table from the GOTO program
343  const symbol_tablet &st = ns.get_symbol_table();
344  // Move a new namespace containing this symbol table over the top of the
345  // current one
346  ns = namespacet(st);
347  }
348 
349  namespacet &ns;
350  };
351 
352  // We'll be using ns during symbolic execution and it needs to know
353  // about the names minted in `state`, so make it point both to
354  // `state`'s symbol table and the symbol table of the original
355  // goto-program.
357 
358  // whichever way we exit this method, reset the namespace back to a sane state
359  // as state.symbol_table might go out of scope
360  reset_namespacet reset_ns(ns);
361 
362  PRECONDITION(state.call_stack().top().end_of_function->is_end_function());
363 
366  return;
367  while(!state.call_stack().empty())
368  {
369  state.has_saved_jump_target = false;
370  state.has_saved_next_instruction = false;
373  return;
374  }
375 
376  // Clients may need to construct a namespace with both the names in
377  // the original goto-program and the names generated during symbolic
378  // execution, so return the names generated through symbolic execution
379  // through `new_symbol_table`.
380  new_symbol_table = state.symbol_table;
381 }
382 
384  const get_goto_functiont &get_goto_function,
385  const statet &saved_state,
386  symex_target_equationt *const saved_equation,
387  symbol_tablet &new_symbol_table)
388 {
389  // saved_state contains a pointer to a symex_target_equationt that is
390  // almost certainly stale. This is because equations are owned by bmcts,
391  // and we construct a new bmct for every path that we execute. We're on a
392  // new path now, so the old bmct and the equation that it owned have now
393  // been deallocated. So, construct a new state from the old one, and make
394  // its equation member point to the (valid) equation passed as an argument.
395  statet state(saved_state, saved_equation);
396 
397  // Do NOT do the same initialization that `symex_with_state` does for a
398  // fresh state, as that would clobber the saved state's program counter
400  state,
402  new_symbol_table);
403 }
404 
405 std::unique_ptr<goto_symext::statet> goto_symext::initialize_entry_point_state(
406  const get_goto_functiont &get_goto_function)
407 {
408  const irep_idt entry_point_id = goto_functionst::entry_point();
409 
410  const goto_functionst::goto_functiont *start_function;
411  try
412  {
413  start_function = &get_goto_function(entry_point_id);
414  }
415  catch(const std::out_of_range &)
416  {
417  throw unsupported_operation_exceptiont("the program has no entry point");
418  }
419 
420  // Get our path_storage pointer because this state will live beyond
421  // this instance of goto_symext, so we can't take the reference directly.
422  auto *storage = &path_storage;
423 
424  // create and prepare the state
425  auto state = util_make_unique<statet>(
426  symex_targett::sourcet(entry_point_id, start_function->body),
429  [storage](const irep_idt &id) { return storage->get_unique_l2_index(id); });
430 
431  CHECK_RETURN(!state->threads.empty());
432  CHECK_RETURN(!state->call_stack().empty());
433 
435  std::prev(start_function->body.instructions.end());
436  state->call_stack().top().end_of_function = limit;
437  state->call_stack().top().calling_location.pc =
438  state->call_stack().top().end_of_function;
439  state->call_stack().top().hidden_function = start_function->is_hidden();
440 
441  state->symex_target = &target;
442 
443  state->run_validation_checks = symex_config.run_validation_checks;
444 
445  // initialize support analyses
446  auto emplace_safe_pointers_result =
447  path_storage.safe_pointers.emplace(entry_point_id, local_safe_pointerst{});
448  if(emplace_safe_pointers_result.second)
449  emplace_safe_pointers_result.first->second(start_function->body);
450 
452  entry_point_id, *start_function);
453  state->dirty = &path_storage.dirty;
454 
455  // Only enable loop analysis when complexity is enabled.
457  {
458  // Set initial loop analysis.
459  path_storage.add_function_loops(entry_point_id, start_function->body);
460  state->call_stack().top().loops_info =
461  path_storage.get_loop_analysis(entry_point_id);
462  }
463 
464  // make the first step onto the instruction pointed to by the initial program
465  // counter
466  symex_transition(*state, state->source.pc, false);
467 
468  return state;
469 }
470 
472  const get_goto_functiont &get_goto_function,
473  symbol_tablet &new_symbol_table)
474 {
476 
477  symex_with_state(*state, get_goto_function, new_symbol_table);
478 }
479 
481  const get_goto_functiont &get_goto_function,
482  symbol_tablet &new_symbol_table)
483 {
485 
486  path_storaget::patht entry_point_start(target, *state);
487  entry_point_start.state.saved_target = state->source.pc;
488  entry_point_start.state.has_saved_next_instruction = true;
489 
490  path_storage.push(entry_point_start);
491 }
492 
495 {
496  return [&goto_model](
497  const irep_idt &id) -> const goto_functionst::goto_functiont & {
498  return goto_model.get_goto_function(id);
499  };
500 }
501 
504 {
505  log.status() << source.function_id
506  << " location number: " << source.pc->location_number;
507 
508  return log.status();
509 }
510 
512 {
513  // If we're showing the route, begin outputting debug info, and don't print
514  // instructions we don't run.
515 
516  // We also skip dead instructions as they don't add much to step-based
517  // debugging and if there's no code block at this point.
518  if(
520  state.source.pc->type == DEAD ||
521  (state.source.pc->get_code().is_nil() &&
522  state.source.pc->type != END_FUNCTION))
523  {
524  return;
525  }
526 
527  if(state.source.pc->get_code().is_not_nil())
528  {
529  auto guard_expression = state.guard.as_expr();
530  std::size_t size = 0;
531  for(auto it = guard_expression.depth_begin();
532  it != guard_expression.depth_end();
533  ++it)
534  {
535  size++;
536  }
537 
538  log.status() << "[Guard size: " << size << "] "
539  << format(state.source.pc->get_code());
540 
541  if(
542  state.source.pc->source_location.is_not_nil() &&
543  !state.source.pc->source_location.get_java_bytecode_index().empty())
544  {
545  log.status()
546  << " bytecode index: "
547  << state.source.pc->source_location.get_java_bytecode_index();
548  }
549 
550  log.status() << messaget::eom;
551  }
552 
553  // Print the method we're returning too.
554  const auto &call_stack = state.threads[state.source.thread_nr].call_stack;
555  if(state.source.pc->type == END_FUNCTION)
556  {
557  log.status() << messaget::eom;
558 
559  if(!call_stack.empty())
560  {
561  log.status() << "Returning to: ";
562  print_callstack_entry(call_stack.back().calling_location)
563  << messaget::eom;
564  }
565 
566  log.status() << messaget::eom;
567  }
568 
569  // On a function call print the entire call stack.
570  if(state.source.pc->type == FUNCTION_CALL)
571  {
572  log.status() << messaget::eom;
573 
574  if(!call_stack.empty())
575  {
576  log.status() << "Call stack:" << messaget::eom;
577 
578  for(auto &frame : call_stack)
579  {
580  print_callstack_entry(frame.calling_location) << messaget::eom;
581  }
582 
584 
585  // Add the method we're about to enter with no location number.
586  log.status() << format(state.source.pc->get_function_call().function())
588  }
589  }
590 }
591 
594  const get_goto_functiont &get_goto_function,
595  statet &state)
596 {
597  // Print debug statements if they've been enabled.
598  print_symex_step(state);
601 }
602 
604  const get_goto_functiont &get_goto_function,
605  statet &state)
606 {
607  PRECONDITION(!state.threads.empty());
608  PRECONDITION(!state.call_stack().empty());
609 
610  const goto_programt::instructiont &instruction=*state.source.pc;
611 
613  merge_gotos(state);
614 
615  // depth exceeded?
617  {
618  // Rule out this path:
619  symex_assume_l2(state, false_exprt());
620  }
621  state.depth++;
622 
623  // actually do instruction
624  switch(instruction.type)
625  {
626  case SKIP:
627  if(state.reachable)
628  target.location(state.guard.as_expr(), state.source);
629  symex_transition(state);
630  break;
631 
632  case END_FUNCTION:
633  // do even if !state.reachable to clear out frame created
634  // in symex_start_thread
635  symex_end_of_function(state);
636  symex_transition(state);
637  break;
638 
639  case LOCATION:
640  if(state.reachable)
641  target.location(state.guard.as_expr(), state.source);
642  symex_transition(state);
643  break;
644 
645  case GOTO:
646  if(state.reachable)
647  symex_goto(state);
648  else
649  symex_unreachable_goto(state);
650  break;
651 
652  case ASSUME:
653  if(state.reachable)
654  symex_assume(state, instruction.get_condition());
655  symex_transition(state);
656  break;
657 
658  case ASSERT:
659  if(state.reachable && !ignore_assertions)
660  symex_assert(instruction, state);
661  symex_transition(state);
662  break;
663 
664  case RETURN:
665  // This case should have been removed by return-value removal
666  UNREACHABLE;
667  break;
668 
669  case ASSIGN:
670  if(state.reachable)
671  symex_assign(
672  state, instruction.get_assign().lhs(), instruction.get_assign().rhs());
673 
674  symex_transition(state);
675  break;
676 
677  case FUNCTION_CALL:
678  if(state.reachable)
679  {
681  get_goto_function, state, instruction.get_function_call());
682  }
683  else
684  symex_transition(state);
685  break;
686 
687  case OTHER:
688  if(state.reachable)
689  symex_other(state);
690  symex_transition(state);
691  break;
692 
693  case DECL:
694  if(state.reachable)
695  symex_decl(state);
696  symex_transition(state);
697  break;
698 
699  case DEAD:
700  symex_dead(state);
701  symex_transition(state);
702  break;
703 
704  case START_THREAD:
705  symex_start_thread(state);
706  symex_transition(state);
707  break;
708 
709  case END_THREAD:
710  // behaves like assume(0);
711  if(state.reachable)
712  state.reachable = false;
713  symex_transition(state);
714  break;
715 
716  case ATOMIC_BEGIN:
717  symex_atomic_begin(state);
718  symex_transition(state);
719  break;
720 
721  case ATOMIC_END:
722  symex_atomic_end(state);
723  symex_transition(state);
724  break;
725 
726  case CATCH:
727  symex_catch(state);
728  symex_transition(state);
729  break;
730 
731  case THROW:
732  symex_throw(state);
733  symex_transition(state);
734  break;
735 
736  case NO_INSTRUCTION_TYPE:
737  throw unsupported_operation_exceptiont("symex got NO_INSTRUCTION");
738 
739  case INCOMPLETE_GOTO:
740  DATA_INVARIANT(false, "symex got unexpected instruction type");
741  }
742 
743  complexity_violationt complexity_result =
745  if(complexity_result != complexity_violationt::NONE)
746  complexity_module.run_transformations(complexity_result, state);
747 }
748 
750 {
751  for(const auto &symbol_expr : instruction_local_symbols)
752  symex_dead(state, symbol_expr);
754 }
755 
763 {
764  optionalt<symbol_exprt> return_value;
765  for(auto it = expr.depth_cbegin(); it != expr.depth_cend(); ++it)
766  {
767  const symbol_exprt *symbol_expr = expr_try_dynamic_cast<symbol_exprt>(*it);
768  if(symbol_expr && can_cast_type<pointer_typet>(symbol_expr->type()))
769  {
770  // If we already have a potential return value, check if it is the same
771  // symbol, and return an empty optionalt if not
772  if(return_value && *symbol_expr != *return_value)
773  {
774  return {};
775  }
776  return_value = *symbol_expr;
777  }
778  }
779 
780  // Either expr contains no pointer-typed symbols or it contains one unique
781  // pointer-typed symbol, possibly repeated multiple times
782  return return_value;
783 }
784 
786  goto_symex_statet &state,
787  exprt condition,
788  const value_sett &original_value_set,
789  value_sett *jump_taken_value_set,
790  value_sett *jump_not_taken_value_set,
791  const namespacet &ns)
792 {
793  condition = state.rename<L1>(std::move(condition), ns).get();
794 
795  optionalt<symbol_exprt> symbol_expr =
797 
798  if(!symbol_expr)
799  {
800  return;
801  }
802 
803  const pointer_typet &symbol_type = to_pointer_type(symbol_expr->type());
804 
805  const std::vector<exprt> value_set_elements =
806  original_value_set.get_value_set(*symbol_expr, ns);
807 
808  std::unordered_set<exprt, irep_hash> erase_from_jump_taken_value_set;
809  std::unordered_set<exprt, irep_hash> erase_from_jump_not_taken_value_set;
810  erase_from_jump_taken_value_set.reserve(value_set_elements.size());
811  erase_from_jump_not_taken_value_set.reserve(value_set_elements.size());
812 
813  // Try evaluating the condition with the symbol replaced by a pointer to each
814  // one of its possible values in turn. If that leads to a true for some
815  // value_set_element then we can delete it from the value set that will be
816  // used if the condition is false, and vice versa.
817  for(const exprt &value_set_element : value_set_elements)
818  {
819  if(
820  value_set_element.id() == ID_unknown ||
821  value_set_element.id() == ID_invalid)
822  {
823  continue;
824  }
825 
826  const bool exclude_null_derefs = false;
828  value_set_element, exclude_null_derefs, language_mode))
829  {
830  continue;
831  }
832 
835  value_set_element, *symbol_expr, ns);
836 
837  if(value.pointer.is_nil())
838  continue;
839 
840  exprt modified_condition(condition);
841 
842  address_of_aware_replace_symbolt replace_symbol{};
843  replace_symbol.insert(*symbol_expr, value.pointer);
844  replace_symbol(modified_condition);
845 
846  // This do_simplify() is needed for the following reason: if `condition` is
847  // `*p == a` and we replace `p` with `&a` then we get `*&a == a`. Suppose
848  // our constant propagation knows that `a` is `1`. Without this call to
849  // do_simplify(), state.rename() turns this into `*&a == 1` (because
850  // rename() doesn't do constant propagation inside addresses), which
851  // do_simplify() turns into `a == 1`, which cannot be evaluated as true
852  // without another round of constant propagation.
853  // It would be sufficient to replace this call to do_simplify() with
854  // something that just replaces `*&x` with `x` whenever it finds it.
855  do_simplify(modified_condition);
856 
857  state.record_events.push(false);
858  modified_condition = state.rename(std::move(modified_condition), ns).get();
859  state.record_events.pop();
860 
861  do_simplify(modified_condition);
862 
863  if(jump_taken_value_set && modified_condition.is_false())
864  {
865  erase_from_jump_taken_value_set.insert(value_set_element);
866  }
867  else if(jump_not_taken_value_set && modified_condition.is_true())
868  {
869  erase_from_jump_not_taken_value_set.insert(value_set_element);
870  }
871  }
872  if(jump_taken_value_set && !erase_from_jump_taken_value_set.empty())
873  {
874  auto entry_index = jump_taken_value_set->get_index_of_symbol(
875  symbol_expr->get_identifier(), symbol_type, "", ns);
876  jump_taken_value_set->erase_values_from_entry(
877  *entry_index, erase_from_jump_taken_value_set);
878  }
879  if(jump_not_taken_value_set && !erase_from_jump_not_taken_value_set.empty())
880  {
881  auto entry_index = jump_not_taken_value_set->get_index_of_symbol(
882  symbol_expr->get_identifier(), symbol_type, "", ns);
883  jump_not_taken_value_set->erase_values_from_entry(
884  *entry_index, erase_from_jump_not_taken_value_set);
885  }
886 }
goto_symext::symex_with_state
virtual void symex_with_state(statet &state, const get_goto_functiont &get_goto_functions, symbol_tablet &new_symbol_table)
Symbolically execute the entire program starting from entry point.
Definition: symex_main.cpp:326
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:504
goto_symext::clean_expr
exprt clean_expr(exprt expr, statet &state, bool write)
Clean up an expression.
Definition: symex_clean_expr.cpp:233
exception_utils.h
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:37
address_of_aware_replace_symbolt
Replace symbols with constants while maintaining syntactically valid expressions.
Definition: replace_symbol.h:120
source_locationt::get_comment
const irep_idt & get_comment() const
Definition: source_location.h:71
goto_symext::symex_step
virtual void symex_step(const get_goto_functiont &get_goto_function, statet &state)
Called for each step in the symbolic execution This calls print_symex_step to print symex's current i...
Definition: symex_main.cpp:593
format
static format_containert< T > format(const T &o)
Definition: format.h:37
framet::active_loops
std::vector< active_loop_infot > active_loops
Definition: frame.h:69
symbol_tablet
The symbol table.
Definition: symbol_table.h:20
goto_symext::symex_assume_l2
void symex_assume_l2(statet &, const exprt &cond)
Definition: symex_main.cpp:223
complexity_violationt::NONE
@ NONE
exprt::depth_cbegin
const_depth_iteratort depth_cbegin() const
Definition: expr.cpp:300
goto_programt::instructiont::source_location
source_locationt source_location
The location of the instruction in the source file.
Definition: goto_program.h:347
value_set_dereferencet::valuet
Return value for build_reference_to; see that method for documentation.
Definition: value_set_dereference.h:70
has_subexpr
bool has_subexpr(const exprt &expr, const std::function< bool(const exprt &)> &pred)
returns true if the expression has a subexpression that satisfies pred
Definition: expr_util.cpp:141
goto_symex_statet::remaining_vccs
unsigned remaining_vccs
Definition: goto_symex_state.h:229
goto_statet::apply_condition
void apply_condition(const exprt &condition, const goto_symex_statet &previous_state, const namespacet &ns)
Given a condition that must hold on this path, propagate as much knowledge as possible.
Definition: goto_state.cpp:42
goto_symext::instruction_local_symbols
std::vector< symbol_exprt > instruction_local_symbols
Variables that should be killed at the end of the current symex_step invocation.
Definition: goto_symex.h:273
goto_symext::symex_unreachable_goto
void symex_unreachable_goto(statet &state)
Symbolically execute a GOTO instruction in the context of unreachable code.
Definition: symex_goto.cpp:532
symex_target_equationt::assumption
virtual void assumption(const exprt &guard, const exprt &cond, const sourcet &source)
Record an assumption.
Definition: symex_target_equation.cpp:272
goto_symext::kill_instruction_local_symbols
void kill_instruction_local_symbols(statet &state)
Kills any variables in instruction_local_symbols (these are currently always let-bound variables defi...
Definition: symex_main.cpp:749
L1
@ L1
Definition: renamed.h:18
goto_symext::try_filter_value_sets
void try_filter_value_sets(goto_symex_statet &state, exprt condition, const value_sett &original_value_set, value_sett *jump_taken_value_set, value_sett *jump_not_taken_value_set, const namespacet &ns)
Try to filter value sets based on whether possible values of a pointer-typed symbol make the conditio...
Definition: symex_main.cpp:785
optionst
Definition: options.h:23
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:496
code_assignt::rhs
exprt & rhs()
Definition: std_code.h:317
goto_statet::reachable
bool reachable
Is this code reachable? If not we can take shortcuts such as not entering function calls,...
Definition: goto_state.h:62
symex_targett::sourcet::pc
goto_programt::const_targett pc
Definition: symex_target.h:43
guard_exprt::guard_expr
exprt guard_expr(exprt expr) const
Return guard => dest or a simplified variant thereof if either guard or dest are trivial.
Definition: guard_expr.cpp:20
messaget::status
mstreamt & status() const
Definition: message.h:414
goto_symext::target
symex_target_equationt & target
The equation that this execution is building up.
Definition: goto_symex.h:264
goto_symext::resume_symex_from_saved_state
virtual void resume_symex_from_saved_state(const get_goto_functiont &get_goto_function, const statet &saved_state, symex_target_equationt *saved_equation, symbol_tablet &new_symbol_table)
Performs symbolic execution using a state and equation that have already been used to symbolically ex...
Definition: symex_main.cpp:383
value_set_dereference.h
Pointer Dereferencing.
goto_symex_statet::has_saved_jump_target
bool has_saved_jump_target
This state is saved, with the PC pointing to the target of a GOTO.
Definition: goto_symex_state.h:219
goto_symext::path_storage
path_storaget & path_storage
Symbolic execution paths to be resumed later.
Definition: goto_symex.h:802
goto_symex_statet
Central data structure: state.
Definition: goto_symex_state.h:46
unsupported_operation_exceptiont
Thrown when we encounter an instruction, parameters to an instruction etc.
Definition: exception_utils.h:144
goto_programt::instructiont::type
goto_program_instruction_typet type
What kind of instruction?
Definition: goto_program.h:350
replace_symbol.h
local_safe_pointerst
A very simple, cheap analysis to determine when dereference operations are trivially guarded by a che...
Definition: local_safe_pointers.h:27
goto_symext::ignore_assertions
bool ignore_assertions
If this flag is set to true then assertions will be temporarily ignored by the symbolic executions.
Definition: goto_symex.h:169
format.h
goto_symext::guard_manager
guard_managert & guard_manager
Used to create guards.
Definition: goto_symex.h:261
symex_targett::sourcet::thread_nr
unsigned thread_nr
Definition: symex_target.h:39
invariant.h
goto_symext::initialize_path_storage_from_entry_point_of
virtual void initialize_path_storage_from_entry_point_of(const get_goto_functiont &get_goto_function, symbol_tablet &new_symbol_table)
Puts the initial state of the entry point function into the path storage.
Definition: symex_main.cpp:480
DEFAULT_MAX_FIELD_SENSITIVITY_ARRAY_SIZE
constexpr std::size_t DEFAULT_MAX_FIELD_SENSITIVITY_ARRAY_SIZE
Limit the size of arrays for which field_sensitivity gets applied.
Definition: magic.h:21
value_set_dereferencet::should_ignore_value
static bool should_ignore_value(const exprt &what, bool exclude_null_derefs, const irep_idt &language_mode)
Determine whether possible alias what should be ignored when replacing a pointer by its referees.
Definition: value_set_dereference.cpp:407
value_sett
State type in value_set_domaint, used in value-set analysis and goto-symex.
Definition: value_set.h:45
exprt
Base class for all expressions.
Definition: expr.h:54
goto_symext::merge_gotos
void merge_gotos(statet &state)
Merge all branches joining at the current program point.
Definition: symex_goto.cpp:611
complexity_violationt
complexity_violationt
What sort of symex-complexity violation has taken place.
Definition: complexity_violation.h:18
goto_symex_statet::source
symex_targett::sourcet source
Definition: goto_symex_state.h:64
symex_configt::show_symex_steps
bool show_symex_steps
Prints out the path that symex is actively taking during execution, includes diagnostic information a...
Definition: symex_config.h:48
messaget::eom
static eomt eom
Definition: message.h:297
goto_symext::symex_dead
virtual void symex_dead(statet &state)
Symbolically execute a DEAD instruction.
Definition: symex_dead.cpp:19
exprt::is_true
bool is_true() const
Return whether the expression is a constant representing true.
Definition: expr.cpp:60
goto_symext::symex_catch
void symex_catch(statet &state)
Symbolically execute a CATCH instruction.
Definition: symex_catch.cpp:14
switch_to_thread
static void switch_to_thread(goto_symex_statet &state, const unsigned int thread_nb)
Definition: symex_main.cpp:283
symbol_exprt
Expression to hold a symbol (variable)
Definition: std_expr.h:80
goto_symext::complexity_module
complexity_limitert complexity_module
Definition: goto_symex.h:828
ssa_exprt::get_original_expr
const exprt & get_original_expr() const
Definition: ssa_expr.h:33
goto_symext::symex_throw
void symex_throw(statet &state)
Symbolically execute a THROW instruction.
Definition: symex_throw.cpp:14
can_cast_type< pointer_typet >
bool can_cast_type< pointer_typet >(const typet &type)
Check whether a reference to a typet is a pointer_typet.
Definition: pointer_expr.h:49
goto_symext::initialize_entry_point_state
std::unique_ptr< statet > initialize_entry_point_state(const get_goto_functiont &get_goto_function)
Initialize the symbolic execution and the given state with the beginning of the entry point function.
Definition: symex_main.cpp:405
goto_programt::instructiont::get_assign
const code_assignt & get_assign() const
Get the assignment for ASSIGN.
Definition: goto_program.h:199
exprt::is_false
bool is_false() const
Return whether the expression is a constant representing false.
Definition: expr.cpp:69
goto_symext::path_segment_vccs
std::size_t path_segment_vccs
Number of VCCs generated during the run of this goto_symext object.
Definition: goto_symex.h:814
symex_transition
void symex_transition(goto_symext::statet &state, goto_programt::const_targett to, bool is_backwards_goto)
Definition: symex_main.cpp:80
goto_programt::loop_id
static irep_idt loop_id(const irep_idt &function_id, const instructiont &instruction)
Human-readable loop name.
Definition: goto_program.h:739
goto_symext::log
messaget log
The messaget to write log messages to.
Definition: goto_symex.h:276
symex_target_equationt::location
virtual void location(const exprt &guard, const sourcet &source)
Record a location.
Definition: symex_target_equation.cpp:173
pop_exited_loops
static void pop_exited_loops(const goto_programt::const_targett &to, std::vector< framet::active_loop_infot > &active_loops)
If 'to' is not an instruction in our currently top-most active loop, pop and re-check until we find a...
Definition: symex_main.cpp:67
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:92
string2int.h
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:82
THROW
@ THROW
Definition: goto_program.h:51
symex_configt::max_field_sensitivity_array_size
std::size_t max_field_sensitivity_array_size
Maximum sizes for which field sensitivity will be applied to array cells.
Definition: symex_config.h:52
goto_symex_statet::threads
std::vector< threadt > threads
Definition: goto_symex_state.h:198
goto_symext::symex_atomic_end
virtual void symex_atomic_end(statet &state)
Symbolically execute an ATOMIC_END instruction.
Definition: symex_atomic_section.cpp:36
GOTO
@ GOTO
Definition: goto_program.h:35
path_storaget::get_loop_analysis
std::shared_ptr< lexical_loopst > get_loop_analysis(const irep_idt &function_id)
Definition: path_storage.h:131
framet::loops_info
std::shared_ptr< lexical_loopst > loops_info
Definition: frame.h:68
goto_symex_statet::call_stack
call_stackt & call_stack()
Definition: goto_symex_state.h:147
make_unique.h
goto_symext::outer_symbol_table
const symbol_tablet & outer_symbol_table
The symbol table associated with the goto-program being executed.
Definition: goto_symex.h:247
goto_symex_statet::has_saved_next_instruction
bool has_saved_next_instruction
This state is saved, with the PC pointing to the next instruction of a GOTO.
Definition: goto_symex_state.h:223
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:511
call_stackt::top
framet & top()
Definition: call_stack.h:17
to_ssa_expr
const ssa_exprt & to_ssa_expr(const exprt &expr)
Cast a generic exprt to an ssa_exprt.
Definition: ssa_expr.h:145
goto_symext::symex_goto
virtual void symex_goto(statet &state)
Symbolically execute a GOTO instruction.
Definition: symex_goto.cpp:227
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:49
goto_symex_statet::symbol_table
symbol_tablet symbol_table
contains symbols that are minted during symbolic execution, such as dynamically created objects etc.
Definition: goto_symex_state.h:69
value_set_dereferencet::valuet::pointer
exprt pointer
Definition: value_set_dereference.h:73
path_storaget::push
virtual void push(const patht &)=0
Add a path to resume to the storage.
goto_symex_statet::total_vccs
unsigned total_vccs
Definition: goto_symex_state.h:228
goto_statet::depth
unsigned depth
Distance from entry.
Definition: goto_state.h:35
value_sett::get_value_set
std::vector< exprt > get_value_set(exprt expr, const namespacet &ns) const
Gets values pointed to by expr, including following dereference operators (i.e.
Definition: value_set.cpp:352
guard_exprt::as_expr
exprt as_expr() const
Definition: guard_expr.h:49
goto_symext::symex_decl
virtual void symex_decl(statet &state)
Symbolically execute a DECL instruction.
Definition: symex_decl.cpp:16
goto_symext::_remaining_vccs
unsigned _remaining_vccs
Definition: goto_symex.h:825
guard_exprt::add
void add(const exprt &expr)
Definition: guard_expr.cpp:40
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:464
symex_configt::doing_path_exploration
bool doing_path_exploration
Definition: symex_config.h:23
goto_symext::symex_from_entry_point_of
virtual void symex_from_entry_point_of(const get_goto_functiont &get_goto_function, symbol_tablet &new_symbol_table)
Symbolically execute the entire program starting from entry point.
Definition: symex_main.cpp:471
incremental_dirtyt::populate_dirty_for_function
void populate_dirty_for_function(const irep_idt &id, const goto_functionst::goto_functiont &function)
Analyse the given function with dirtyt if it hasn't been seen before.
Definition: dirty.cpp:78
goto_symex.h
Symbolic Execution.
goto_statet::guard
guardt guard
Definition: goto_state.h:58
framet::loop_iterations
std::unordered_map< irep_idt, loop_infot > loop_iterations
Definition: frame.h:71
std_types.h
Pre-defined types.
code_assignt::lhs
exprt & lhs()
Definition: std_code.h:312
goto_programt::instructiont::get_function_call
const code_function_callt & get_function_call() const
Get the function call for FUNCTION_CALL.
Definition: goto_program.h:319
complexity_limitert::run_transformations
void run_transformations(complexity_violationt complexity_violation, goto_symex_statet &current_state)
Runs a suite of transformations on the state and symex executable, performing whatever transformation...
Definition: complexity_limiter.cpp:204
goto_symext::symex_end_of_function
virtual void symex_end_of_function(statet &)
Symbolically execute a END_FUNCTION instruction.
Definition: symex_function_call.cpp:405
to_pointer_type
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
Definition: pointer_expr.h:62
NO_INSTRUCTION_TYPE
@ NO_INSTRUCTION_TYPE
Definition: goto_program.h:34
path_storaget::dirty
incremental_dirtyt dirty
Local variables are considered 'dirty' if they've had an address taken and therefore may be referred ...
Definition: path_storage.h:116
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:189
OTHER
@ OTHER
Definition: goto_program.h:38
symex_configt::max_depth
unsigned max_depth
The maximum depth to take the execution to.
Definition: symex_config.h:21
irept::is_nil
bool is_nil() const
Definition: irep.h:387
irept::id
const irep_idt & id() const
Definition: irep.h:407
framet::end_of_function
goto_programt::const_targett end_of_function
Definition: frame.h:32
path_storaget::add_function_loops
void add_function_loops(const irep_idt &identifier, const goto_programt &body)
Generates a loop analysis for the instructions in goto_programt and keys it against function ID.
Definition: path_storage.h:120
false_exprt
The Boolean constant false.
Definition: std_expr.h:2725
framet
Stack frames – these are used for function calls and for exceptions.
Definition: frame.h:21
END_FUNCTION
@ END_FUNCTION
Definition: goto_program.h:43
SKIP
@ SKIP
Definition: goto_program.h:39
guard_exprt::is_false
bool is_false() const
Definition: guard_expr.h:68
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
path_storaget::patht
Information saved at a conditional goto to resume execution.
Definition: path_storage.h:42
goto_symext::do_simplify
virtual void do_simplify(exprt &expr)
Definition: goto_symex.cpp:33
goto_symext::symex_threaded_step
void symex_threaded_step(statet &state, const get_goto_functiont &get_goto_function)
Invokes symex_step and verifies whether additional threads can be executed.
Definition: symex_main.cpp:302
symex_target_equationt
Inheriting the interface of symex_targett this class represents the SSA form of the input program as ...
Definition: symex_target_equation.h:41
goto_functionst::goto_functiont
::goto_functiont goto_functiont
Definition: goto_functions.h:25
RETURN
@ RETURN
Definition: goto_program.h:46
goto_symext::ns
namespacet ns
Initialized just before symbolic execution begins, to point to both outer_symbol_table and the symbol...
Definition: goto_symex.h:256
expr_util.h
Deprecated expression utility functions.
ASSIGN
@ ASSIGN
Definition: goto_program.h:47
symex_target_equationt::assertion
virtual void assertion(const exprt &guard, const exprt &cond, const std::string &msg, const sourcet &source)
Record an assertion.
Definition: symex_target_equation.cpp:286
format_expr.h
namespacet::get_symbol_table
const symbol_table_baset & get_symbol_table() const
Return first symbol table registered with the namespace.
Definition: namespace.h:124
CATCH
@ CATCH
Definition: goto_program.h:52
symex_configt::complexity_limits_active
bool complexity_limits_active
Whether this run of symex is under complexity limits.
Definition: symex_config.h:56
expr_iterator.h
Forward depth-first search iterators These iterators' copy operations are expensive,...
goto_symext::language_mode
irep_idt language_mode
language_mode: ID_java, ID_C or another language identifier if we know the source language in use,...
Definition: goto_symex.h:239
DECL
@ DECL
Definition: goto_program.h:48
unchecked_replace_symbolt::insert
void insert(const symbol_exprt &old_expr, const exprt &new_expr)
Definition: replace_symbol.cpp:249
goto_symext::execute_next_instruction
void execute_next_instruction(const get_goto_functiont &get_goto_function, statet &state)
Executes the instruction state.source.pc Case-switches over the type of the instruction being execute...
Definition: symex_main.cpp:603
path_storaget::safe_pointers
std::unordered_map< irep_idt, local_safe_pointerst > safe_pointers
Map function identifiers to local_safe_pointerst instances.
Definition: path_storage.h:100
goto_programt::instructiont::incoming_edges
std::set< targett > incoming_edges
Definition: goto_program.h:412
to_quantifier_expr
const quantifier_exprt & to_quantifier_expr(const exprt &expr)
Cast an exprt to a quantifier_exprt.
Definition: mathematical_expr.h:316
path_storaget::patht::state
goto_symex_statet state
Definition: path_storage.h:44
exprt::depth_cend
const_depth_iteratort depth_cend() const
Definition: expr.cpp:302
goto_statet::atomic_section_id
unsigned atomic_section_id
Threads.
Definition: goto_state.h:76
ASSUME
@ ASSUME
Definition: goto_program.h:36
abstract_goto_modelt::get_goto_function
virtual const goto_functionst::goto_functiont & get_goto_function(const irep_idt &id)=0
Get a GOTO function by name, or throw if no such function exists.
optionst::get_bool_option
bool get_bool_option(const std::string &option) const
Definition: options.cpp:44
value_sett::get_index_of_symbol
optionalt< irep_idt > get_index_of_symbol(irep_idt identifier, const typet &type, const std::string &suffix, const namespacet &ns) const
Get the index of the symbol and suffix.
Definition: value_set.cpp:396
goto_symext::symex_assume
virtual void symex_assume(statet &state, const exprt &cond)
Symbolically execute an ASSUME instruction or simulate such an execution for a synthetic assumption.
Definition: symex_main.cpp:203
goto_symext::vcc
virtual void vcc(const exprt &, const std::string &msg, statet &)
Definition: symex_main.cpp:186
goto_symext::get_goto_function
static get_goto_functiont get_goto_function(abstract_goto_modelt &goto_model)
Return a function to get/load a goto function from the given goto model Create a default delegate to ...
Definition: symex_main.cpp:494
goto_symext::_total_vccs
unsigned _total_vccs
Definition: goto_symex.h:825
goto_symext::symex_config
const symex_configt symex_config
The configuration to use for this symbolic execution.
Definition: goto_symex.h:183
START_THREAD
@ START_THREAD
Definition: goto_program.h:40
FUNCTION_CALL
@ FUNCTION_CALL
Definition: goto_program.h:50
value_set_dereferencet::build_reference_to
static valuet build_reference_to(const exprt &what, const exprt &pointer, const namespacet &ns)
Definition: value_set_dereference.cpp:444
goto_symext::print_callstack_entry
messaget::mstreamt & print_callstack_entry(const symex_targett::sourcet &target)
Definition: symex_main.cpp:503
goto_symext::get_goto_functiont
std::function< const goto_functionst::goto_functiont &(const irep_idt &)> get_goto_functiont
The type of delegate functions that retrieve a goto_functiont for a particular function identifier.
Definition: goto_symex.h:95
goto_symex_statet::record_events
std::stack< bool > record_events
Definition: goto_symex_state.h:212
find_unique_pointer_typed_symbol
static optionalt< symbol_exprt > find_unique_pointer_typed_symbol(const exprt &expr)
Check if an expression only contains one unique symbol (possibly repeated multiple times)
Definition: symex_main.cpp:762
messaget::mstreamt
Definition: message.h:224
ATOMIC_END
@ ATOMIC_END
Definition: goto_program.h:45
goto_programt::const_targett
instructionst::const_iterator const_targett
Definition: goto_program.h:564
goto_symex_statet::rename
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...
abstract_goto_modelt
Abstract interface to eager or lazy GOTO models.
Definition: abstract_goto_model.h:21
goto_symex_statet::saved_target
goto_programt::const_targett saved_target
Definition: goto_symex_state.h:216
DEAD
@ DEAD
Definition: goto_program.h:49
exprt::operands
operandst & operands()
Definition: expr.h:96
symex_targett::sourcet
Identifies source in the context of symbolic execution.
Definition: symex_target.h:38
goto_symext::symex_atomic_begin
virtual void symex_atomic_begin(statet &state)
Symbolically execute an ATOMIC_BEGIN instruction.
Definition: symex_atomic_section.cpp:16
goto_functionst::entry_point
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
Definition: goto_functions.h:90
complexity_limitert::check_complexity
complexity_violationt check_complexity(goto_symex_statet &state)
Checks the passed-in state to see if its become too complex for us to deal with, and if so set its gu...
Definition: complexity_limiter.cpp:134
ATOMIC_BEGIN
@ ATOMIC_BEGIN
Definition: goto_program.h:44
symex_configt::run_validation_checks
bool run_validation_checks
Should the additional validation checks be run? If this flag is set the checks for renaming (both lev...
Definition: symex_config.h:44
symbol_table.h
Author: Diffblue Ltd.
pointer_typet
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
Definition: pointer_expr.h:24
goto_symext::symex_function_call
virtual void symex_function_call(const get_goto_functiont &get_goto_function, statet &state, const code_function_callt &code)
Symbolically execute a FUNCTION_CALL instruction.
Definition: symex_function_call.cpp:177
symex_targett::sourcet::function_id
irep_idt function_id
Definition: symex_target.h:40
goto_programt::instructiont::get_condition
const exprt & get_condition() const
Get the condition of gotos, assume, assert.
Definition: goto_program.h:363
LOCATION
@ LOCATION
Definition: goto_program.h:42
goto_symext::print_symex_step
void print_symex_step(statet &state)
Prints the route of symex as it walks through the code.
Definition: symex_main.cpp:511
goto_symext::symex_assert
void symex_assert(const goto_programt::instructiont &, statet &)
Definition: symex_main.cpp:158
symex_configt::symex_configt
symex_configt(const optionst &options)
Construct a symex_configt using options specified in an optionst.
Definition: symex_main.cpp:34
ASSERT
@ ASSERT
Definition: goto_program.h:37
value_sett::erase_values_from_entry
void erase_values_from_entry(const irep_idt &index, const std::unordered_set< exprt, irep_hash > &values_to_erase)
Update the entry stored at index by erasing any values listed in values_to_erase.
Definition: value_set.cpp:1643
goto_programt::instructiont
This class represents an instruction in the GOTO intermediate representation.
Definition: goto_program.h:180
std_expr.h
API to expression classes.
goto_symext::symex_assign
void symex_assign(statet &state, const exprt &lhs, const exprt &rhs)
Symbolically execute an ASSIGN instruction or simulate such an execution for a synthetic assignment.
Definition: goto_symex.cpp:39
goto_statet::value_set
value_sett value_set
Uses level 1 names, and is used to do dereferencing.
Definition: goto_state.h:51
goto_symext::rewrite_quantifiers
void rewrite_quantifiers(exprt &, statet &)
Definition: symex_main.cpp:255
goto_symext::symex_other
virtual void symex_other(statet &state)
Symbolically execute an OTHER instruction.
Definition: symex_other.cpp:74
goto_symext::symex_start_thread
virtual void symex_start_thread(statet &state)
Symbolically execute a START_THREAD instruction.
Definition: symex_start_thread.cpp:20
format_type.h
END_THREAD
@ END_THREAD
Definition: goto_program.h:41
INCOMPLETE_GOTO
@ INCOMPLETE_GOTO
Definition: goto_program.h:53
unsafe_string2int
int unsafe_string2int(const std::string &str, int base)
Definition: string2int.cpp:33
goto_symext::should_pause_symex
bool should_pause_symex
Set when states are pushed onto the workqueue If this flag is set at the end of a symbolic execution ...
Definition: goto_symex.h:165
mathematical_expr.h
API to expression classes for 'mathematical' expressions.