CBMC
cfg_info.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: CFG-based information for assigns clause checking simplification
4 
5 Author: Remi Delmas
6 
7 Date: 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 
39 class cfg_infot
40 {
41 public:
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(
88  expr.id() == ID_byte_extract_little_endian ||
89  expr.id() == ID_byte_extract_big_endian)
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 {
112 public:
113  explicit function_cfg_infot(const goto_functiont &_goto_function)
114  : is_dirty(_goto_function), locals(_goto_function)
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 
135 private:
138  std::unordered_set<irep_idt> parameters;
139 };
140 
141 // For a loop in a goto_function
142 class loop_cfg_infot : public cfg_infot
143 {
144 public:
145  loop_cfg_infot(goto_functiont &_goto_function, const loopt &loop)
146  : is_dirty(_goto_function)
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 
192 private:
194  std::unordered_set<irep_idt> locals;
195 };
196 
200 {
201 public:
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 
232 protected:
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)
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
typet & type()
Return the type of the expression.
Definition: expr.h:84
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...
Definition: goto_function.h:24
goto_programt body
Definition: goto_function.h:26
parameter_identifierst parameter_identifiers
The identifiers of the parameters of this function.
Definition: goto_function.h:33
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.
Definition: goto_program.h:73
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:387
const irep_idt & id() const
Definition: irep.h:384
Definition: locals.h:25
bool is_local(const irep_idt &identifier) const
Definition: locals.h:37
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
const exprt & struct_op() const
Definition: std_expr.h:2879
The type of an expression, extends irept.
Definition: type.h:29
Thrown when we encounter an instruction, parameters to an instruction etc.
Variables whose address is taken.
Templated functions to cast to specific exprt-derived classes.
find_symbols_sett find_symbol_identifiers(const exprt &src)
Find identifiers of the sub expressions with id ID_symbol, considering both free and bound variables.
Definition: find_symbols.h:53
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 if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition: std_expr.h:2450
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:272
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2102
const complex_real_exprt & to_complex_real_expr(const exprt &expr)
Cast an exprt to a complex_real_exprt.
Definition: std_expr.h:2005
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2933
const complex_imag_exprt & to_complex_imag_expr(const exprt &expr)
Cast an exprt to a complex_imag_exprt.
Definition: std_expr.h:2048
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1533