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