Skip to content

Commit c40b836

Browse files
Truncate string concatenations in case of overflow
1 parent c52c813 commit c40b836

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

src/solvers/refinement/string_constraint_generator_concat.cpp

+12-5
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@ Author: Romain Brenguier, [email protected]
1818
/// at index `end_index'`.
1919
/// Where start_index' is max(0, start_index) and end_index' is
2020
/// max(min(end_index, s2.length), start_index')
21+
/// If s1.length + end_index' - start_index' is greater than the maximal integer
22+
/// of the type of res.length, then the result gets truncated to the size
23+
/// of this maximal integer.
2124
///
2225
/// These axioms are:
23-
/// 1. \f$|res| = |s_1| + end\_index' - start\_index' \f$
26+
/// 1. \f$|res| = overflow ? |s_1| + end\_index' - start\_index'
27+
/// : max_int \f$
2428
/// 2. \f$\forall i<|s_1|. res[i]=s_1[i] \f$
25-
/// 3. \f$\forall i< end\_index' - start\_index'.\ res[i+|s_1|]
26-
/// = s_2[start\_index'+i]\f$
29+
/// 3. \f$\forall i< |res| - |s_1|.\ res[i+|s_1|] = s_2[start\_index'+i]\f$
2730
///
2831
/// \param res: an array of characters expression
2932
/// \param s1: an array of characters expression
@@ -59,7 +62,8 @@ exprt string_constraint_generatort::add_axioms_for_concat_substr(
5962
fresh_univ_index("QA_index_concat2", res.length().type());
6063
const equal_exprt res_eq(
6164
res[plus_exprt(idx2, s1.length())], s2[plus_exprt(start1, idx2)]);
62-
return string_constraintt(idx2, minus_exprt(end1, start1), res_eq);
65+
const minus_exprt upper_bound(res.length(), s1.length());
66+
return string_constraintt(idx2, upper_bound, res_eq);
6367
}());
6468

6569
return from_integer(0, get_return_code_type());
@@ -77,10 +81,13 @@ exprt length_constraint_for_concat_substr(
7781
const exprt &start,
7882
const exprt &end)
7983
{
84+
PRECONDITION(res.length().type().id() == ID_signedbv);
8085
const exprt start1 = maximum(start, from_integer(0, start.type()));
8186
const exprt end1 = maximum(minimum(end, s2.length()), start1);
8287
const plus_exprt res_length(s1.length(), minus_exprt(end1, start1));
83-
return equal_exprt(res.length(), res_length);
88+
const exprt overflow = sum_overflows(res_length);
89+
const exprt max_int = to_signedbv_type(res.length().type()).largest_expr();
90+
return equal_exprt(res.length(), if_exprt(overflow, max_int, res_length));
8491
}
8592

8693
/// Add axioms enforcing that the length of `res` is that of the concatenation

0 commit comments

Comments
 (0)