@@ -7,55 +7,49 @@ Author: Daniel Kroening, kroening@kroening.com
77\*******************************************************************/
88
99#include < util/bitvector_expr.h>
10+ #include < util/bitvector_types.h>
1011#include < util/invariant.h>
1112
1213#include " boolbv.h"
1314
14- literalt boolbvt::convert_overflow (const exprt &expr)
15+ literalt boolbvt::convert_binary_overflow (const binary_overflow_exprt &expr)
1516{
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- };
17+ const bvt &bv0 = convert_bv (expr.lhs ());
18+ const bvt &bv1 = convert_bv (
19+ expr.rhs (),
20+ can_cast_expr<mult_overflow_exprt>(expr)
21+ ? optionalt<std::size_t >{bv0.size ()}
22+ : nullopt );
23+
24+ const bv_utilst::representationt rep =
25+ can_cast_type<signedbv_typet>(expr.lhs ().type ())
26+ ? bv_utilst::representationt::SIGNED
27+ : bv_utilst::representationt::UNSIGNED;
28+
3529 if (
3630 const auto plus_overflow = expr_try_dynamic_cast<plus_overflow_exprt>(expr))
3731 {
38- return plus_or_minus_conversion (*plus_overflow, &bv_utilst::overflow_add);
32+ if (bv0.size () != bv1.size ())
33+ return SUB::convert_rest (expr);
34+
35+ return bv_utils.overflow_add (bv0, bv1, rep);
3936 }
4037 if (const auto minus = expr_try_dynamic_cast<minus_overflow_exprt>(expr))
4138 {
42- return plus_or_minus_conversion (*minus, &bv_utilst::overflow_sub);
39+ if (bv0.size () != bv1.size ())
40+ return SUB::convert_rest (expr);
41+
42+ return bv_utils.overflow_sub (bv0, bv1, rep);
4343 }
4444 else if (
4545 const auto mult_overflow = expr_try_dynamic_cast<mult_overflow_exprt>(expr))
4646 {
4747 if (
48- mult_overflow->lhs ().type ().id () != ID_unsignedbv &&
49- mult_overflow->lhs ().type ().id () != ID_signedbv)
48+ !can_cast_type<unsignedbv_typet>(expr.lhs ().type ()) &&
49+ !can_cast_type<signedbv_typet>(expr.lhs ().type ()))
50+ {
5051 return SUB::convert_rest (expr);
51-
52- bvt bv0 = convert_bv (mult_overflow->lhs ());
53- bvt bv1 = convert_bv (mult_overflow->rhs (), bv0.size ());
54-
55- bv_utilst::representationt rep =
56- mult_overflow->lhs ().type ().id () == ID_signedbv
57- ? bv_utilst::representationt::SIGNED
58- : bv_utilst::representationt::UNSIGNED;
52+ }
5953
6054 DATA_INVARIANT (
6155 mult_overflow->lhs ().type () == mult_overflow->rhs ().type (),
@@ -65,10 +59,10 @@ literalt boolbvt::convert_overflow(const exprt &expr)
6559 std::size_t new_size=old_size*2 ;
6660
6761 // sign/zero extension
68- bv0= bv_utils.extension (bv0, new_size, rep);
69- bv1= bv_utils.extension (bv1, new_size, rep);
62+ const bvt &bv0_extended = bv_utils.extension (bv0, new_size, rep);
63+ const bvt &bv1_extended = bv_utils.extension (bv1, new_size, rep);
7064
71- bvt result= bv_utils.multiplier (bv0, bv1 , rep);
65+ bvt result = bv_utils.multiplier (bv0_extended, bv1_extended , rep);
7266
7367 if (rep==bv_utilst::representationt::UNSIGNED)
7468 {
@@ -100,23 +94,15 @@ literalt boolbvt::convert_overflow(const exprt &expr)
10094 else if (
10195 const auto shl_overflow = expr_try_dynamic_cast<shl_overflow_exprt>(expr))
10296 {
103- const bvt &bv0 = convert_bv (shl_overflow->lhs ());
104- const bvt &bv1 = convert_bv (shl_overflow->rhs ());
105-
10697 std::size_t old_size = bv0.size ();
10798 std::size_t new_size = old_size * 2 ;
10899
109- bv_utilst::representationt rep =
110- shl_overflow->lhs ().type ().id () == ID_signedbv
111- ? bv_utilst::representationt::SIGNED
112- : bv_utilst::representationt::UNSIGNED;
113-
114100 bvt bv_ext=bv_utils.extension (bv0, new_size, rep);
115101
116102 bvt result=bv_utils.shift (bv_ext, bv_utilst::shiftt::SHIFT_LEFT, bv1);
117103
118104 // a negative shift is undefined; yet this isn't an overflow
119- literalt neg_shift = shl_overflow-> lhs (). type (). id () == ID_unsignedbv
105+ literalt neg_shift = rep == bv_utilst::representationt::UNSIGNED
120106 ? const_literal (false )
121107 : bv1.back (); // sign bit
122108
@@ -161,7 +147,13 @@ literalt boolbvt::convert_overflow(const exprt &expr)
161147 return
162148 prop.land (!neg_shift, prop.lselect (undef, prop.lor (bv0), overflow));
163149 }
164- else if (
150+
151+ return SUB::convert_rest (expr);
152+ }
153+
154+ literalt boolbvt::convert_unary_overflow (const unary_overflow_exprt &expr)
155+ {
156+ if (
165157 const auto unary_minus_overflow =
166158 expr_try_dynamic_cast<unary_minus_overflow_exprt>(expr))
167159 {
0 commit comments