@@ -6,51 +6,59 @@ Author: Daniel Kroening, kroening@kroening.com
66
77\*******************************************************************/
88
9- #include " boolbv.h"
10-
9+ #include < util/bitvector_expr.h>
1110#include < util/invariant.h>
1211
12+ #include " boolbv.h"
13+
1314literalt boolbvt::convert_overflow (const exprt &expr)
1415{
15- if (expr.id ()==ID_overflow_plus ||
16- expr.id ()==ID_overflow_minus)
16+ const auto plus_or_minus_conversion =
17+ [&](
18+ const binary_overflow_exprt &overflow_expr,
19+ const std::function<literalt (
20+ bv_utilst *, const bvt &, const bvt &, bv_utilst::representationt)>
21+ &bv_util_overflow) {
22+ const bvt &bv0 = convert_bv (overflow_expr.lhs ());
23+ const bvt &bv1 = convert_bv (overflow_expr.rhs ());
24+
25+ if (bv0.size () != bv1.size ())
26+ return SUB::convert_rest (expr);
27+
28+ bv_utilst::representationt rep =
29+ overflow_expr.lhs ().type ().id () == ID_signedbv
30+ ? bv_utilst::representationt::SIGNED
31+ : bv_utilst::representationt::UNSIGNED;
32+
33+ return bv_util_overflow (&bv_utils, bv0, bv1, rep);
34+ };
35+ if (
36+ const auto plus_overflow = expr_try_dynamic_cast<plus_overflow_exprt>(expr))
1737 {
18- const auto &overflow_expr = to_binary_expr (expr);
19-
20- const bvt &bv0 = convert_bv (overflow_expr.lhs ());
21- const bvt &bv1 = convert_bv (overflow_expr.rhs ());
22-
23- if (bv0.size ()!=bv1.size ())
24- return SUB::convert_rest (expr);
25-
26- bv_utilst::representationt rep =
27- overflow_expr.lhs ().type ().id () == ID_signedbv
28- ? bv_utilst::representationt::SIGNED
29- : bv_utilst::representationt::UNSIGNED;
30-
31- return expr.id ()==ID_overflow_minus?
32- bv_utils.overflow_sub (bv0, bv1, rep):
33- bv_utils.overflow_add (bv0, bv1, rep);
38+ return plus_or_minus_conversion (*plus_overflow, &bv_utilst::overflow_add);
3439 }
35- else if (expr.id ()==ID_overflow_mult)
40+ if (const auto minus = expr_try_dynamic_cast<minus_overflow_exprt>(expr))
41+ {
42+ return plus_or_minus_conversion (*minus, &bv_utilst::overflow_sub);
43+ }
44+ else if (
45+ const auto mult_overflow = expr_try_dynamic_cast<mult_overflow_exprt>(expr))
3646 {
37- const auto &overflow_expr = to_binary_expr (expr);
38-
3947 if (
40- overflow_expr. lhs ().type ().id () != ID_unsignedbv &&
41- overflow_expr. lhs ().type ().id () != ID_signedbv)
48+ mult_overflow-> lhs ().type ().id () != ID_unsignedbv &&
49+ mult_overflow-> lhs ().type ().id () != ID_signedbv)
4250 return SUB::convert_rest (expr);
4351
44- bvt bv0 = convert_bv (overflow_expr. lhs ());
45- bvt bv1 = convert_bv (overflow_expr. rhs (), bv0.size ());
52+ bvt bv0 = convert_bv (mult_overflow-> lhs ());
53+ bvt bv1 = convert_bv (mult_overflow-> rhs (), bv0.size ());
4654
4755 bv_utilst::representationt rep =
48- overflow_expr. lhs ().type ().id () == ID_signedbv
56+ mult_overflow-> lhs ().type ().id () == ID_signedbv
4957 ? bv_utilst::representationt::SIGNED
5058 : bv_utilst::representationt::UNSIGNED;
5159
5260 DATA_INVARIANT (
53- overflow_expr. lhs ().type () == overflow_expr. rhs ().type (),
61+ mult_overflow-> lhs ().type () == mult_overflow-> rhs ().type (),
5462 " operands of overflow_mult expression shall have same type" );
5563
5664 std::size_t old_size=bv0.size ();
@@ -89,18 +97,17 @@ literalt boolbvt::convert_overflow(const exprt &expr)
8997 return !prop.lor (all_one, all_zero);
9098 }
9199 }
92- else if (expr.id () == ID_overflow_shl)
100+ else if (
101+ const auto shl_overflow = expr_try_dynamic_cast<shl_overflow_exprt>(expr))
93102 {
94- const auto &overflow_expr = to_binary_expr (expr);
95-
96- const bvt &bv0 = convert_bv (overflow_expr.lhs ());
97- const bvt &bv1 = convert_bv (overflow_expr.rhs ());
103+ const bvt &bv0 = convert_bv (shl_overflow->lhs ());
104+ const bvt &bv1 = convert_bv (shl_overflow->rhs ());
98105
99106 std::size_t old_size = bv0.size ();
100107 std::size_t new_size = old_size * 2 ;
101108
102109 bv_utilst::representationt rep =
103- overflow_expr. lhs ().type ().id () == ID_signedbv
110+ shl_overflow-> lhs ().type ().id () == ID_signedbv
104111 ? bv_utilst::representationt::SIGNED
105112 : bv_utilst::representationt::UNSIGNED;
106113
@@ -109,7 +116,7 @@ literalt boolbvt::convert_overflow(const exprt &expr)
109116 bvt result=bv_utils.shift (bv_ext, bv_utilst::shiftt::SHIFT_LEFT, bv1);
110117
111118 // a negative shift is undefined; yet this isn't an overflow
112- literalt neg_shift = overflow_expr. lhs ().type ().id () == ID_unsignedbv
119+ literalt neg_shift = shl_overflow-> lhs ().type ().id () == ID_unsignedbv
113120 ? const_literal (false )
114121 : bv1.back (); // sign bit
115122
@@ -154,11 +161,11 @@ literalt boolbvt::convert_overflow(const exprt &expr)
154161 return
155162 prop.land (!neg_shift, prop.lselect (undef, prop.lor (bv0), overflow));
156163 }
157- else if (expr.id ()==ID_overflow_unary_minus)
164+ else if (
165+ const auto unary_minus_overflow =
166+ expr_try_dynamic_cast<unary_minus_overflow_exprt>(expr))
158167 {
159- const auto &overflow_expr = to_unary_expr (expr);
160-
161- const bvt &bv = convert_bv (overflow_expr.op ());
168+ const bvt &bv = convert_bv (unary_minus_overflow->op ());
162169
163170 return bv_utils.overflow_negate (bv);
164171 }
0 commit comments