CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
local_control_flow_history.h
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Abstract Interpretation
4
5Author: Martin Brain, martin.brain@cs.ox.ac.uk
6
7\*******************************************************************/
8
11
12#ifndef CPROVER_ANALYSES_LOCAL_CONTROL_FLOW_HISTORY_H
13#define CPROVER_ANALYSES_LOCAL_CONTROL_FLOW_HISTORY_H
14
15#include "ai_history.h"
16
21
24{
25public:
29 typedef std::shared_ptr<const local_control_flow_decisiont> lcfd_ptrt;
30 lcfd_ptrt previous; // null at the start of the function
31
36
37 bool operator<(const local_control_flow_decisiont &op) const;
38 bool operator==(const local_control_flow_decisiont &op) const;
39};
40
44template <bool track_forward_jumps, bool track_backward_jumps>
46{
47protected:
49
53
54 // A repeating idiom -- can cast from interface type to this type
55 // caller's responsibility to ensure correct types
56 std::shared_ptr<const local_control_flow_historyt<
57 track_forward_jumps,
58 track_backward_jumps>>
60 {
61 PRECONDITION(in != nullptr);
62 auto tmp = std::dynamic_pointer_cast<const local_control_flow_historyt<
63 track_forward_jumps,
64 track_backward_jumps>>(in);
65 PRECONDITION(tmp != nullptr);
66 return tmp;
67 }
68
69public:
70 // nullptr denotes this is the "merge all other CFG paths" node
71 bool is_path_merge_history(void) const
72 {
73 return control_flow_decision_history == nullptr;
74 }
75
76 // Set to 0 to disable but be aware that this may well diverge
77 // and not terminate
79 {
81 }
82
91
99
108
118
121 const trace_sett &others,
122 trace_ptrt caller_hist) const override;
123
124 bool operator<(const ai_history_baset &op) const override;
125 bool operator==(const ai_history_baset &op) const override;
126
127 const locationt &current_location(void) const override
128 {
129 return current_loc;
130 }
131
132 // If there is no history, then it is because we have merged
133 // If we are merging control flow histories then we should probably
134 // also widen on domain merge so that analysis converges faster.
135 bool should_widen(const ai_history_baset &other) const override
136 {
137 return is_path_merge_history();
138 }
139
140 void output(std::ostream &out) const override;
141};
142
143// Sets the kind of jumps to track and the max number of histories per location
145{
146protected:
150
151public:
161
163 {
165 {
167 {
168 // All local control flow branches
169 return std::make_shared<local_control_flow_historyt<true, true>>(
171 }
172 else
173 {
174 // "Path sensitive" but merge loops eagerly
175 return std::make_shared<local_control_flow_historyt<true, false>>(
177 }
178 }
179 else
180 {
182 {
183 // Loop unwinding but merge branches eagerly
184 return std::make_shared<local_control_flow_historyt<false, true>>(
186 }
187 else
188 {
189 // Ignore all branches. Same effect as ahistorical but at more cost???
190 return std::make_shared<local_control_flow_historyt<false, false>>(
192 }
193 }
195 }
196
198 {
199 // Pointer is reference counted.
200 }
201};
202
203#endif // CPROVER_ANALYSES_LOCAL_CONTROL_FLOW_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
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
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Records all local control-flow decisions up to a limit of number of histories per location.
local_control_flow_decisiont(locationt loc, bool taken, lcfd_ptrt ptr)
std::shared_ptr< const local_control_flow_decisiont > lcfd_ptrt
bool operator<(const local_control_flow_decisiont &op) const
bool operator==(const local_control_flow_decisiont &op) const
ai_history_baset::locationt locationt
ai_history_baset::trace_ptrt epoch(ai_history_baset::locationt l) override
Creates a new history from the given starting point.
local_control_flow_history_factoryt(bool track_f, bool track_b, size_t max_hist)
Whether we track forwards and / or backwards jumps is compile-time fixed as it does not need to be va...
bool operator<(const ai_history_baset &op) const override
The order for history_sett.
const locationt & current_location(void) const override
The current location in the history, used to compute the transformer POSTCONDITION(return value is de...
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...
void output(std::ostream &out) const override
bool operator==(const ai_history_baset &op) const override
History objects should be comparable.
local_control_flow_decisiont::lcfd_ptrt lcfd_ptrt
local_control_flow_historyt(locationt loc, size_t max_hist)
std::shared_ptr< const local_control_flow_historyt< track_forward_jumps, track_backward_jumps > > to_local_control_flow_history(trace_ptrt in) const
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...
local_control_flow_historyt(locationt loc, lcfd_ptrt hist, size_t max_hist)
local_control_flow_historyt(const local_control_flow_historyt< track_forward_jumps, track_backward_jumps > &old)
STL namespace.
#define UNREACHABLE
This should be used to mark dead code.
Definition invariant.h:525
#define PRECONDITION(CONDITION)
Definition invariant.h:463