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 \*******************************************************************/
10 #include "liveness_context.h"
12 
13 template <class context_classt>
16 {
18  new context_classt{abstract_object, abstract_object->type()});
19 }
20 
21 template <class abstract_object_classt>
23  const typet type,
24  bool top,
25  bool bottom,
26  const exprt &e,
27  const abstract_environmentt &environment,
28  const namespacet &ns)
29 {
30  if(top || bottom)
31  return std::make_shared<abstract_object_classt>(type, top, bottom);
32 
33  PRECONDITION(type == ns.follow(e.type()));
34  return std::make_shared<abstract_object_classt>(e, environment, ns);
35 }
36 
38  const abstract_object_pointert &abstract_object,
39  const vsd_configt &configuration)
40 {
41  if(configuration.context_tracking.liveness)
42  return create_context_abstract_object<liveness_contextt>(abstract_object);
43 
45  return create_context_abstract_object<data_dependency_contextt>(
46  abstract_object);
47 
48  if(configuration.context_tracking.last_write_context)
49  return create_context_abstract_object<write_location_contextt>(
50  abstract_object);
51 
52  return abstract_object;
53 }
54 
71 template <class abstract_object_classt>
73  const typet type,
74  bool top,
75  bool bottom,
76  const exprt &e,
77  const abstract_environmentt &environment,
78  const namespacet &ns,
79  const vsd_configt &configuration)
80 {
81  auto abstract_object = create_abstract_object<abstract_object_classt>(
82  type, top, bottom, e, environment, ns);
83 
84  return wrap_with_context_object(abstract_object, configuration);
85 }
86 
89  const typet &type) const
90 {
91  ABSTRACT_OBJECT_TYPET abstract_object_type = TWO_VALUE;
92 
93  if(
94  type.id() == ID_signedbv || type.id() == ID_unsignedbv ||
95  type.id() == ID_fixedbv || type.id() == ID_c_bool || type.id() == ID_bool ||
96  type.id() == ID_integer || type.id() == ID_c_bit_field)
97  {
99  }
100  else if(type.id() == ID_floatbv)
101  {
103  return (float_type == INTERVAL) ? CONSTANT : float_type;
104  }
105  else if(type.id() == ID_array)
106  {
108  }
109  else if(type.id() == ID_pointer)
110  {
112  }
113  else if(type.id() == ID_struct)
114  {
116  }
117  else if(type.id() == ID_union)
118  {
120  }
121  else if(type.id() == ID_dynamic_object)
122  {
123  return HEAP_ALLOCATION;
124  }
125 
126  return abstract_object_type;
127 }
128 
131  const typet &type,
132  bool top,
133  bool bottom,
134  const exprt &e,
135  const abstract_environmentt &environment,
136  const namespacet &ns) const
137 {
138  const typet &followed_type = ns.follow(type);
139  ABSTRACT_OBJECT_TYPET abstract_object_type =
140  get_abstract_object_type(followed_type);
141 
142  switch(abstract_object_type)
143  {
144  case TWO_VALUE:
145  return initialize_abstract_object<abstract_objectt>(
146  followed_type, top, bottom, e, environment, ns, configuration);
147  case CONSTANT:
148  return initialize_abstract_object<constant_abstract_valuet>(
149  followed_type, top, bottom, e, environment, ns, configuration);
150  case INTERVAL:
151  return initialize_abstract_object<interval_abstract_valuet>(
152  followed_type, top, bottom, e, environment, ns, configuration);
153  case VALUE_SET:
154  return initialize_abstract_object<value_set_abstract_objectt>(
155  followed_type, top, bottom, e, environment, ns, configuration);
156 
157  case ARRAY_INSENSITIVE:
158  return initialize_abstract_object<two_value_array_abstract_objectt>(
159  followed_type, top, bottom, e, environment, ns, configuration);
160  case ARRAY_SENSITIVE:
161  return initialize_abstract_object<full_array_abstract_objectt>(
162  followed_type, top, bottom, e, environment, ns, configuration);
163 
164  case POINTER_INSENSITIVE:
165  return initialize_abstract_object<two_value_pointer_abstract_objectt>(
166  followed_type, top, bottom, e, environment, ns, configuration);
167  case POINTER_SENSITIVE:
168  return initialize_abstract_object<constant_pointer_abstract_objectt>(
169  followed_type, top, bottom, e, environment, ns, configuration);
171  return initialize_abstract_object<value_set_pointer_abstract_objectt>(
172  followed_type, top, bottom, e, environment, ns, configuration);
173 
174  case STRUCT_INSENSITIVE:
175  return initialize_abstract_object<two_value_struct_abstract_objectt>(
176  followed_type, top, bottom, e, environment, ns, configuration);
177  case STRUCT_SENSITIVE:
178  return initialize_abstract_object<full_struct_abstract_objectt>(
179  followed_type, top, bottom, e, environment, ns, configuration);
180 
181  case UNION_INSENSITIVE:
182  return initialize_abstract_object<two_value_union_abstract_objectt>(
183  followed_type, top, bottom, e, environment, ns, configuration);
184 
185  case HEAP_ALLOCATION:
186  {
187  auto dynamic_object = exprt(ID_dynamic_object);
188  dynamic_object.set(
189  ID_identifier, "heap-allocation-" + std::to_string(heap_allocations++));
190  auto heap_symbol = unary_exprt(ID_address_of, dynamic_object, e.type());
191  auto heap_pointer =
192  get_abstract_object(e.type(), false, false, heap_symbol, environment, ns);
193  return heap_pointer;
194  }
195 
196  default:
197  UNREACHABLE;
198  return initialize_abstract_object<abstract_objectt>(
199  followed_type, top, bottom, e, environment, ns, configuration);
200  }
201 }
202 
205  const abstract_object_pointert &abstract_object) const
206 {
207  return wrap_with_context_object(abstract_object, configuration);
208 }
variable_sensitivity_object_factoryt::heap_allocations
size_t heap_allocations
Definition: variable_sensitivity_object_factory.h:95
UNREACHABLE
#define UNREACHABLE
This should be used to mark dead code.
Definition: invariant.h:503
VALUE_SET_OF_POINTERS
@ VALUE_SET_OF_POINTERS
Definition: variable_sensitivity_configuration.h:27
abstract_object_pointert
sharing_ptrt< class abstract_objectt > abstract_object_pointert
Definition: abstract_object.h:69
variable_sensitivity_object_factory.h
vsd_configt::data_dependency_context
bool data_dependency_context
Definition: variable_sensitivity_configuration.h:59
wrap_with_context_object
abstract_object_pointert wrap_with_context_object(const abstract_object_pointert &abstract_object, const vsd_configt &configuration)
Definition: variable_sensitivity_object_factory.cpp:37
typet
The type of an expression, extends irept.
Definition: type.h:28
vsd_configt::pointer_abstract_type
ABSTRACT_OBJECT_TYPET pointer_abstract_type
Definition: variable_sensitivity_configuration.h:47
HEAP_ALLOCATION
@ HEAP_ALLOCATION
Definition: variable_sensitivity_configuration.h:35
CONSTANT
@ CONSTANT
Definition: variable_sensitivity_configuration.h:23
vsd_configt::last_write_context
bool last_write_context
Definition: variable_sensitivity_configuration.h:60
variable_sensitivity_object_factoryt::wrap_with_context
abstract_object_pointert wrap_with_context(const abstract_object_pointert &abstract_object) const
Definition: variable_sensitivity_object_factory.cpp:204
abstract_environmentt
Definition: abstract_environment.h:40
ARRAY_INSENSITIVE
@ ARRAY_INSENSITIVE
Definition: variable_sensitivity_configuration.h:26
exprt
Base class for all expressions.
Definition: expr.h:55
unary_exprt
Generic base class for unary expressions.
Definition: std_expr.h:313
vsd_configt::liveness
bool liveness
Definition: variable_sensitivity_configuration.h:58
vsd_configt::context_tracking
struct vsd_configt::@0 context_tracking
variable_sensitivity_object_factoryt::get_abstract_object_type
ABSTRACT_OBJECT_TYPET get_abstract_object_type(const typet &type) const
Decide which abstract object type to use for the variable in question.
Definition: variable_sensitivity_object_factory.cpp:88
to_string
std::string to_string(const string_not_contains_constraintt &expr)
Used for debug printing.
Definition: string_constraint.cpp:58
vsd_configt
Definition: variable_sensitivity_configuration.h:44
vsd_configt::struct_abstract_type
ABSTRACT_OBJECT_TYPET struct_abstract_type
Definition: variable_sensitivity_configuration.h:48
UNION_INSENSITIVE
@ UNION_INSENSITIVE
Definition: variable_sensitivity_configuration.h:33
VALUE_SET
@ VALUE_SET
Definition: variable_sensitivity_configuration.h:34
INTERVAL
@ INTERVAL
Definition: variable_sensitivity_configuration.h:24
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
ARRAY_SENSITIVE
@ ARRAY_SENSITIVE
Definition: variable_sensitivity_configuration.h:25
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
vsd_configt::array_abstract_type
ABSTRACT_OBJECT_TYPET array_abstract_type
Definition: variable_sensitivity_configuration.h:49
TWO_VALUE
@ TWO_VALUE
Definition: variable_sensitivity_configuration.h:22
create_context_abstract_object
abstract_object_pointert create_context_abstract_object(const abstract_object_pointert &abstract_object)
Definition: variable_sensitivity_object_factory.cpp:15
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
vsd_configt::value_abstract_type
ABSTRACT_OBJECT_TYPET value_abstract_type
Definition: variable_sensitivity_configuration.h:46
float_type
floatbv_typet float_type()
Definition: c_types.cpp:195
vsd_configt::union_abstract_type
ABSTRACT_OBJECT_TYPET union_abstract_type
Definition: variable_sensitivity_configuration.h:50
irept::id
const irep_idt & id() const
Definition: irep.h:396
full_array_abstract_object.h
POINTER_SENSITIVE
@ POINTER_SENSITIVE
Definition: variable_sensitivity_configuration.h:28
namespace_baset::follow
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:49
variable_sensitivity_object_factoryt::configuration
vsd_configt configuration
Definition: variable_sensitivity_object_factory.h:94
variable_sensitivity_object_factoryt::get_abstract_object
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.
Definition: variable_sensitivity_object_factory.cpp:130
POINTER_INSENSITIVE
@ POINTER_INSENSITIVE
Definition: variable_sensitivity_configuration.h:29
ABSTRACT_OBJECT_TYPET
ABSTRACT_OBJECT_TYPET
Definition: variable_sensitivity_configuration.h:20
STRUCT_SENSITIVE
@ STRUCT_SENSITIVE
Definition: variable_sensitivity_configuration.h:30
value_set_pointer_abstract_object.h
liveness_context.h
initialize_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...
Definition: variable_sensitivity_object_factory.cpp:72
create_abstract_object
abstract_object_pointert create_abstract_object(const typet type, bool top, bool bottom, const exprt &e, const abstract_environmentt &environment, const namespacet &ns)
Definition: variable_sensitivity_object_factory.cpp:22
STRUCT_INSENSITIVE
@ STRUCT_INSENSITIVE
Definition: variable_sensitivity_configuration.h:31