CBMC
abstract_value_object.h
Go to the documentation of this file.
1 /*******************************************************************\
2 
3  Module: analyses variable-sensitivity
4 
5  Author: Jez Higgins, jez@jezuk.co.uk
6 
7 \*******************************************************************/
8 
12 #ifndef CPROVER_ANALYSES_VARIABLE_SENSITIVITY_ABSTRACT_VALUE_OBJECT_H
13 #define CPROVER_ANALYSES_VARIABLE_SENSITIVITY_ABSTRACT_VALUE_OBJECT_H
14 
16 
18 
20 {
21 };
22 
24 
26  std::unique_ptr<index_range_implementationt>;
27 
29 {
30 public:
31  virtual ~index_range_implementationt() = default;
32 
34 
35  virtual const exprt &current() const = 0;
36  virtual bool advance_to_next() = 0;
37 };
38 
40 {
41 public:
42  const exprt &operator*() const
43  {
44  return range->current();
45  }
46  void operator++()
47  {
48  active = range->advance_to_next();
49  }
50  bool operator==(const index_range_iteratort &other) const
51  {
52  if(!active && !other.active)
53  return true;
54  return false;
55  }
56  bool operator!=(const index_range_iteratort &other) const
57  {
58  return !operator==(other);
59  }
60 
62  : range(std::move(rhs.range)), active(rhs.active)
63  {
64  }
67 
68 private:
69  index_range_iteratort() : range(nullptr), active(false)
70  {
71  }
73  : range(std::move(r)), active(true)
74  {
75  active = range->advance_to_next();
76  }
77 
79  bool active;
80 
81  friend class index_ranget;
82 };
83 
85 {
86 public:
88  {
89  }
90  index_ranget(index_ranget &&rhs) : range(rhs.range.release())
91  {
92  }
93  index_ranget(const index_ranget &) = delete;
94  ~index_ranget() = default;
95 
97  {
98  return index_range_iteratort{range->reset()};
99  }
101  {
102  return {};
103  }
104 
105 private:
107 };
108 
110 {
111 protected:
112  explicit single_value_index_ranget(const exprt &val);
113 
114 public:
115  const exprt &current() const override;
116  bool advance_to_next() override;
117 
118 protected:
119  const exprt value;
120 
121 private:
122  bool available;
123 };
124 
127 
129 
131  std::unique_ptr<value_range_implementationt>;
132 
134 {
135 public:
136  virtual ~value_range_implementationt() = default;
137 
139 
140  virtual const abstract_object_pointert &current() const = 0;
141  virtual bool advance_to_next() = 0;
142 };
143 
145 {
146 public:
148  {
149  return range->current();
150  }
151  void operator++()
152  {
153  active = range->advance_to_next();
154  }
155  bool operator==(const value_range_iteratort &other) const
156  {
157  if(!active && !other.active)
158  return true;
159  return false;
160  }
161  bool operator!=(const value_range_iteratort &other) const
162  {
163  return !operator==(other);
164  }
165 
167  : range(std::move(rhs.range)), active(rhs.active)
168  {
169  }
172 
173 private:
174  value_range_iteratort() : range(nullptr), active(false)
175  {
176  }
178  : range(std::move(r)), active(true)
179  {
180  active = range->advance_to_next();
181  }
182 
184  bool active;
185 
186  friend class value_ranget;
187 };
188 
190 {
191 public:
193 
195  {
196  }
197  value_ranget(value_ranget &&rhs) : range(rhs.range.release())
198  {
199  }
200  value_ranget(const value_ranget &) = delete;
201  ~value_ranget() = default;
202 
204  {
205  return value_range_iteratort{range->reset()};
206  }
208  {
209  return {};
210  }
211 
212 private:
214 };
215 
218 
220 {
221 public:
222  const abstract_object_pointert &current() const override
223  {
224  return nothing;
225  }
226  bool advance_to_next() override
227  {
228  return false;
229  }
231  {
232  return std::make_unique<empty_value_ranget>();
233  }
234 
235 private:
237 };
238 
240  public abstract_value_tag
241 {
242 public:
243  abstract_value_objectt(const typet &type, bool tp, bool bttm)
244  : abstract_objectt(type, tp, bttm)
245  {
246  }
247 
249  const exprt &expr,
250  const abstract_environmentt &environment,
251  const namespacet &ns)
252  : abstract_objectt(expr, environment, ns)
253  {
254  }
255 
257  {
259  }
260 
262  {
264  }
265 
267 
281  const exprt &expr,
282  const std::vector<abstract_object_pointert> &operands,
283  const abstract_environmentt &environment,
284  const namespacet &ns) const final;
285 
287  constrain(const exprt &lower, const exprt &upper) const = 0;
288 
290  abstract_environmentt &environment,
291  const namespacet &ns,
292  const std::stack<exprt> &stack,
293  const exprt &specifier,
294  const abstract_object_pointert &value,
295  bool merging_write) const final;
296 
297 protected:
299 
308  const abstract_object_pointert &other,
309  const widen_modet &widen_mode) const final;
310 
312  meet(const abstract_object_pointert &other) const final;
313 
315  const abstract_value_pointert &other,
316  const widen_modet &widen_mode) const = 0;
317 
319  meet_with_value(const abstract_value_pointert &other) const = 0;
320 
323 
326 
328  as_value(const abstract_object_pointert &obj) const;
329 };
330 
332 
333 #endif
abstract_objectt is the top of the inheritance heirarchy of objects used to represent individual vari...
std::shared_ptr< const T > sharing_ptrt
Merge is designed to allow different abstractions to be merged gracefully.
sharing_ptrt< class abstract_objectt > abstract_object_pointert
std::unique_ptr< index_range_implementationt > index_range_implementation_ptrt
sharing_ptrt< const abstract_value_objectt > abstract_value_pointert
index_range_implementation_ptrt make_indeterminate_index_range()
index_range_implementation_ptrt make_empty_index_range()
std::unique_ptr< value_range_implementationt > value_range_implementation_ptrt
value_range_implementation_ptrt make_single_value_range(const abstract_object_pointert &value)
virtual const typet & type() const
Get the real type of the variable this abstract object is representing.
virtual index_range_implementation_ptrt index_range_implementation(const namespacet &ns) const =0
abstract_value_objectt(const typet &type, bool tp, bool bttm)
virtual constant_interval_exprt to_interval() const =0
sharing_ptrt< const abstract_value_objectt > as_value(const abstract_object_pointert &obj) const
abstract_object_pointert merge(const abstract_object_pointert &other, const widen_modet &widen_mode) const final
Attempts to do a value/value merge if both are constants, otherwise falls back to the parent merge.
virtual abstract_object_pointert meet_with_value(const abstract_value_pointert &other) const =0
abstract_value_objectt(const exprt &expr, const abstract_environmentt &environment, const namespacet &ns)
virtual sharing_ptrt< const abstract_value_objectt > constrain(const exprt &lower, const exprt &upper) const =0
value_ranget value_range() const
abstract_object_pointert expression_transform(const exprt &expr, const std::vector< abstract_object_pointert > &operands, const abstract_environmentt &environment, const namespacet &ns) const final
Interface for transforms.
abstract_object_pointert meet(const abstract_object_pointert &other) const final
Base implementation of the meet operation: only used if no more precise abstraction can be used,...
virtual value_range_implementation_ptrt value_range_implementation() const =0
sharing_ptrt< const abstract_value_objectt > abstract_value_pointert
index_ranget index_range(const namespacet &ns) const
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 final
A helper function to evaluate writing to a component of an abstract object.
virtual abstract_object_pointert merge_with_value(const abstract_value_pointert &other, const widen_modet &widen_mode) const =0
Represents an interval of values.
Definition: interval.h:52
const abstract_object_pointert & current() const override
bool advance_to_next() override
abstract_object_pointert nothing
value_range_implementation_ptrt reset() const override
Base class for all expressions.
Definition: expr.h:56
virtual bool advance_to_next()=0
virtual ~index_range_implementationt()=default
virtual const exprt & current() const =0
virtual index_range_implementation_ptrt reset() const =0
bool operator==(const index_range_iteratort &other) const
index_range_implementation_ptrt range
~index_range_iteratort()=default
index_range_iteratort(index_range_iteratort &&rhs)
bool operator!=(const index_range_iteratort &other) const
index_range_iteratort(index_range_implementation_ptrt &&r)
const exprt & operator*() const
index_range_iteratort(const index_range_iteratort &)=delete
index_range_implementation_ptrt range
index_ranget(const index_ranget &)=delete
~index_ranget()=default
index_range_iteratort begin() const
index_ranget(index_ranget &&rhs)
index_ranget(index_range_implementation_ptrt r)
index_range_iteratort end() const
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
single_value_index_ranget(const exprt &val)
const exprt & current() const override
The type of an expression, extends irept.
Definition: type.h:29
virtual ~value_range_implementationt()=default
virtual value_range_implementation_ptrt reset() const =0
virtual bool advance_to_next()=0
virtual const abstract_object_pointert & current() const =0
value_range_implementation_ptrt range
const abstract_object_pointert & operator*() const
value_range_iteratort(const value_range_iteratort &)=delete
value_range_iteratort(value_range_iteratort &&rhs)
value_range_iteratort(value_range_implementation_ptrt &&r)
bool operator==(const value_range_iteratort &other) const
bool operator!=(const value_range_iteratort &other) const
~value_range_iteratort()=default
value_range_implementation_ptrt range
value_ranget(const value_ranget &)=delete
~value_ranget()=default
value_ranget(value_ranget &&rhs)
value_range_iteratort begin() const
value_ranget(value_range_implementation_ptrt r)
abstract_object_pointert value_type
value_range_iteratort end() const
static int8_t r
Definition: irep_hash.h:60