18
18
// / at index `end_index'`.
19
19
// / Where start_index' is max(0, start_index) and end_index' is
20
20
// / 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.
21
24
// /
22
25
// / 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$
24
28
// / 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$
27
30
// /
28
31
// / \param res: an array of characters expression
29
32
// / \param s1: an array of characters expression
@@ -59,7 +62,8 @@ exprt string_constraint_generatort::add_axioms_for_concat_substr(
59
62
fresh_univ_index (" QA_index_concat2" , res.length ().type ());
60
63
const equal_exprt res_eq (
61
64
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);
63
67
}());
64
68
65
69
return from_integer (0 , get_return_code_type ());
@@ -77,10 +81,13 @@ exprt length_constraint_for_concat_substr(
77
81
const exprt &start,
78
82
const exprt &end)
79
83
{
84
+ PRECONDITION (res.length ().type ().id () == ID_signedbv);
80
85
const exprt start1 = maximum (start, from_integer (0 , start.type ()));
81
86
const exprt end1 = maximum (minimum (end, s2.length ()), start1);
82
87
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));
84
91
}
85
92
86
93
// / Add axioms enforcing that the length of `res` is that of the concatenation
0 commit comments