CBMC
Loading...
Searching...
No Matches
cfg_info.h
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: CFG-based information for assigns clause checking simplification
4
5Author: Remi Delmas
6
7Date: June 2022
8
9\*******************************************************************/
10
14
15#ifndef CPROVER_GOTO_INSTRUMENT_CONTRACTS_CFG_INFO_H
16#define CPROVER_GOTO_INSTRUMENT_CONTRACTS_CFG_INFO_H
17
19
20#include <util/byte_operators.h>
21#include <util/expr_cast.h>
22#include <util/find_symbols.h>
23#include <util/message.h>
24
26
27#include <analyses/dirty.h>
28#include <analyses/locals.h>
31
32#include <set>
33#include <vector>
34
40{
41public:
43 virtual bool is_local(const irep_idt &ident) const = 0;
44
47 virtual bool is_not_local_or_dirty_local(const irep_idt &ident) const = 0;
48
51 bool is_local_composite_access(const exprt &expr) const
52 {
53 // case-splitting on the lhs structure copied from symex_assignt::assign_rec
54 if(expr.id() == ID_symbol)
55 {
56 return is_local(to_symbol_expr(expr).get_identifier());
57 }
58 else if(expr.id() == ID_index)
59 {
60 return is_local_composite_access(to_index_expr(expr).array());
61 }
62 else if(expr.id() == ID_member)
63 {
64 const typet &type = to_member_expr(expr).struct_op().type();
65 if(
66 type.id() == ID_struct || type.id() == ID_struct_tag ||
67 type.id() == ID_union || type.id() == ID_union_tag)
68 {
69 return is_local_composite_access(to_member_expr(expr).compound());
70 }
71 else
72 {
74 "is_local_composite_access: unexpected assignment to member of '" +
75 type.id_string() + "'");
76 }
77 }
78 else if(expr.id() == ID_if)
79 {
80 return is_local_composite_access(to_if_expr(expr).true_case()) &&
81 is_local_composite_access(to_if_expr(expr).false_case());
82 }
83 else if(expr.id() == ID_typecast)
84 {
86 }
87 else if(
90 {
92 }
93 else if(expr.id() == ID_complex_real)
94 {
96 }
97 else if(expr.id() == ID_complex_imag)
98 {
100 }
101 else
102 {
103 // matches ID_address_of, ID_dereference, etc.
104 return false;
105 }
106 }
107};
108
109// For goto_functions
111{
112public:
115 {
116 parameters.insert(
117 _goto_function.parameter_identifiers.begin(),
118 _goto_function.parameter_identifiers.end());
119 }
120
122 bool is_local(const irep_idt &ident) const override
123 {
124 return locals.is_local(ident) ||
125 (parameters.find(ident) != parameters.end());
126 }
127
130 bool is_not_local_or_dirty_local(const irep_idt &ident) const override
131 {
132 return is_local(ident) ? is_dirty(ident) : true;
133 }
134
135private:
138 std::unordered_set<irep_idt> parameters;
139};
140
141// For a loop in a goto_function
143{
144public:
147 {
148 for(const auto &t : loop)
149 {
150 if(t->is_decl())
151 locals.insert(t->decl_symbol().get_identifier());
152 }
153 }
154
156 bool is_local(const irep_idt &ident) const override
157 {
158 return locals.find(ident) != locals.end();
159 }
160
163 bool is_not_local_or_dirty_local(const irep_idt &ident) const override
164 {
165 if(is_local(ident))
166 return is_dirty(ident);
167 else
168 return true;
169 }
170
171 void erase_locals(std::set<exprt> &exprs)
172 {
173 auto it = exprs.begin();
174 while(it != exprs.end())
175 {
176 const std::unordered_set<irep_idt> symbols = find_symbol_identifiers(*it);
177
178 if(
179 std::find_if(symbols.begin(), symbols.end(), [this](const irep_idt &s) {
180 return is_local(s);
181 }) != symbols.end())
182 {
183 it = exprs.erase(it);
184 }
185 else
186 {
187 it++;
188 }
189 }
190 }
191
192private:
194 std::unordered_set<irep_idt> locals;
195};
196
200{
201public:
202 explicit goto_program_cfg_infot(const goto_programt &goto_program)
203 {
204 // collect symbols declared in the insruction sequence as locals
205 goto_program.get_decl_identifiers(locals);
206
207 // collect dirty locals
208 goto_functiont goto_function;
209 goto_function.body.copy_from(goto_program);
210
211 dirtyt is_dirty(goto_function);
212 const auto &dirty_ids = is_dirty.get_dirty_ids();
213 dirty.insert(dirty_ids.begin(), dirty_ids.end());
214 }
215
217 bool is_local(const irep_idt &ident) const override
218 {
219 return locals.find(ident) != locals.end();
220 }
221
224 bool is_not_local_or_dirty_local(const irep_idt &ident) const override
225 {
226 if(is_local(ident))
227 return dirty.find(ident) != dirty.end();
228 else
229 return true;
230 }
231
232protected:
233 std::set<irep_idt> locals;
234 std::set<irep_idt> dirty;
235};
236
237#endif
Expression classes for byte-level operators.
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Stores information about a goto function computed from its CFG.
Definition cfg_info.h:40
virtual bool is_not_local_or_dirty_local(const irep_idt &ident) const =0
Returns true iff the given ident is either non-locally declared or is locally-declared but dirty.
virtual bool is_local(const irep_idt &ident) const =0
Returns true iff ident is locally declared.
bool is_local_composite_access(const exprt &expr) const
Returns true iff expr is an access to a locally declared symbol and does not contain dereference or a...
Definition cfg_info.h:51
Dirty variables are ones which have their address taken so we can't reliably work out where they may ...
Definition dirty.h:28
const std::unordered_set< irep_idt > & get_dirty_ids() const
Definition dirty.h:78
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
bool is_local(const irep_idt &ident) const override
Returns true iff ident is a local or parameter of the goto_function.
Definition cfg_info.h:122
std::unordered_set< irep_idt > parameters
Definition cfg_info.h:138
const localst locals
Definition cfg_info.h:137
const dirtyt is_dirty
Definition cfg_info.h:136
bool is_not_local_or_dirty_local(const irep_idt &ident) const override
Returns true iff the given ident is either not a goto_function local or is a local that is dirty.
Definition cfg_info.h:130
function_cfg_infot(const goto_functiont &_goto_function)
Definition cfg_info.h:113
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
goto_programt body
For a goto program.
Definition cfg_info.h:200
goto_program_cfg_infot(const goto_programt &goto_program)
Definition cfg_info.h:202
bool is_local(const irep_idt &ident) const override
Returns true iff ident is a loop local.
Definition cfg_info.h:217
std::set< irep_idt > dirty
Definition cfg_info.h:234
bool is_not_local_or_dirty_local(const irep_idt &ident) const override
Returns true iff the given ident is either not a loop local or is a loop local that is dirty.
Definition cfg_info.h:224
std::set< irep_idt > locals
Definition cfg_info.h:233
A generic container class for the GOTO intermediate representation of one function.
void copy_from(const goto_programt &src)
Copy a full goto program, preserving targets.
void get_decl_identifiers(decl_identifierst &decl_identifiers) const
get the variables in decl statements
const std::string & id_string() const
Definition irep.h:391
const irep_idt & id() const
Definition irep.h:388
bool is_not_local_or_dirty_local(const irep_idt &ident) const override
Returns true iff the given ident is either not a loop local or is a loop local that is dirty.
Definition cfg_info.h:163
bool is_local(const irep_idt &ident) const override
Returns true iff ident is a loop local.
Definition cfg_info.h:156
void erase_locals(std::set< exprt > &exprs)
Definition cfg_info.h:171
std::unordered_set< irep_idt > locals
Definition cfg_info.h:194
loop_cfg_infot(goto_functiont &_goto_function, const loopt &loop)
Definition cfg_info.h:145
const dirtyt is_dirty
Definition cfg_info.h:193
The type of an expression, extends irept.
Definition type.h:29
Thrown when we encounter an instruction, parameters to an instruction etc.
static std::unordered_set< irep_idt > find_symbol_identifiers(const goto_programt &src)
Find all identifiers in src.
Variables whose address is taken.
Templated functions to cast to specific exprt-derived classes.
Program Transformation.
Symbol Table + CFG.
Utilities for building havoc code for expressions.
Local variables whose address is taken.
Helper functions for k-induction and loop invariants.
natural_loops_mutablet::natural_loopt loopt
Definition loop_utils.h:20
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition std_expr.h:1538
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition std_expr.h:2107
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition std_expr.h:2577
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition std_expr.h:3063
const complex_imag_exprt & to_complex_imag_expr(const exprt &expr)
Cast an exprt to a complex_imag_exprt.
Definition std_expr.h:2053
const complex_real_exprt & to_complex_real_expr(const exprt &expr)
Cast an exprt to a complex_real_exprt.
Definition std_expr.h:2010
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:272