7
7
\*******************************************************************/
8
8
9
9
#include < util/bitvector_expr.h>
10
+ #include < util/bitvector_types.h>
10
11
#include < util/invariant.h>
11
12
12
13
#include " boolbv.h"
13
14
14
- literalt boolbvt::convert_overflow (const exprt &expr)
15
+ literalt boolbvt::convert_binary_overflow (const binary_overflow_exprt &expr)
15
16
{
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
+
35
29
if (
36
30
const auto plus_overflow = expr_try_dynamic_cast<plus_overflow_exprt>(expr))
37
31
{
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);
39
36
}
40
37
if (const auto minus = expr_try_dynamic_cast<minus_overflow_exprt>(expr))
41
38
{
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);
43
43
}
44
44
else if (
45
45
const auto mult_overflow = expr_try_dynamic_cast<mult_overflow_exprt>(expr))
46
46
{
47
47
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
+ {
50
51
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
+ }
59
53
60
54
DATA_INVARIANT (
61
55
mult_overflow->lhs ().type () == mult_overflow->rhs ().type (),
@@ -65,10 +59,10 @@ literalt boolbvt::convert_overflow(const exprt &expr)
65
59
std::size_t new_size=old_size*2 ;
66
60
67
61
// 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);
70
64
71
- bvt result= bv_utils.multiplier (bv0, bv1 , rep);
65
+ bvt result = bv_utils.multiplier (bv0_extended, bv1_extended , rep);
72
66
73
67
if (rep==bv_utilst::representationt::UNSIGNED)
74
68
{
@@ -100,23 +94,15 @@ literalt boolbvt::convert_overflow(const exprt &expr)
100
94
else if (
101
95
const auto shl_overflow = expr_try_dynamic_cast<shl_overflow_exprt>(expr))
102
96
{
103
- const bvt &bv0 = convert_bv (shl_overflow->lhs ());
104
- const bvt &bv1 = convert_bv (shl_overflow->rhs ());
105
-
106
97
std::size_t old_size = bv0.size ();
107
98
std::size_t new_size = old_size * 2 ;
108
99
109
- bv_utilst::representationt rep =
110
- shl_overflow->lhs ().type ().id () == ID_signedbv
111
- ? bv_utilst::representationt::SIGNED
112
- : bv_utilst::representationt::UNSIGNED;
113
-
114
100
bvt bv_ext=bv_utils.extension (bv0, new_size, rep);
115
101
116
102
bvt result=bv_utils.shift (bv_ext, bv_utilst::shiftt::SHIFT_LEFT, bv1);
117
103
118
104
// 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
120
106
? const_literal (false )
121
107
: bv1.back (); // sign bit
122
108
@@ -161,7 +147,13 @@ literalt boolbvt::convert_overflow(const exprt &expr)
161
147
return
162
148
prop.land (!neg_shift, prop.lselect (undef, prop.lor (bv0), overflow));
163
149
}
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 (
165
157
const auto unary_minus_overflow =
166
158
expr_try_dynamic_cast<unary_minus_overflow_exprt>(expr))
167
159
{
0 commit comments