CBMC
call_stack_history.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Abstract Interpretation
4 
5 Author: Martin Brain, martin.brain@cs.ox.ac.uk
6 
7 \*******************************************************************/
8 
11 
12 #ifndef CPROVER_ANALYSES_CALL_STACK_HISTORY_H
13 #define CPROVER_ANALYSES_CALL_STACK_HISTORY_H
14 
15 #include "ai_history.h"
16 
21 {
22 protected:
23  class call_stack_entryt;
24  typedef std::shared_ptr<const call_stack_entryt> cse_ptrt;
26  {
27  public:
30 
32  {
33  }
34 
35  bool operator<(const call_stack_entryt &op) const;
36  bool operator==(const call_stack_entryt &op) const;
37  };
38 
40  // DATA_INVARIANT(current_stack != nullptr, "current_stack must exist");
41  // DATA_INVARIANT(current_stack->current.is_dereferenceable(),
42  // "Must not be _::end()")
43 
44  // At what point to merge with a previous call stack when handling recursion
45  // Setting to 0 disables completely
46  unsigned int recursion_limit;
47 
48  bool has_recursion_limit(void) const
49  {
50  return recursion_limit != 0;
51  }
52 
53  call_stack_historyt(cse_ptrt cur_stack, unsigned int rec_lim)
54  : ai_history_baset(cur_stack->current_location),
55  current_stack(cur_stack),
56  recursion_limit(rec_lim)
57  {
59  cur_stack != nullptr); // A little late by now but worth documenting
60  }
61 
62 public:
64  : ai_history_baset(l),
65  current_stack(std::make_shared<call_stack_entryt>(l, nullptr)),
67  {
68  }
69 
70  call_stack_historyt(locationt l, unsigned int rec_lim)
71  : ai_history_baset(l),
72  current_stack(std::make_shared<call_stack_entryt>(l, nullptr)),
73  recursion_limit(rec_lim)
74  {
75  }
76 
78  : ai_history_baset(old),
81  {
82  }
83 
85  locationt to,
86  const trace_sett &others,
87  trace_ptrt caller_hist) const override;
88 
89  bool operator<(const ai_history_baset &op) const override;
90  bool operator==(const ai_history_baset &op) const override;
91 
92  const locationt &current_location(void) const override
93  {
94  return current_stack->current_location;
95  }
96 
97  // Use default widening
98  // Typically this would be used for loops, which are not tracked
99  // it would be possible to use this to improve the handling of recursion
100  bool should_widen(const ai_history_baset &other) const override
101  {
102  return ai_history_baset::should_widen(other);
103  }
104 
105  void output(std::ostream &out) const override;
106 };
107 
108 // Allows passing a recursion limit
110 {
111 protected:
112  unsigned int recursion_limit;
113 
114 public:
115  explicit call_stack_history_factoryt(unsigned int rec_lim)
116  : recursion_limit(rec_lim)
117  {
118  }
119 
121  {
123  std::make_shared<call_stack_historyt>(l, recursion_limit));
124  return p;
125  }
126 
128  {
129  }
130 };
131 
132 #endif // CPROVER_ANALYSES_CALL_STACK_HISTORY_H
Abstract Interpretation history.
A history object is an abstraction / representation of the control-flow part of a set of traces.
Definition: ai_history.h:37
std::shared_ptr< const ai_history_baset > trace_ptrt
History objects are intended to be immutable so they can be shared to reduce memory overhead.
Definition: ai_history.h:43
std::pair< step_statust, trace_ptrt > step_returnt
Definition: ai_history.h:88
virtual bool should_widen(const ai_history_baset &other) const
Domains with a substantial height may need to widen when merging this method allows the history to pr...
Definition: ai_history.h:139
goto_programt::const_targett locationt
Definition: ai_history.h:39
std::set< trace_ptrt, compare_historyt > trace_sett
Definition: ai_history.h:79
As more detailed histories can get complex (for example, nested loops or deep, mutually recursive cal...
Definition: ai_history.h:242
ai_history_baset::trace_ptrt epoch(ai_history_baset::locationt l) override
Creates a new history from the given starting point.
call_stack_history_factoryt(unsigned int rec_lim)
call_stack_entryt(locationt l, cse_ptrt p)
bool operator<(const call_stack_entryt &op) const
bool operator==(const call_stack_entryt &op) const
Records the call stack Care must be taken when using this on recursive code; it will need the domain ...
call_stack_historyt(const call_stack_historyt &old)
bool operator<(const ai_history_baset &op) const override
The order for history_sett.
std::shared_ptr< const call_stack_entryt > cse_ptrt
call_stack_historyt(cse_ptrt cur_stack, unsigned int rec_lim)
const locationt & current_location(void) const override
The current location in the history, used to compute the transformer POSTCONDITION(return value is de...
call_stack_historyt(locationt l)
void output(std::ostream &out) const override
bool has_recursion_limit(void) const
unsigned int recursion_limit
bool should_widen(const ai_history_baset &other) const override
Domains with a substantial height may need to widen when merging this method allows the history to pr...
bool operator==(const ai_history_baset &op) const override
History objects should be comparable.
step_returnt step(locationt to, const trace_sett &others, trace_ptrt caller_hist) const override
Step creates a new history by advancing the current one to location "to" It is given the set of all o...
call_stack_historyt(locationt l, unsigned int rec_lim)
#define PRECONDITION(CONDITION)
Definition: invariant.h:463