CBMC
construct_value_expr_from_smt.cpp
Go to the documentation of this file.
1 // Author: Diffblue Ltd.
2 
3 #include <util/arith_tools.h>
4 #include <util/c_types.h>
5 #include <util/namespace.h>
6 #include <util/pointer_expr.h>
7 #include <util/std_expr.h>
8 #include <util/std_types.h>
9 #include <util/type.h>
10 
13 
15 {
16 private:
18  const namespacet &ns;
19  std::optional<exprt> result;
20 
22  const typet &type_to_construct,
23  const namespacet &ns)
25  {
26  }
27 
28  void visit(const smt_bool_literal_termt &bool_literal) override
29  {
30  INVARIANT(
32  "Bool terms may only be used to construct bool typed expressions.");
33  result = bool_literal.value() ? (exprt)true_exprt{} : false_exprt{};
34  }
35 
36  void visit(const smt_identifier_termt &identifier_term) override
37  {
38  INVARIANT(
39  false, "Unexpected conversion of identifier to value expression.");
40  }
41 
42  void visit(const smt_bit_vector_constant_termt &bit_vector_constant) override
43  {
44  const auto sort_width = bit_vector_constant.get_sort().bit_width();
45  if(
46  const auto pointer_type =
47  type_try_dynamic_cast<pointer_typet>(type_to_construct))
48  {
49  INVARIANT(
50  pointer_type->get_width() == sort_width,
51  "Width of smt bit vector term must match the width of pointer type.");
52  if(bit_vector_constant.value() == 0)
53  {
55  }
56  else
57  {
58  // The reason we are manually constructing a constant_exprt here is a
59  // limitation in the design of `from_integer`, which only allows it to
60  // be used with pointer values of 0 (null pointers).
62  integer2bvrep(bit_vector_constant.value(), sort_width),
63  *pointer_type};
64  }
65  return;
66  }
67  if(
68  const auto bitvector_type =
69  type_try_dynamic_cast<bitvector_typet>(type_to_construct))
70  {
71  INVARIANT(
72  bitvector_type->get_width() == sort_width,
73  "Width of smt bit vector term must match the width of bit vector "
74  "type.");
75  result = from_integer(bit_vector_constant.value(), type_to_construct);
76  return;
77  }
78  if(
79  const auto c_enum_tag_type =
80  type_try_dynamic_cast<c_enum_tag_typet>(type_to_construct))
81  {
82  const c_enum_typet &real_type = ns.follow_tag(*c_enum_tag_type);
83  INVARIANT(
85  sort_width,
86  "Width of smt bit vector term must match the width of bit vector "
87  "underlying type of the original c_enum type.");
88  result = from_integer(bit_vector_constant.value(), real_type);
89  result->type() = type_to_construct;
90  return;
91  }
92 
93  INVARIANT(
94  false,
95  "construct_value_expr_from_smt for bit vector should not be applied to "
96  "unsupported type " +
98  }
99 
100  void
101  visit(const smt_function_application_termt &function_application) override
102  {
103  INVARIANT(
104  false,
105  "Unexpected conversion of function application to value expression.");
106  }
107 
108  void visit(const smt_forall_termt &forall) override
109  {
110  INVARIANT(
111  false, "Unexpected conversion of forall quantifier to value expression.");
112  }
113 
114  void visit(const smt_exists_termt &exists) override
115  {
116  INVARIANT(
117  false, "Unexpected conversion of exists quantifier to value expression.");
118  }
119 
120 public:
124  static exprt make(
125  const smt_termt &value_term,
126  const typet &type_to_construct,
127  const namespacet &ns)
128  {
130  value_term.accept(factory);
131  INVARIANT(factory.result.has_value(), "Factory must result in expr value.");
132  return *factory.result;
133  }
134 };
135 
137  const smt_termt &value_term,
138  const typet &type_to_construct,
139  const namespacet &ns)
140 {
141  return value_expr_from_smt_factoryt::make(value_term, type_to_construct, ns);
142 }
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
irep_idt integer2bvrep(const mp_integer &src, std::size_t width)
convert an integer to bit-vector representation with given width This uses two's complement for negat...
const bitvector_typet & to_bitvector_type(const typet &type)
Cast a typet to a bitvector_typet.
pointer_typet pointer_type(const typet &subtype)
Definition: c_types.cpp:235
std::size_t get_width() const
Definition: std_types.h:920
The Boolean type.
Definition: std_types.h:36
The type of C enums.
Definition: c_types.h:239
const typet & underlying_type() const
Definition: c_types.h:307
A constant literal expression.
Definition: std_expr.h:2987
Base class for all expressions.
Definition: expr.h:56
The Boolean constant false.
Definition: std_expr.h:3064
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:482
const union_typet & follow_tag(const union_tag_typet &) const
Follow type tag of union type.
Definition: namespace.cpp:63
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:94
The null pointer constant.
Definition: pointer_expr.h:909
const smt_bit_vector_sortt & get_sort() const
Definition: smt_terms.cpp:121
mp_integer value() const
Definition: smt_terms.cpp:116
std::size_t bit_width() const
Definition: smt_sorts.cpp:62
bool value() const
Definition: smt_terms.cpp:47
Stores identifiers in unescaped and unquoted form.
Definition: smt_terms.h:93
void accept(smt_term_const_downcast_visitort &) const
Definition: smt_terms.cpp:236
The Boolean constant true.
Definition: std_expr.h:3055
The type of an expression, extends irept.
Definition: type.h:29
void visit(const smt_bool_literal_termt &bool_literal) override
void visit(const smt_function_application_termt &function_application) override
void visit(const smt_identifier_termt &identifier_term) override
static exprt make(const smt_termt &value_term, const typet &type_to_construct, const namespacet &ns)
This function is complete the external interface to this class.
void visit(const smt_forall_termt &forall) override
void visit(const smt_bit_vector_constant_termt &bit_vector_constant) override
void visit(const smt_exists_termt &exists) override
value_expr_from_smt_factoryt(const typet &type_to_construct, const namespacet &ns)
exprt construct_value_expr_from_smt(const smt_termt &value_term, const typet &type_to_construct, const namespacet &ns)
Given a value_term and a type_to_construct, this function constructs a value exprt with a value based...
mini_bddt exists(const mini_bddt &u, const unsigned var)
Definition: miniBDD.cpp:556
API to expression classes for Pointers.
API to expression classes.
Pre-defined types.
Defines typet, type_with_subtypet and type_with_subtypest.