CBMC
abstract_object.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3  Module: analyses variable-sensitivity
4 
5  Author: Thomas Kiley, thomas.kiley@diffblue.com
6 
7 \*******************************************************************/
8 
25 
26 #ifndef CPROVER_ANALYSES_VARIABLE_SENSITIVITY_ABSTRACT_OBJECT_H
27 #define CPROVER_ANALYSES_VARIABLE_SENSITIVITY_ABSTRACT_OBJECT_H
28 
29 #include <memory>
30 #include <set>
31 #include <stack>
32 
34 #include <util/sharing_map.h>
35 
37 class namespacet;
39 enum class widen_modet;
40 
41 #define CLONE \
42  internal_abstract_object_pointert mutable_clone() const override \
43  { \
44  typedef std::remove_const< \
45  std::remove_reference<decltype(*this)>::type>::type current_typet; \
46  return internal_abstract_object_pointert(new current_typet(*this)); \
47  }
48 
65 
66 template <class T>
67 using sharing_ptrt = std::shared_ptr<const T>; // NOLINT(*)
68 
70 using abstract_object_visitedt = std::set<abstract_object_pointert>;
71 
72 class abstract_objectt : public std::enable_shared_from_this<abstract_objectt>
73 {
74 public:
76  explicit abstract_objectt(const typet &type);
77 
84  abstract_objectt(const typet &type, bool top, bool bottom);
85 
94  const exprt &expr,
95  const abstract_environmentt &environment,
96  const namespacet &ns);
97 
106  const typet &type,
107  const exprt &expr,
108  const abstract_environmentt &environment,
109  const namespacet &ns);
110 
112  {
113  }
114 
118  virtual const typet &type() const;
119 
124  virtual bool is_top() const;
125 
129  virtual bool is_bottom() const;
130 
134  virtual bool verify() const;
135 
136  virtual void get_statistics(
137  abstract_object_statisticst &statistics,
138  abstract_object_visitedt &visited,
139  const abstract_environmentt &env,
140  const namespacet &ns) const;
141 
158  const exprt &expr,
159  const std::vector<abstract_object_pointert> &operands,
160  const abstract_environmentt &environment,
161  const namespacet &ns) const;
162 
172  virtual exprt to_constant() const;
173 
183  exprt to_predicate(const exprt &name) const;
184 
202  abstract_environmentt &environment,
203  const namespacet &ns,
204  const std::stack<exprt> &stack,
205  const exprt &specifier,
206  const abstract_object_pointert &value,
207  bool merging_write) const;
208 
215  virtual void output(
216  std::ostream &out,
217  const class ai_baset &ai,
218  const namespacet &ns) const;
219 
223 
224  static void dump_map(std::ostream out, const shared_mapt &m);
232  static void
233  dump_map_diff(std::ostream out, const shared_mapt &m1, const shared_mapt &m2);
234 
243  virtual bool has_been_modified(const abstract_object_pointert &before) const
244  {
248  return this != before.get();
249  };
250 
263  {
265  bool modified;
266  };
267  static combine_result merge(
268  const abstract_object_pointert &op1,
269  const abstract_object_pointert &op2,
270  const locationt &merge_location,
271  const widen_modet &widen_mode);
272  static combine_result merge(
273  const abstract_object_pointert &op1,
274  const abstract_object_pointert &op2,
275  const widen_modet &widen_mode);
276 
284  static combine_result meet(
285  const abstract_object_pointert &op1,
286  const abstract_object_pointert &op2);
287 
294  meet(const abstract_object_pointert &other) const;
295 
305  write_location_context(const locationt &location) const;
306 
316  merge_location_context(const locationt &location) const;
317 
318  // Const versions must perform copy-on-write
320  {
321  if(is_top())
322  return shared_from_this();
323 
325  clone->set_top();
326  return clone;
327  }
328 
330  {
331  if(!is_top())
332  return shared_from_this();
333 
335  clone->set_not_top();
336  return clone;
337  }
338 
340 
346  {
348  visit(const abstract_object_pointert &element) const = 0;
349  };
350 
364  {
365  return shared_from_this();
366  }
367 
368  virtual size_t internal_hash() const
369  {
370  return std::hash<abstract_object_pointert>{}(shared_from_this());
371  }
372 
373  virtual bool internal_equality(const abstract_object_pointert &other) const
374  {
375  return shared_from_this() == other;
376  }
377 
381  virtual exprt to_predicate_internal(const exprt &name) const;
382 
383 private:
386  bool bottom;
387  bool top;
388 
389  // Hooks to allow a sub-class to perform its own operations on
390  // setting/clearing top
391  virtual void set_top_internal()
392  {
393  }
394  virtual void set_not_top_internal()
395  {
396  }
397 
412 
419 
420 protected:
421  template <class T>
422  using internal_sharing_ptrt = std::shared_ptr<T>;
423 
426 
427  // Macro is not used as this does not override
429  {
431  }
432 
441 
449  bool should_use_base_merge(const abstract_object_pointert &other) const;
450 
459  const abstract_object_pointert &other,
460  const widen_modet &widen_mode) const;
461 
468 
473  bool should_use_base_meet(const abstract_object_pointert &other) const;
474 
475  // The one exception is merge in descendant classes, which needs this
476  void set_top()
477  {
478  top = true;
479  this->set_top_internal();
480  }
481  void set_not_top()
482  {
483  top = false;
484  this->set_not_top_internal();
485  }
487  {
488  bottom = false;
489  }
490 };
491 
493 {
495  typedef std::size_t result_typet;
496  result_typet operator()(argument_typet const &s) const noexcept
497  {
498  return s->internal_hash();
499  }
500 };
501 
503 {
505  typedef std::size_t result_typet;
506  bool operator()(argument_typet const &left, argument_typet const &right) const
507  noexcept
508  {
509  return left->internal_equality(right);
510  }
511 };
512 
513 #endif // CPROVER_ANALYSES_VARIABLE_SENSITIVITY_ABSTRACT_OBJECT_H
abstract_objectt::internal_equality
virtual bool internal_equality(const abstract_object_pointert &other) const
Definition: abstract_object.h:373
abstract_hashert::operator()
result_typet operator()(argument_typet const &s) const noexcept
Definition: abstract_object.h:496
abstract_objectt::dump_map
static void dump_map(std::ostream out, const shared_mapt &m)
Definition: abstract_object.cpp:270
widen_modet
widen_modet
Definition: abstract_environment.h:32
abstract_objectt::abstract_object_meet_internal
virtual abstract_object_pointert abstract_object_meet_internal(const abstract_object_pointert &other) const
Helper function for base meet, in case additional work was needed.
Definition: abstract_object.cpp:99
abstract_object_pointert
sharing_ptrt< class abstract_objectt > abstract_object_pointert
Definition: abstract_object.h:69
abstract_objectt::abstract_object_merge
abstract_object_pointert abstract_object_merge(const abstract_object_pointert &other) const
Create a new abstract object that is the result of the merge, unless the object would be unchanged,...
Definition: abstract_object.cpp:59
abstract_objectt::is_top
virtual bool is_top() const
Find out if the abstract object is top.
Definition: abstract_object.cpp:155
abstract_objectt::output
virtual void output(std::ostream &out, const class ai_baset &ai, const namespacet &ns) const
Print the value of the abstract object.
Definition: abstract_object.cpp:190
abstract_objectt::locationt
goto_programt::const_targett locationt
Definition: abstract_object.h:220
sharing_mapt< irep_idt, abstract_object_pointert, false, irep_id_hash >
typet
The type of an expression, extends irept.
Definition: type.h:28
abstract_objectt::type
virtual const typet & type() const
Get the real type of the variable this abstract object is representing.
Definition: abstract_object.cpp:47
abstract_objectt::internal_hash
virtual size_t internal_hash() const
Definition: abstract_object.h:368
abstract_objectt::should_use_base_meet
bool should_use_base_meet(const abstract_object_pointert &other) const
Helper function to decide if base meet implementation should be used.
Definition: abstract_object.cpp:252
abstract_objectt::set_top
void set_top()
Definition: abstract_object.h:476
abstract_environmentt
Definition: abstract_environment.h:40
exprt
Base class for all expressions.
Definition: expr.h:55
sharing_ptrt
std::shared_ptr< const T > sharing_ptrt
Merge is designed to allow different abstractions to be merged gracefully.
Definition: abstract_object.h:67
abstract_objectt::clear_top
abstract_object_pointert clear_top() const
Definition: abstract_object.h:329
abstract_hashert::result_typet
std::size_t result_typet
Definition: abstract_object.h:495
abstract_objectt::get_statistics
virtual void get_statistics(abstract_object_statisticst &statistics, abstract_object_visitedt &visited, const abstract_environmentt &env, const namespacet &ns) const
Definition: abstract_object.cpp:310
abstract_objectt::internal_abstract_object_pointert
internal_sharing_ptrt< class abstract_objectt > internal_abstract_object_pointert
Definition: abstract_object.h:425
abstract_hashert::argument_typet
abstract_object_pointert argument_typet
Definition: abstract_object.h:494
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
abstract_objectt::combine_result::modified
bool modified
Definition: abstract_object.h:265
abstract_objectt::merge
static combine_result merge(const abstract_object_pointert &op1, const abstract_object_pointert &op2, const locationt &merge_location, const widen_modet &widen_mode)
Definition: abstract_object.cpp:209
abstract_equalert::operator()
bool operator()(argument_typet const &left, argument_typet const &right) const noexcept
Definition: abstract_object.h:506
abstract_object_statisticst
Definition: abstract_object_statistics.h:18
abstract_objectt::~abstract_objectt
virtual ~abstract_objectt()
Definition: abstract_object.h:111
abstract_objectt::shared_mapt
sharing_mapt< irep_idt, abstract_object_pointert, false, irep_id_hash > shared_mapt
Definition: abstract_object.h:222
abstract_objectt::to_constant
virtual exprt to_constant() const
Converts to a constant expression if possible.
Definition: abstract_object.cpp:170
abstract_objectt::make_top
abstract_object_pointert make_top() const
Definition: abstract_object.h:319
abstract_objectt::dump_map_diff
static void dump_map_diff(std::ostream out, const shared_mapt &m1, const shared_mapt &m2)
Dump all elements in m1 that are different or missing in m2.
Definition: abstract_object.cpp:287
abstract_objectt::set_not_top_internal
virtual void set_not_top_internal()
Definition: abstract_object.h:394
abstract_equalert::result_typet
std::size_t result_typet
Definition: abstract_object.h:505
abstract_object_visitedt
std::set< abstract_object_pointert > abstract_object_visitedt
Definition: abstract_object.h:70
abstract_objectt::bottom
bool bottom
Definition: abstract_object.h:386
abstract_objectt::abstract_object_visitort
Pure virtual interface required of a client that can apply a copy-on-write operation to a given abstr...
Definition: abstract_object.h:345
goto_program.h
abstract_equalert::argument_typet
abstract_object_pointert argument_typet
Definition: abstract_object.h:504
abstract_objectt::meet
static combine_result meet(const abstract_object_pointert &op1, const abstract_object_pointert &op2)
Interface method for the meet operation.
Definition: abstract_object.cpp:241
abstract_equalert
Definition: abstract_object.h:502
abstract_objectt::abstract_object_meet
abstract_object_pointert abstract_object_meet(const abstract_object_pointert &other) const
Helper function for base meet.
Definition: abstract_object.cpp:84
abstract_objectt::unwrap_context
virtual abstract_object_pointert unwrap_context() const
Definition: abstract_object.cpp:305
abstract_objectt::has_been_modified
virtual bool has_been_modified(const abstract_object_pointert &before) const
Determine whether 'this' abstract_object has been modified in comparison to a previous 'before' state...
Definition: abstract_object.h:243
abstract_hashert
Definition: abstract_object.h:492
abstract_objectt::set_not_bottom
void set_not_bottom()
Definition: abstract_object.h:486
ai_baset
This is the basic interface of the abstract interpreter with default implementations of the core func...
Definition: ai.h:118
abstract_objectt::verify
virtual bool verify() const
Verify the internal structure of an abstract_object is correct.
Definition: abstract_object.cpp:165
abstract_objectt::internal_sharing_ptrt
std::shared_ptr< T > internal_sharing_ptrt
Definition: abstract_object.h:422
abstract_objectt::set_not_top
void set_not_top()
Definition: abstract_object.h:481
abstract_objectt::write
virtual abstract_object_pointert write(abstract_environmentt &environment, const namespacet &ns, const std::stack< exprt > &stack, const exprt &specifier, const abstract_object_pointert &value, bool merging_write) const
A helper function to evaluate writing to a component of an abstract object.
Definition: abstract_object.cpp:144
abstract_objectt::set_top_internal
virtual void set_top_internal()
Definition: abstract_object.h:391
goto_programt::const_targett
instructionst::const_iterator const_targett
Definition: goto_program.h:587
abstract_objectt::to_predicate
exprt to_predicate(const exprt &name) const
Converts to an invariant expression.
Definition: abstract_object.cpp:175
abstract_objectt::top
bool top
Definition: abstract_object.h:387
abstract_objectt::write_location_context
virtual abstract_object_pointert write_location_context(const locationt &location) const
Update the write location context for an abstract object.
Definition: abstract_object.cpp:259
abstract_objectt
Definition: abstract_object.h:72
abstract_objectt::abstract_object_visitort::visit
virtual abstract_object_pointert visit(const abstract_object_pointert &element) const =0
abstract_objectt::is_bottom
virtual bool is_bottom() const
Find out if the abstract object is bottom.
Definition: abstract_object.cpp:160
abstract_objectt::combine_result::object
abstract_object_pointert object
Definition: abstract_object.h:264
sharing_map.h
abstract_objectt::should_use_base_merge
bool should_use_base_merge(const abstract_object_pointert &other) const
To detect the cases where the base merge is sufficient to do a merge We can't do if this->is_bottom()...
Definition: abstract_object.cpp:235
abstract_objectt::visit_sub_elements
virtual abstract_object_pointert visit_sub_elements(const abstract_object_visitort &visitor) const
Apply a visitor operation to all sub elements of this abstract_object.
Definition: abstract_object.h:363
abstract_objectt::to_predicate_internal
virtual exprt to_predicate_internal(const exprt &name) const
to_predicate implementation - derived classes will override
Definition: abstract_object.cpp:184
abstract_objectt::combine_result
Clones the first parameter and merges it with the second.
Definition: abstract_object.h:262
abstract_objectt::mutable_clone
virtual internal_abstract_object_pointert mutable_clone() const
Definition: abstract_object.h:428
abstract_objectt::abstract_object_merge_internal
virtual abstract_object_pointert abstract_object_merge_internal(const abstract_object_pointert &other) const
Helper function for abstract_objectt::abstract_object_merge to perform any additional actions after t...
Definition: abstract_object.cpp:71
abstract_objectt::t
typet t
To enforce copy-on-write these are private and have read-only accessors.
Definition: abstract_object.h:385
abstract_objectt::expression_transform
virtual abstract_object_pointert expression_transform(const exprt &expr, const std::vector< abstract_object_pointert > &operands, const abstract_environmentt &environment, const namespacet &ns) const
Interface for transforms.
Definition: abstract_object.cpp:112
abstract_objectt::abstract_objectt
abstract_objectt(const typet &type)
Definition: abstract_object.cpp:19
abstract_objectt::merge_location_context
virtual abstract_object_pointert merge_location_context(const locationt &location) const
Update the merge location context for an abstract object.
Definition: abstract_object.cpp:265