Skip to content

Commit 0d7310a

Browse files
Merge pull request diffblue#1691 from romainbrenguier/bugfix/getClass#TG-1245
Improve cprover_string_literal argument handling TG-1245
2 parents e308a32 + 23c3561 commit 0d7310a

File tree

7 files changed

+485
-28
lines changed

7 files changed

+485
-28
lines changed

src/solvers/refinement/string_constraint_generator.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,11 @@ class string_constraint_generatort final
164164
const exprt &end_index);
165165
exprt add_axioms_for_concat(const function_application_exprt &f);
166166
exprt add_axioms_for_concat_code_point(const function_application_exprt &f);
167-
exprt add_axioms_for_constant(const array_string_exprt &res, irep_idt sval);
167+
exprt add_axioms_for_constant(
168+
const array_string_exprt &res,
169+
irep_idt sval,
170+
const exprt &guard = true_exprt());
171+
168172
exprt add_axioms_for_delete(
169173
const array_string_exprt &res,
170174
const array_string_exprt &str,
@@ -195,6 +199,11 @@ class string_constraint_generatort final
195199
exprt add_axioms_for_insert_char(const function_application_exprt &f);
196200
exprt add_axioms_for_insert_float(const function_application_exprt &f);
197201
exprt add_axioms_for_insert_double(const function_application_exprt &f);
202+
203+
exprt add_axioms_for_cprover_string(
204+
const array_string_exprt &res,
205+
const exprt &arg,
206+
const exprt &guard);
198207
exprt add_axioms_from_literal(const function_application_exprt &f);
199208
exprt add_axioms_from_int(const function_application_exprt &f);
200209
exprt add_axioms_from_int(

src/solvers/refinement/string_constraint_generator_constants.cpp

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ Author: Romain Brenguier, [email protected]
1919
/// equal.
2020
/// \param res: array of characters for the result
2121
/// \param sval: a string constant
22+
/// \param guard: condition under which the axiom should apply, true by default
2223
/// \return integer expression equal to zero
2324
exprt string_constraint_generatort::add_axioms_for_constant(
2425
const array_string_exprt &res,
25-
irep_idt sval)
26+
irep_idt sval,
27+
const exprt &guard)
2628
{
2729
const typet &index_type = res.length().type();
2830
const typet &char_type = res.content().type().subtype();
@@ -43,12 +45,12 @@ exprt string_constraint_generatort::add_axioms_for_constant(
4345
const exprt idx = from_integer(i, index_type);
4446
const exprt c = from_integer(str[i], char_type);
4547
const equal_exprt lemma(res[idx], c);
46-
axioms.push_back(lemma);
48+
axioms.push_back(implies_exprt(guard, lemma));
4749
}
4850

4951
const exprt s_length = from_integer(str.size(), index_type);
5052

51-
axioms.push_back(res.axiom_for_has_length(s_length));
53+
axioms.push_back(implies_exprt(guard, equal_exprt(res.length(), s_length)));
5254
return from_integer(0, get_return_code_type());
5355
}
5456

@@ -65,6 +67,39 @@ exprt string_constraint_generatort::add_axioms_for_empty_string(
6567
return from_integer(0, get_return_code_type());
6668
}
6769

70+
/// Convert an expression of type string_typet to a string_exprt
71+
/// \param res: string expression for the result
72+
/// \param arg: expression of type string typet
73+
/// \param guard: condition under which `res` should be equal to arg
74+
/// \return 0 if constraints were added, 1 if expression could not be handled
75+
/// and no constraint was added. Expression we can handle are of the
76+
/// form \f$ e := "<string constant>" | (expr)? e : e \f$
77+
exprt string_constraint_generatort::add_axioms_for_cprover_string(
78+
const array_string_exprt &res,
79+
const exprt &arg,
80+
const exprt &guard)
81+
{
82+
if(const auto if_expr = expr_try_dynamic_cast<if_exprt>(arg))
83+
{
84+
const and_exprt guard_true(guard, if_expr->cond());
85+
const exprt return_code_true =
86+
add_axioms_for_cprover_string(res, if_expr->true_case(), guard_true);
87+
88+
const and_exprt guard_false(guard, not_exprt(if_expr->cond()));
89+
const exprt return_code_false =
90+
add_axioms_for_cprover_string(res, if_expr->false_case(), guard_false);
91+
92+
return if_exprt(
93+
equal_exprt(return_code_true, from_integer(0, get_return_code_type())),
94+
return_code_false,
95+
return_code_true);
96+
}
97+
else if(const auto constant_expr = expr_try_dynamic_cast<constant_exprt>(arg))
98+
return add_axioms_for_constant(res, constant_expr->get_value(), guard);
99+
else
100+
return from_integer(1, get_return_code_type());
101+
}
102+
68103
/// String corresponding to an internal cprover string
69104
///
70105
/// Add axioms ensuring that the returned string expression is equal to the
@@ -79,7 +114,5 @@ exprt string_constraint_generatort::add_axioms_from_literal(
79114
const function_application_exprt::argumentst &args=f.arguments();
80115
PRECONDITION(args.size() == 3); // Bad args to string literal?
81116
const array_string_exprt res = char_array_of_pointer(args[1], args[0]);
82-
const exprt &arg = args[2];
83-
irep_idt sval=to_constant_expr(arg).get_value();
84-
return add_axioms_for_constant(res, sval);
117+
return add_axioms_for_cprover_string(res, args[2], true_exprt());
85118
}

0 commit comments

Comments
 (0)