CBMC
value_set_fi.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Value Set (Flow Insensitive, Sharing)
4 
5 Author: Daniel Kroening, kroening@kroening.com
6  CM Wintersteiger
7 
8 \*******************************************************************/
9 
12 
13 #ifndef CPROVER_POINTER_ANALYSIS_VALUE_SET_FI_H
14 #define CPROVER_POINTER_ANALYSIS_VALUE_SET_FI_H
15 
16 #include <list>
17 #include <map>
18 #include <set>
19 #include <unordered_set>
20 
21 #include <util/mp_arith.h>
23 
24 #include "object_numbering.h"
25 
26 class codet;
27 class namespacet;
28 
30 {
31 public:
33  changed(false)
34  // to_function, to_target_index are set by set_to()
35  // from_function, from_target_index are set by set_from()
36  {
37  }
38 
43 
44  void set_from(const irep_idt &function, unsigned inx)
45  {
47  from_target_index = inx;
48  }
49 
50  void set_to(const irep_idt &function, unsigned inx)
51  {
53  to_target_index = inx;
54  }
55 
56  typedef irep_idt idt;
57 
61  bool offset_is_zero(const offsett &offset) const
62  {
63  return offset && offset->is_zero();
64  }
65 
67  {
68  typedef std::map<object_numberingt::number_type, offsett> data_typet;
70 
71  public:
72  // NOLINTNEXTLINE(readability/identifiers)
73  typedef data_typet::iterator iterator;
74  // NOLINTNEXTLINE(readability/identifiers)
75  typedef data_typet::const_iterator const_iterator;
76  // NOLINTNEXTLINE(readability/identifiers)
77  typedef data_typet::value_type value_type;
78 
79  iterator begin() { return data.begin(); }
80  const_iterator begin() const { return data.begin(); }
81  const_iterator cbegin() const { return data.cbegin(); }
82 
83  iterator end() { return data.end(); }
84  const_iterator end() const { return data.end(); }
85  const_iterator cend() const { return data.cend(); }
86 
87  size_t size() const { return data.size(); }
88 
90  {
91  return data[i];
92  }
93 
94  template <typename It>
95  void insert(It b, It e) { data.insert(b, e); }
96 
97  template <typename T>
98  const_iterator find(T &&t) const { return data.find(std::forward<T>(t)); }
99 
100  static const object_map_dt blank;
101 
102  protected:
103  ~object_map_dt()=default;
104  };
105 
106  exprt to_expr(const object_map_dt::value_type &it) const;
107 
109 
110  void set(object_mapt &dest, const object_map_dt::value_type &it) const
111  {
112  dest.write()[it.first]=it.second;
113  }
114 
115  bool insert(object_mapt &dest, const object_map_dt::value_type &it) const
116  {
117  return insert(dest, it.first, it.second);
118  }
119 
120  bool insert(object_mapt &dest, const exprt &src) const
121  {
122  return insert(dest, object_numbering.number(src), offsett());
123  }
124 
125  bool insert(
126  object_mapt &dest,
127  const exprt &src,
128  const mp_integer &offset_value) const
129  {
130  return insert(dest, object_numbering.number(src), offsett(offset_value));
131  }
132 
133  bool insert(
134  object_mapt &dest,
136  const offsett &offset) const
137  {
138  if(dest.read().find(n)==dest.read().end())
139  {
140  // new
141  dest.write()[n] = offset;
142  return true;
143  }
144  else
145  {
146  offsett &old_offset = dest.write()[n];
147 
148  if(old_offset && offset)
149  {
150  if(*old_offset == *offset)
151  return false;
152  else
153  {
154  old_offset.reset();
155  return true;
156  }
157  }
158  else if(!old_offset)
159  return false;
160  else
161  {
162  old_offset.reset();
163  return true;
164  }
165  }
166  }
167 
168  bool insert(object_mapt &dest, const exprt &expr, const offsett &offset) const
169  {
170  return insert(dest, object_numbering.number(expr), offset);
171  }
172 
173  struct entryt
174  {
177  std::string suffix;
178 
180  {
181  }
182 
183  entryt(const idt &_identifier, const std::string _suffix):
184  identifier(_identifier),
185  suffix(_suffix)
186  {
187  }
188  };
189 
190  typedef std::unordered_set<exprt, irep_hash> expr_sett;
191 
192  typedef std::unordered_set<unsigned int> dynamic_object_id_sett;
193 
194  #ifdef USE_DSTRING
195  typedef std::map<idt, entryt> valuest;
196  typedef std::set<idt> flatten_seent;
197  typedef std::unordered_set<idt> gvs_recursion_sett;
198  typedef std::unordered_set<idt> recfind_recursion_sett;
199  typedef std::unordered_set<idt> assign_recursion_sett;
200  #else
201  typedef std::unordered_map<idt, entryt, string_hash> valuest;
202  typedef std::unordered_set<idt, string_hash> flatten_seent;
203  typedef std::unordered_set<idt, string_hash> gvs_recursion_sett;
204  typedef std::unordered_set<idt, string_hash> recfind_recursion_sett;
205  typedef std::unordered_set<idt, string_hash> assign_recursion_sett;
206  #endif
207 
208  std::vector<exprt>
209  get_value_set(const exprt &expr, const namespacet &ns) const;
210 
211  expr_sett &get(
212  const idt &identifier,
213  const std::string &suffix);
214 
215  void clear()
216  {
217  values.clear();
218  }
219 
220  void add_var(const idt &id)
221  {
222  get_entry(id, "");
223  }
224 
225  void add_var(const entryt &e)
226  {
228  }
229 
230  entryt &get_entry(const idt &id, const std::string &suffix)
231  {
232  return get_entry(entryt(id, suffix));
233  }
234 
236  {
237  std::string index=id2string(e.identifier)+e.suffix;
238 
239  std::pair<valuest::iterator, bool> r=
240  values.insert(std::pair<idt, entryt>(index, e));
241 
242  return r.first->second;
243  }
244 
245  void add_vars(const std::list<entryt> &vars)
246  {
247  for(std::list<entryt>::const_iterator
248  it=vars.begin();
249  it!=vars.end();
250  it++)
251  add_var(*it);
252  }
253 
254  void output(
255  const namespacet &ns,
256  std::ostream &out) const;
257 
259 
260  bool changed;
261 
262  // true = added something new
263  bool make_union(object_mapt &dest, const object_mapt &src) const;
264 
265  // true = added something new
266  bool make_union(const valuest &new_values);
267 
268  // true = added something new
269  bool make_union(const value_set_fit &new_values)
270  {
271  return make_union(new_values.values);
272  }
273 
274  void apply_code(const codet &code, const namespacet &ns);
275 
276  void assign(
277  const exprt &lhs,
278  const exprt &rhs,
279  const namespacet &ns);
280 
281  void do_function_call(
282  const irep_idt &function,
283  const exprt::operandst &arguments,
284  const namespacet &ns);
285 
286  // edge back to call site
287  void do_end_function(
288  const exprt &lhs,
289  const namespacet &ns);
290 
291  void get_reference_set(
292  const exprt &expr,
293  expr_sett &expr_set,
294  const namespacet &ns) const;
295 
296 protected:
298  const exprt &expr,
299  expr_sett &expr_set,
300  const namespacet &ns) const;
301 
302  void get_value_set_rec(
303  const exprt &expr,
304  object_mapt &dest,
305  const std::string &suffix,
306  const typet &original_type,
307  const namespacet &ns,
308  gvs_recursion_sett &recursion_set) const;
309 
310 
311  void get_value_set(
312  const exprt &expr,
313  object_mapt &dest,
314  const namespacet &ns) const;
315 
317  const exprt &expr,
318  object_mapt &dest,
319  const namespacet &ns) const
320  {
321  get_reference_set_sharing_rec(expr, dest, ns);
322  }
323 
325  const exprt &expr,
326  object_mapt &dest,
327  const namespacet &ns) const;
328 
329  void dereference_rec(
330  const exprt &src,
331  exprt &dest) const;
332 
333  void assign_rec(
334  const exprt &lhs,
335  const object_mapt &values_rhs,
336  const std::string &suffix,
337  const namespacet &ns,
338  assign_recursion_sett &recursion_set);
339 
340  void flatten(const entryt &e, object_mapt &dest) const;
341 
342  void flatten_rec(
343  const entryt&,
344  object_mapt&,
345  flatten_seent&) const;
346 };
347 
348 #endif // CPROVER_POINTER_ANALYSIS_VALUE_SET_FI_H
value_set_fit::get_reference_set_sharing
void get_reference_set_sharing(const exprt &expr, object_mapt &dest, const namespacet &ns) const
Definition: value_set_fi.h:316
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
value_set_fit::get_entry
entryt & get_entry(const idt &id, const std::string &suffix)
Definition: value_set_fi.h:230
value_set_fit::insert
bool insert(object_mapt &dest, const exprt &src) const
Definition: value_set_fi.h:120
value_set_fit::object_map_dt::cbegin
const_iterator cbegin() const
Definition: value_set_fi.h:81
mp_integer
BigInt mp_integer
Definition: smt_terms.h:17
value_set_fit::object_map_dt::begin
const_iterator begin() const
Definition: value_set_fi.h:80
value_set_fit::object_map_dt::begin
iterator begin()
Definition: value_set_fi.h:79
mp_arith.h
value_set_fit::idt
irep_idt idt
Definition: value_set_fi.h:56
value_set_fit::flatten_seent
std::set< idt > flatten_seent
Definition: value_set_fi.h:196
value_set_fit::offset_is_zero
bool offset_is_zero(const offsett &offset) const
Definition: value_set_fi.h:61
value_set_fit::dynamic_object_id_sett
std::unordered_set< unsigned int > dynamic_object_id_sett
Definition: value_set_fi.h:192
value_set_fit::object_map_dt::iterator
data_typet::iterator iterator
Definition: value_set_fi.h:73
value_set_fit::values
valuest values
Definition: value_set_fi.h:258
typet
The type of an expression, extends irept.
Definition: type.h:28
value_set_fit::value_set_fit
value_set_fit()
Definition: value_set_fi.h:32
value_set_fit::assign
void assign(const exprt &lhs, const exprt &rhs, const namespacet &ns)
Definition: value_set_fi.cpp:961
value_set_fit::get_reference_set_sharing_rec
void get_reference_set_sharing_rec(const exprt &expr, object_mapt &dest, const namespacet &ns) const
Definition: value_set_fi.cpp:761
value_set_fit::entryt::entryt
entryt(const idt &_identifier, const std::string _suffix)
Definition: value_set_fi.h:183
numberingt
Definition: numbering.h:21
value_set_fit::expr_sett
std::unordered_set< exprt, irep_hash > expr_sett
Definition: value_set_fi.h:190
value_set_fit::do_function_call
void do_function_call(const irep_idt &function, const exprt::operandst &arguments, const namespacet &ns)
Definition: value_set_fi.cpp:1276
value_set_fit::entryt
Definition: value_set_fi.h:173
value_set_fit::from_function
unsigned from_function
Definition: value_set_fi.h:39
value_set_fit::entryt::entryt
entryt()
Definition: value_set_fi.h:179
exprt
Base class for all expressions.
Definition: expr.h:55
object_numbering.h
value_set_fit::object_map_dt::data_typet
std::map< object_numberingt::number_type, offsett > data_typet
Definition: value_set_fi.h:68
value_set_fit::dereference_rec
void dereference_rec(const exprt &src, exprt &dest) const
Definition: value_set_fi.cpp:686
value_set_fit::from_target_index
unsigned from_target_index
Definition: value_set_fi.h:40
value_set_fit::object_map_dt::data
data_typet data
Definition: value_set_fi.h:69
value_set_fit::flatten
void flatten(const entryt &e, object_mapt &dest) const
Definition: value_set_fi.cpp:135
value_set_fit::flatten_rec
void flatten_rec(const entryt &, object_mapt &, flatten_seent &) const
Definition: value_set_fi.cpp:151
value_set_fit
Definition: value_set_fi.h:29
value_set_fit::to_target_index
unsigned to_target_index
Definition: value_set_fi.h:40
value_set_fit::object_mapt
reference_counting< object_map_dt > object_mapt
Definition: value_set_fi.h:108
value_set_fit::get
expr_sett & get(const idt &identifier, const std::string &suffix)
value_set_fit::recfind_recursion_sett
std::unordered_set< idt > recfind_recursion_sett
Definition: value_set_fi.h:198
value_set_fit::entryt::suffix
std::string suffix
Definition: value_set_fi.h:177
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
value_set_fit::entryt::identifier
idt identifier
Definition: value_set_fi.h:176
value_set_fit::apply_code
void apply_code(const codet &code, const namespacet &ns)
Definition: value_set_fi.cpp:1338
value_set_fit::changed
bool changed
Definition: value_set_fi.h:260
value_set_fit::insert
bool insert(object_mapt &dest, const exprt &src, const mp_integer &offset_value) const
Definition: value_set_fi.h:125
value_set_fit::object_map_dt::operator[]
offsett & operator[](object_numberingt::number_type i)
Definition: value_set_fi.h:89
value_set_fit::object_map_dt::end
iterator end()
Definition: value_set_fi.h:83
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
value_set_fit::object_map_dt::insert
void insert(It b, It e)
Definition: value_set_fi.h:95
value_set_fit::object_map_dt::const_iterator
data_typet::const_iterator const_iterator
Definition: value_set_fi.h:75
value_set_fit::insert
bool insert(object_mapt &dest, const exprt &expr, const offsett &offset) const
Definition: value_set_fi.h:168
value_set_fit::get_value_set
std::vector< exprt > get_value_set(const exprt &expr, const namespacet &ns) const
Definition: value_set_fi.cpp:294
value_set_fit::set_from
void set_from(const irep_idt &function, unsigned inx)
Definition: value_set_fi.h:44
expr_sett
std::unordered_set< exprt, irep_hash > expr_sett
Definition: cone_of_influence.h:21
value_set_fit::assign_rec
void assign_rec(const exprt &lhs, const object_mapt &values_rhs, const std::string &suffix, const namespacet &ns, assign_recursion_sett &recursion_set)
Definition: value_set_fi.cpp:1122
value_set_fit::valuest
std::map< idt, entryt > valuest
Definition: value_set_fi.h:195
value_set_fit::entryt::object_map
object_mapt object_map
Definition: value_set_fi.h:175
exprt::operandst
std::vector< exprt > operandst
Definition: expr.h:58
reference_counting< object_map_dt >
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
value_set_fit::object_map_dt::blank
static const object_map_dt blank
Definition: value_set_fi.h:100
value_set_fit::make_union
bool make_union(const value_set_fit &new_values)
Definition: value_set_fi.h:269
value_set_fit::make_union
bool make_union(object_mapt &dest, const object_mapt &src) const
Definition: value_set_fi.cpp:280
value_set_fit::object_map_dt::end
const_iterator end() const
Definition: value_set_fi.h:84
value_set_fit::assign_recursion_sett
std::unordered_set< idt > assign_recursion_sett
Definition: value_set_fi.h:199
value_set_fit::clear
void clear()
Definition: value_set_fi.h:215
value_set_fit::output
void output(const namespacet &ns, std::ostream &out) const
Definition: value_set_fi.cpp:38
value_set_fit::gvs_recursion_sett
std::unordered_set< idt > gvs_recursion_sett
Definition: value_set_fi.h:197
value_set_fit::add_var
void add_var(const entryt &e)
Definition: value_set_fi.h:225
value_set_fit::to_expr
exprt to_expr(const object_map_dt::value_type &it) const
Definition: value_set_fi.cpp:221
value_set_fit::do_end_function
void do_end_function(const exprt &lhs, const namespacet &ns)
Definition: value_set_fi.cpp:1325
numberingt::number
number_type number(const key_type &a)
Definition: numbering.h:37
reference_counting.h
value_set_fit::set
void set(object_mapt &dest, const object_map_dt::value_type &it) const
Definition: value_set_fi.h:110
value_set_fit::object_numbering
static object_numberingt object_numbering
Definition: value_set_fi.h:41
value_set_fit::object_map_dt::~object_map_dt
~object_map_dt()=default
reference_counting::read
const T & read() const
Definition: reference_counting.h:69
value_set_fit::insert
bool insert(object_mapt &dest, object_numberingt::number_type n, const offsett &offset) const
Definition: value_set_fi.h:133
reference_counting::write
T & write()
Definition: reference_counting.h:76
value_set_fit::function_numbering
static numberingt< irep_idt > function_numbering
Definition: value_set_fi.h:42
value_set_fit::to_function
unsigned to_function
Definition: value_set_fi.h:39
value_set_fit::get_reference_set_sharing
void get_reference_set_sharing(const exprt &expr, expr_sett &expr_set, const namespacet &ns) const
Definition: value_set_fi.cpp:749
value_set_fit::offsett
optionalt< mp_integer > offsett
Represents the offset into an object: either a unique integer offset, or an unknown value,...
Definition: value_set_fi.h:60
r
static int8_t r
Definition: irep_hash.h:60
value_set_fit::set_to
void set_to(const irep_idt &function, unsigned inx)
Definition: value_set_fi.h:50
value_set_fit::object_map_dt::size
size_t size() const
Definition: value_set_fi.h:87
value_set_fit::add_vars
void add_vars(const std::list< entryt > &vars)
Definition: value_set_fi.h:245
value_set_fit::object_map_dt::value_type
data_typet::value_type value_type
Definition: value_set_fi.h:77
value_set_fit::get_reference_set
void get_reference_set(const exprt &expr, expr_sett &expr_set, const namespacet &ns) const
Definition: value_set_fi.cpp:701
value_set_fit::object_map_dt::find
const_iterator find(T &&t) const
Definition: value_set_fi.h:98
value_set_fit::object_map_dt
Definition: value_set_fi.h:66
value_set_fit::add_var
void add_var(const idt &id)
Definition: value_set_fi.h:220
numberingt< exprt, irep_hash >::number_type
std::size_t number_type
Definition: numbering.h:24
value_set_fit::get_entry
entryt & get_entry(const entryt &e)
Definition: value_set_fi.h:235
value_set_fit::insert
bool insert(object_mapt &dest, const object_map_dt::value_type &it) const
Definition: value_set_fi.h:115
value_set_fit::get_value_set_rec
void get_value_set_rec(const exprt &expr, object_mapt &dest, const std::string &suffix, const typet &original_type, const namespacet &ns, gvs_recursion_sett &recursion_set) const
Definition: value_set_fi.cpp:367
value_set_fit::object_map_dt::cend
const_iterator cend() const
Definition: value_set_fi.h:85
codet
Data structure for representing an arbitrary statement in a program.
Definition: std_code_base.h:28