CBMC
variable_sensitivity_object_factory.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3  Module: analyses variable-sensitivity
4 
5  Author: Owen Jones, owen.jones@diffblue.com
6 
7 \*******************************************************************/
8 
10 
17 #include "liveness_context.h"
24 
25 template <class context_classt>
28 {
30  new context_classt{abstract_object, abstract_object->type(), true, false});
31 }
32 
33 template <class abstract_object_classt>
35  const typet type,
36  bool top,
37  bool bottom,
38  const exprt &e,
39  const abstract_environmentt &environment,
40  const namespacet &ns)
41 {
42  if(top || bottom)
43  return std::make_shared<abstract_object_classt>(type, top, bottom);
44 
45  PRECONDITION(type == e.type());
46  return std::make_shared<abstract_object_classt>(e, environment, ns);
47 }
48 
50  const abstract_object_pointert &abstract_object,
51  const vsd_configt &configuration)
52 {
53  if(configuration.context_tracking.liveness)
54  return create_context_abstract_object<liveness_contextt>(abstract_object);
55 
57  return create_context_abstract_object<data_dependency_contextt>(
58  abstract_object);
59 
60  if(configuration.context_tracking.last_write_context)
61  return create_context_abstract_object<write_location_contextt>(
62  abstract_object);
63 
64  return abstract_object;
65 }
66 
83 template <class abstract_object_classt>
85  const typet type,
86  bool top,
87  bool bottom,
88  const exprt &e,
89  const abstract_environmentt &environment,
90  const namespacet &ns,
91  const vsd_configt &configuration)
92 {
93  auto abstract_object = create_abstract_object<abstract_object_classt>(
94  type, top, bottom, e, environment, ns);
95 
96  return wrap_with_context_object(abstract_object, configuration);
97 }
98 
101  const typet &type) const
102 {
103  ABSTRACT_OBJECT_TYPET abstract_object_type = TWO_VALUE;
104 
105  if(
106  type.id() == ID_signedbv || type.id() == ID_unsignedbv ||
107  type.id() == ID_fixedbv || type.id() == ID_c_bool || type.id() == ID_bool ||
108  type.id() == ID_integer || type.id() == ID_c_bit_field)
109  {
111  }
112  else if(type.id() == ID_floatbv)
113  {
115  return (float_type == INTERVAL) ? CONSTANT : float_type;
116  }
117  else if(type.id() == ID_array)
118  {
120  }
121  else if(type.id() == ID_pointer)
122  {
124  }
125  else if(type.id() == ID_struct || type.id() == ID_struct_tag)
126  {
128  }
129  else if(type.id() == ID_union || type.id() == ID_union_tag)
130  {
132  }
133  else if(type.id() == ID_dynamic_object)
134  {
135  return HEAP_ALLOCATION;
136  }
137 
138  return abstract_object_type;
139 }
140 
143  const typet &type,
144  bool top,
145  bool bottom,
146  const exprt &e,
147  const abstract_environmentt &environment,
148  const namespacet &ns) const
149 {
150  ABSTRACT_OBJECT_TYPET abstract_object_type = get_abstract_object_type(type);
151 
152  switch(abstract_object_type)
153  {
154  case TWO_VALUE:
155  return initialize_abstract_object<abstract_objectt>(
156  type, top, bottom, e, environment, ns, configuration);
157  case CONSTANT:
158  return initialize_abstract_object<constant_abstract_valuet>(
159  type, top, bottom, e, environment, ns, configuration);
160  case INTERVAL:
161  return initialize_abstract_object<interval_abstract_valuet>(
162  type, top, bottom, e, environment, ns, configuration);
163  case VALUE_SET:
164  return initialize_abstract_object<value_set_abstract_objectt>(
165  type, top, bottom, e, environment, ns, configuration);
166 
167  case ARRAY_INSENSITIVE:
168  return initialize_abstract_object<two_value_array_abstract_objectt>(
169  type, top, bottom, e, environment, ns, configuration);
170  case ARRAY_SENSITIVE:
171  return initialize_abstract_object<full_array_abstract_objectt>(
172  type, top, bottom, e, environment, ns, configuration);
173 
174  case POINTER_INSENSITIVE:
175  return initialize_abstract_object<two_value_pointer_abstract_objectt>(
176  type, top, bottom, e, environment, ns, configuration);
177  case POINTER_SENSITIVE:
178  return initialize_abstract_object<constant_pointer_abstract_objectt>(
179  type, top, bottom, e, environment, ns, configuration);
181  return initialize_abstract_object<value_set_pointer_abstract_objectt>(
182  type, top, bottom, e, environment, ns, configuration);
183 
184  case STRUCT_INSENSITIVE:
185  return initialize_abstract_object<two_value_struct_abstract_objectt>(
186  type, top, bottom, e, environment, ns, configuration);
187  case STRUCT_SENSITIVE:
188  return initialize_abstract_object<full_struct_abstract_objectt>(
189  type, top, bottom, e, environment, ns, configuration);
190 
191  case UNION_INSENSITIVE:
192  return initialize_abstract_object<two_value_union_abstract_objectt>(
193  type, top, bottom, e, environment, ns, configuration);
194 
195  case HEAP_ALLOCATION:
196  {
197  auto dynamic_object = exprt(ID_dynamic_object);
198  dynamic_object.set(
199  ID_identifier, "heap-allocation-" + std::to_string(heap_allocations++));
200  auto heap_symbol = unary_exprt(ID_address_of, dynamic_object, e.type());
201  auto heap_pointer =
202  get_abstract_object(e.type(), false, false, heap_symbol, environment, ns);
203  return heap_pointer;
204  }
205 
206  default:
207  UNREACHABLE;
208  return initialize_abstract_object<abstract_objectt>(
209  type, top, bottom, e, environment, ns, configuration);
210  }
211 }
212 
215  const abstract_object_pointert &abstract_object) const
216 {
217  return wrap_with_context_object(abstract_object, configuration);
218 }
sharing_ptrt< class abstract_objectt > abstract_object_pointert
floatbv_typet float_type()
Definition: c_types.cpp:177
Base class for all expressions.
Definition: expr.h:56
typet & type()
Return the type of the expression.
Definition: expr.h:84
const irep_idt & id() const
Definition: irep.h:384
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
The type of an expression, extends irept.
Definition: type.h:29
Generic base class for unary expressions.
Definition: std_expr.h:361
abstract_object_pointert get_abstract_object(const typet &type, bool top, bool bottom, const exprt &e, const abstract_environmentt &environment, const namespacet &ns) const
Get the appropriate abstract object for the variable under consideration.
abstract_object_pointert wrap_with_context(const abstract_object_pointert &abstract_object) const
ABSTRACT_OBJECT_TYPET get_abstract_object_type(const typet &type) const
Decide which abstract object type to use for the variable in question.
An abstraction of a single value that just stores a constant.
An abstraction of a pointer that tracks a single pointer.
Maintain data dependencies as a context in the variable sensitivity domain.
An abstraction of an array value.
An abstraction of a structure that stores one abstract object per field.
An interval to represent a set of possible values.
Maintain a context in the variable sensitvity domain that records the liveness region for a given abs...
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:525
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
ABSTRACT_OBJECT_TYPET union_abstract_type
struct vsd_configt::@0 context_tracking
ABSTRACT_OBJECT_TYPET pointer_abstract_type
ABSTRACT_OBJECT_TYPET struct_abstract_type
ABSTRACT_OBJECT_TYPET array_abstract_type
ABSTRACT_OBJECT_TYPET value_abstract_type
The base type of all abstract array representations.
The base of all structure abstractions.
The base of all union abstractions.
Value Set Abstract Object.
Value Set of Pointer Abstract Object.
abstract_object_pointert create_context_abstract_object(const abstract_object_pointert &abstract_object)
abstract_object_pointert initialize_abstract_object(const typet type, bool top, bool bottom, const exprt &e, const abstract_environmentt &environment, const namespacet &ns, const vsd_configt &configuration)
Function: variable_sensitivity_object_factoryt::initialize_abstract_object Initialize the abstract ob...
abstract_object_pointert create_abstract_object(const typet type, bool top, bool bottom, const exprt &e, const abstract_environmentt &environment, const namespacet &ns)
abstract_object_pointert wrap_with_context_object(const abstract_object_pointert &abstract_object, const vsd_configt &configuration)
Tracks the user-supplied configuration for VSD and build the correct type of abstract object when nee...