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/message.h>
23 
25 
26 #include <analyses/dirty.h>
27 #include <analyses/locals.h>
30 
31 #include <set>
32 #include <vector>
33 
38 class cfg_infot
39 {
40 public:
42  virtual bool is_local(const irep_idt &ident) const = 0;
43 
46  virtual bool is_not_local_or_dirty_local(const irep_idt &ident) const = 0;
47 
50  bool is_local_composite_access(const exprt &expr) const
51  {
52  // case-splitting on the lhs structure copied from symex_assignt::assign_rec
53  if(expr.id() == ID_symbol)
54  {
55  return is_local(to_symbol_expr(expr).get_identifier());
56  }
57  else if(expr.id() == ID_index)
58  {
59  return is_local_composite_access(to_index_expr(expr).array());
60  }
61  else if(expr.id() == ID_member)
62  {
63  const typet &type = to_member_expr(expr).struct_op().type();
64  if(
65  type.id() == ID_struct || type.id() == ID_struct_tag ||
66  type.id() == ID_union || type.id() == ID_union_tag)
67  {
68  return is_local_composite_access(to_member_expr(expr).compound());
69  }
70  else
71  {
73  "is_local_composite_access: unexpected assignment to member of '" +
74  type.id_string() + "'");
75  }
76  }
77  else if(expr.id() == ID_if)
78  {
79  return is_local_composite_access(to_if_expr(expr).true_case()) &&
80  is_local_composite_access(to_if_expr(expr).false_case());
81  }
82  else if(expr.id() == ID_typecast)
83  {
85  }
86  else if(
87  expr.id() == ID_byte_extract_little_endian ||
88  expr.id() == ID_byte_extract_big_endian)
89  {
91  }
92  else if(expr.id() == ID_complex_real)
93  {
95  }
96  else if(expr.id() == ID_complex_imag)
97  {
99  }
100  else
101  {
102  // matches ID_address_of, ID_dereference, etc.
103  return false;
104  }
105  }
106 };
107 
108 // For goto_functions
110 {
111 public:
112  explicit function_cfg_infot(const goto_functiont &_goto_function)
113  : is_dirty(_goto_function), locals(_goto_function)
114  {
115  parameters.insert(
116  _goto_function.parameter_identifiers.begin(),
117  _goto_function.parameter_identifiers.end());
118  }
119 
121  bool is_local(const irep_idt &ident) const override
122  {
123  return locals.is_local(ident) ||
124  (parameters.find(ident) != parameters.end());
125  }
126 
129  bool is_not_local_or_dirty_local(const irep_idt &ident) const override
130  {
131  return is_local(ident) ? is_dirty(ident) : true;
132  }
133 
134 private:
137  std::unordered_set<irep_idt> parameters;
138 };
139 
140 // For a loop in a goto_function
141 class loop_cfg_infot : public cfg_infot
142 {
143 public:
144  loop_cfg_infot(goto_functiont &_goto_function, const loopt &loop)
145  : is_dirty(_goto_function)
146  {
147  for(const auto &t : loop)
148  {
149  if(t->is_decl())
150  locals.insert(t->decl_symbol().get_identifier());
151  }
152  }
153 
155  bool is_local(const irep_idt &ident) const override
156  {
157  return locals.find(ident) != locals.end();
158  }
159 
162  bool is_not_local_or_dirty_local(const irep_idt &ident) const override
163  {
164  if(is_local(ident))
165  return is_dirty(ident);
166  else
167  return true;
168  }
169 
170  void erase_locals(std::set<exprt> &exprs)
171  {
172  auto it = exprs.begin();
173  while(it != exprs.end())
174  {
175  if(
176  it->id() == ID_symbol && is_local(to_symbol_expr(*it).get_identifier()))
177  {
178  it = exprs.erase(it);
179  }
180  else
181  {
182  it++;
183  }
184  }
185  }
186 
187 private:
189  std::unordered_set<irep_idt> locals;
190 };
191 #endif
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
localst
Definition: locals.h:24
dirty.h
function_cfg_infot
Definition: cfg_info.h:109
cfg_infot
Stores information about a goto function computed from its CFG.
Definition: cfg_info.h:38
dirtyt
Dirty variables are ones which have their address taken so we can't reliably work out where they may ...
Definition: dirty.h:27
loop_cfg_infot::is_local
bool is_local(const irep_idt &ident) const override
Returns true iff ident is a loop local.
Definition: cfg_info.h:155
typet
The type of an expression, extends irept.
Definition: type.h:28
to_byte_extract_expr
const byte_extract_exprt & to_byte_extract_expr(const exprt &expr)
Definition: byte_operators.h:57
to_index_expr
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition: std_expr.h:1478
to_if_expr
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition: std_expr.h:2403
function_cfg_infot::is_not_local_or_dirty_local
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:129
unsupported_operation_exceptiont
Thrown when we encounter an instruction, parameters to an instruction etc.
Definition: exception_utils.h:144
goto_convert_class.h
goto_model.h
exprt
Base class for all expressions.
Definition: expr.h:55
havoc_utils.h
function_cfg_infot::is_dirty
const dirtyt is_dirty
Definition: cfg_info.h:135
to_complex_real_expr
const complex_real_exprt & to_complex_real_expr(const exprt &expr)
Cast an exprt to a complex_real_exprt.
Definition: std_expr.h:1952
function_cfg_infot::function_cfg_infot
function_cfg_infot(const goto_functiont &_goto_function)
Definition: cfg_info.h:112
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
byte_operators.h
Expression classes for byte-level operators.
get_identifier
static optionalt< smt_termt > get_identifier(const exprt &expr, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_handle_identifiers, const std::unordered_map< exprt, smt_identifier_termt, irep_hash > &expression_identifiers)
Definition: smt2_incremental_decision_procedure.cpp:328
member_exprt::struct_op
const exprt & struct_op() const
Definition: std_expr.h:2832
locals.h
symbol_exprt::get_identifier
const irep_idt & get_identifier() const
Definition: std_expr.h:142
irept::id_string
const std::string & id_string() const
Definition: irep.h:399
loop_templatet
A loop, specified as a set of instructions.
Definition: loop_analysis.h:23
cfg_infot::is_local_composite_access
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:50
localst::is_local
bool is_local(const irep_idt &identifier) const
Definition: locals.h:37
to_symbol_expr
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition: std_expr.h:222
irept::id
const irep_idt & id() const
Definition: irep.h:396
goto_functiont
A goto function, consisting of function body (see body) and parameter identifiers (see parameter_iden...
Definition: goto_function.h:23
loop_cfg_infot
Definition: cfg_info.h:141
to_complex_imag_expr
const complex_imag_exprt & to_complex_imag_expr(const exprt &expr)
Cast an exprt to a complex_imag_exprt.
Definition: std_expr.h:1997
function_cfg_infot::locals
const localst locals
Definition: cfg_info.h:136
loop_cfg_infot::loop_cfg_infot
loop_cfg_infot(goto_functiont &_goto_function, const loopt &loop)
Definition: cfg_info.h:144
loop_utils.h
function_cfg_infot::is_local
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:121
cfg_infot::is_not_local_or_dirty_local
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.
loop_cfg_infot::is_not_local_or_dirty_local
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:162
to_typecast_expr
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition: std_expr.h:2051
expr_cast.h
Templated functions to cast to specific exprt-derived classes.
goto_functiont::parameter_identifiers
parameter_identifierst parameter_identifiers
The identifiers of the parameters of this function.
Definition: goto_function.h:33
to_member_expr
const member_exprt & to_member_expr(const exprt &expr)
Cast an exprt to a member_exprt.
Definition: std_expr.h:2886
loop_cfg_infot::erase_locals
void erase_locals(std::set< exprt > &exprs)
Definition: cfg_info.h:170
function_cfg_infot::parameters
std::unordered_set< irep_idt > parameters
Definition: cfg_info.h:137
message.h
loop_cfg_infot::locals
std::unordered_set< irep_idt > locals
Definition: cfg_info.h:189
cfg_infot::is_local
virtual bool is_local(const irep_idt &ident) const =0
Returns true iff ident is locally declared.
loop_cfg_infot::is_dirty
const dirtyt is_dirty
Definition: cfg_info.h:188