12 #include <unordered_set>
28 const exprt &return_code,
31 const auto name = expr_checked_cast<symbol_exprt>(fun_app.
function());
34 const irep_idt &
id = name.get_identifier();
36 if(
id == ID_cprover_string_insert_func)
37 return util_make_unique<string_insertion_builtin_functiont>(
38 return_code, fun_app.
arguments(), array_pool);
40 if(
id == ID_cprover_string_concat_func)
41 return util_make_unique<string_concatenation_builtin_functiont>(
42 return_code, fun_app.
arguments(), array_pool);
44 if(
id == ID_cprover_string_concat_char_func)
45 return util_make_unique<string_concat_char_builtin_functiont>(
46 return_code, fun_app.
arguments(), array_pool);
48 if(
id == ID_cprover_string_format_func)
49 return util_make_unique<string_format_builtin_functiont>(
50 return_code, fun_app.
arguments(), array_pool);
52 if(
id == ID_cprover_string_of_int_func)
53 return util_make_unique<string_of_int_builtin_functiont>(
54 return_code, fun_app.
arguments(), array_pool);
56 if(
id == ID_cprover_string_char_set_func)
57 return util_make_unique<string_set_char_builtin_functiont>(
58 return_code, fun_app.
arguments(), array_pool);
60 if(
id == ID_cprover_string_to_lower_case_func)
61 return util_make_unique<string_to_lower_case_builtin_functiont>(
62 return_code, fun_app.
arguments(), array_pool);
64 if(
id == ID_cprover_string_to_upper_case_func)
65 return util_make_unique<string_to_upper_case_builtin_functiont>(
66 return_code, fun_app.
arguments(), array_pool);
68 return util_make_unique<string_builtin_function_with_no_evalt>(
69 return_code, fun_app, array_pool);
76 if(!entry_inserted.second)
79 string_nodes.emplace_back(e, entry_inserted.first->second);
83 std::unique_ptr<const string_dependenciest::string_nodet>
88 return util_make_unique<const string_nodet>(
string_nodes.at(it->second));
93 std::unique_ptr<string_builtin_functiont> builtin_function)
145 fun_app.
arguments()[1].type().id() == ID_pointer)
153 for(
const auto &expr : fun_app.
arguments())
158 [&](
const exprt &e) {
159 if(is_refined_string_type(e.type()))
161 const auto string_struct = expr_checked_cast<struct_exprt>(e);
162 const auto string = of_argument(array_pool, string_struct);
163 dependencies.add_dependency(string, builtin_function_node);
171 const std::function<
exprt(
const exprt &)> &get_value)
const
181 const auto &f = node.result_from;
182 if(f && node.dependencies.size() == 1)
204 const auto fun_app = expr_try_dynamic_cast<function_application_exprt>(expr);
208 bool copy_differs_from_expr =
false;
209 for(std::size_t i = 0; i < expr.
operands().size(); ++i)
216 copy_differs_from_expr =
true;
219 if(copy_differs_from_expr)
224 const exprt return_code = fresh_symbol(
"string_builtin_return", expr.
type());
225 auto builtin_function =
229 const auto &builtin_function_node =
230 dependencies.
make_node(std::move(builtin_function));
233 const auto &string_result =
236 dependencies.
add_dependency(*string_result, builtin_function_node);
237 auto &node = dependencies.
get_node(*string_result);
241 for(
const auto &arg : builtin_function_node.data->string_arguments())
245 (void)dependencies.
get_node(atomic);
251 dependencies, *fun_app, builtin_function_node, array_pool);
258 const std::function<
void(
const string_nodet &)> &f)
const
260 for(
const auto &s : node.
data->string_arguments())
262 std::vector<std::reference_wrapper<const exprt>> stack({s});
263 while(!stack.empty())
265 const auto current = stack.back();
267 if(
const auto if_expr = expr_try_dynamic_cast<if_exprt>(current.get()))
269 stack.emplace_back(if_expr->true_case());
270 stack.emplace_back(if_expr->false_case());
277 "dependencies of the node should have been added to the graph at "
279 current.get().pretty());
296 const std::function<
void(
const nodet &)> &f)
const
315 const std::function<
void(
const nodet &)> &f)
const
318 f(
nodet(string_node));
325 const auto for_each =
326 [&](
const std::function<void(
const nodet &)> &f) {
329 const auto for_each_succ =
330 [&](
const nodet &n,
const std::function<void(
const nodet &)> &f) {
333 const auto node_to_string = [&](
const nodet &n) {
334 std::stringstream ostream;
340 return ostream.str();
342 stream <<
"digraph dependencies {\n";
343 output_dot_generic<nodet>(
344 stream, for_each, for_each_succ, node_to_string, node_to_string);
345 stream <<
'}' << std::endl;
352 std::unordered_set<nodet, node_hash> test_dependencies;
355 if(builtin.data->maybe_testing_function())
356 test_dependencies.insert(
nodet(builtin));
363 const std::function<
void(
const nodet &)> &f) {
370 if(test_dependencies.count(
nodet(node)))
373 merge(constraints, builtin.data->constraints(generator, message_handler));
376 constraints.existential.push_back(node.data->length_constraint());