CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
array_pool.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: String solver
4
5Author: Romain Brenguier, romain.brenguier@diffblue.com
6
7\*******************************************************************/
8
9#include "array_pool.h"
10
11#include <util/pointer_expr.h>
12
14operator()(const irep_idt &prefix, const typet &type)
15{
16 std::ostringstream buf;
17 buf << "string_refinement#" << prefix << "#" << ++symbol_count;
18 irep_idt name(buf.str());
19 symbol_exprt result(name, type);
20#ifdef DEBUG
21 created_symbols.push_back(result);
22#endif
23 return result;
24}
25
27{
29 {
30 return if_exprt{
31 if_expr->cond(),
34 }
35
36 auto emplace_result =
38 if(emplace_result.second)
39 {
40 emplace_result.first->second =
41 fresh_symbol("string_length", s.length_type());
42 }
43
44 return emplace_result.first->second;
45}
46
47std::optional<exprt>
49{
50 auto find_result = length_of_array.find(s);
51 if(find_result != length_of_array.end())
52 return find_result->second;
53 return {};
54}
55
58{
60 symbol_exprt content = fresh_symbol("string_content", array_type);
62 arrays_of_pointers.emplace(
63 address_of_exprt(index_exprt(str, from_integer(0, index_type))), str);
64
65 // add length to length_of_array map
67
68 return str;
69}
70
75 const exprt &char_pointer,
77{
78 PRECONDITION(char_pointer.type().id() == ID_pointer);
81 to_array_type(char_array_type).element_type().id() == ID_unsignedbv ||
82 to_array_type(char_array_type).element_type().id() == ID_signedbv);
83
84 if(char_pointer.id() == ID_if)
85 {
87 const array_string_exprt t =
89 const array_string_exprt f =
92 to_array_type(char_array_type).element_type(),
94 if_expr.cond(),
95 to_array_type(t.type()).size(),
96 to_array_type(f.type()).size()));
97 // BEWARE: this expression is possibly type-inconsistent and must not be
98 // used for any purposes other than passing it to concretization.
99 // Array if-exprts must be replaced (using substitute_array_access) before
100 // passing the lemmas to the solver.
101 return to_array_string_expr(if_exprt(if_expr.cond(), t, f, array_type));
102 }
103
104 const bool is_constant_array =
105 char_pointer.id() == ID_address_of &&
106 to_address_of_expr(char_pointer).object().id() == ID_index &&
107 to_index_expr(to_address_of_expr(char_pointer).object()).array().id() ==
108 ID_array;
109
111 {
114 }
115 const std::string symbol_name = "char_array_" + id2string(char_pointer.id());
116 const auto array_sym =
118 const auto insert_result =
120
121 // add length to length_of_array map
123
124 return to_array_string_expr(insert_result.first->second);
125}
126
137 std::unordered_map<array_string_exprt, exprt, irep_hash> &length_of_array,
139{
141 array_expr.id() != ID_if,
142 "attempt_assign_length_from_type does not handle if exprts");
143 // This invariant seems always true, but I don't know why.
144 // If we find a case where this is violated, try calling
145 // attempt_assign_length_from_type on the true and false cases.
146 const exprt &size_from_type = to_array_type(array_expr.type()).size();
147 const exprt &size_to_assign =
150 : symbol_generator("string_length", array_expr.length_type());
151
152 const auto emplace_result =
153 length_of_array.emplace(array_expr, size_to_assign);
154 INVARIANT(
155 emplace_result.second,
156 "attempt_assign_length_from_type should only be called when no entry"
157 "for the array_string_exprt exists in the length_of_array map");
158}
159
161 const exprt &pointer_expr,
163{
164 const auto it_bool =
165 arrays_of_pointers.insert(std::make_pair(pointer_expr, array_expr));
166
167 INVARIANT(
168 it_bool.second, "should not associate two arrays to the same pointer");
169
171 {
173 }
174}
175
178const std::unordered_map<array_string_exprt, exprt, irep_hash> &
180{
181 return length_of_array;
182}
183
184array_string_exprt array_poolt::find(const exprt &pointer, const exprt &length)
185{
187 to_pointer_type(pointer.type()).base_type(), length);
188 const array_string_exprt array =
190 return array;
191}
192
194{
196 return array_pool.find(string_argument.op1(), string_argument.op0());
197}
198
200{
202 const refined_string_exprt &str = to_string_expr(expr);
203 return array_pool.find(str.content(), str.length());
204}
constant_exprt from_integer(const mp_integer &int_value, const typet &type)
static void attempt_assign_length_from_type(const array_string_exprt &array_expr, std::unordered_map< array_string_exprt, exprt, irep_hash > &length_of_array, symbol_generatort &symbol_generator)
Given an array_string_exprt, get the size of the underlying array.
array_string_exprt of_argument(array_poolt &array_pool, const exprt &arg)
Converts a struct containing a length and pointer to an array.
array_string_exprt get_string_expr(array_poolt &array_pool, const exprt &expr)
Fetch the string_exprt corresponding to the given refined_string_exprt.
Associates arrays and length to pointers, so that the string refinement can transform builtin functio...
bitvector_typet char_type()
Definition c_types.cpp:106
Operator to return the address of an object.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
Correspondance between arrays and pointers string representations.
Definition array_pool.h:42
std::unordered_map< exprt, array_string_exprt, irep_hash > arrays_of_pointers
Associate arrays to char pointers Invariant: Each array_string_exprt in this map has a corresponding ...
Definition array_pool.h:95
std::optional< exprt > get_length_if_exists(const array_string_exprt &s) const
As opposed to get_length(), do not create a new symbol if the length of the array_string_exprt does n...
std::unordered_map< array_string_exprt, exprt, irep_hash > length_of_array
Associate length to arrays of infinite size.
Definition array_pool.h:98
array_string_exprt make_char_array_for_char_pointer(const exprt &char_pointer, const typet &char_array_type)
Helper function for find.
exprt get_or_create_length(const array_string_exprt &s)
Get the length of an array_string_exprt from the array_pool.
void insert(const exprt &pointer_expr, const array_string_exprt &array)
array_string_exprt fresh_string(const typet &index_type, const typet &char_type)
Construct a string expression whose length and content are new variables.
array_string_exprt find(const exprt &pointer, const exprt &length)
Creates a new array if the pointer is not pointing to an array.
symbol_generatort & fresh_symbol
Generate fresh symbols.
Definition array_pool.h:101
const std::unordered_map< array_string_exprt, exprt, irep_hash > & created_strings() const
Return a map mapping all array_string_exprt of the array_pool to their length.
const typet & length_type() const
Definition string_expr.h:70
Arrays with given size.
Definition std_types.h:807
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
typet & type()
Return the type of the expression.
Definition expr.h:84
The trinary if-then-else operator.
Definition std_expr.h:2497
Array index operator.
Definition std_expr.h:1470
An expression denoting infinity.
Definition std_expr.h:3224
const exprt & length() const
const exprt & content() const
Expression to hold a symbol (variable)
Definition std_expr.h:131
Generation of fresh symbols of a given type.
Definition array_pool.h:22
symbol_exprt operator()(const irep_idt &prefix, const typet &type=bool_typet())
Generate a new symbol expression of the given type with some prefix.
unsigned symbol_count
Definition array_pool.h:31
The type of an expression, extends irept.
Definition type.h:29
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
API to expression classes for Pointers.
const address_of_exprt & to_address_of_expr(const exprt &expr)
Cast an exprt to an address_of_exprt.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
bool is_refined_string_type(const typet &type)
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition invariant.h:534
#define PRECONDITION(CONDITION)
Definition invariant.h:463
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
const index_exprt & to_index_expr(const exprt &expr)
Cast an exprt to an index_exprt.
Definition std_expr.h:1538
const if_exprt & to_if_expr(const exprt &expr)
Cast an exprt to an if_exprt.
Definition std_expr.h:2577
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
Definition std_types.h:888
array_string_exprt & to_array_string_expr(exprt &expr)
Definition string_expr.h:96
refined_string_exprt & to_string_expr(exprt &expr)