@@ -31,18 +31,6 @@ bvt boolbvt::convert_extractbits(const extractbits_exprt &expr)
31
31
auto upper_as_int = maybe_upper_as_int.value ();
32
32
auto lower_as_int = maybe_lower_as_int.value ();
33
33
34
- DATA_INVARIANT_WITH_DIAGNOSTICS (
35
- upper_as_int >= 0 && upper_as_int < src_bv.size (),
36
- " upper end of extracted bits must be within the bitvector" ,
37
- expr.find_source_location (),
38
- irep_pretty_diagnosticst{expr});
39
-
40
- DATA_INVARIANT_WITH_DIAGNOSTICS (
41
- lower_as_int >= 0 && lower_as_int < src_bv.size (),
42
- " lower end of extracted bits must be within the bitvector" ,
43
- expr.find_source_location (),
44
- irep_pretty_diagnosticst{expr});
45
-
46
34
DATA_INVARIANT (
47
35
lower_as_int <= upper_as_int,
48
36
" upper bound must be greater or equal to lower bound" );
@@ -56,9 +44,40 @@ bvt boolbvt::convert_extractbits(const extractbits_exprt &expr)
56
44
expr.find_source_location (),
57
45
irep_pretty_diagnosticst{expr});
58
46
59
- const std:: size_t offset = numeric_cast_v<std:: size_t >(lower_as_int) ;
47
+ bvt result_bv ;
60
48
61
- bvt result_bv (src_bv.begin () + offset, src_bv.begin () + offset + bv_width);
49
+ // add out-of-bounds bits (if any) at the lower end
50
+ if (lower_as_int < 0 )
51
+ {
52
+ if (upper_as_int < 0 )
53
+ {
54
+ lower_as_int -= upper_as_int + 1 ;
55
+ upper_as_int = 0 ;
56
+ }
57
+
58
+ const std::size_t lower_out_of_bounds =
59
+ numeric_cast_v<std::size_t >(-lower_as_int);
60
+ result_bv = prop.new_variables (lower_out_of_bounds);
61
+ lower_as_int = 0 ;
62
+ }
63
+
64
+ const std::size_t offset = numeric_cast_v<std::size_t >(lower_as_int);
65
+ const std::size_t upper_size_t = numeric_cast_v<std::size_t >(upper_as_int);
66
+
67
+ result_bv.reserve (bv_width);
68
+ result_bv.insert (
69
+ result_bv.end (),
70
+ src_bv.begin () + std::min (offset, src_bv.size ()),
71
+ src_bv.begin () + std::min (src_bv.size (), upper_size_t + 1 ));
72
+
73
+ // add out-of-bounds bits (if any) at the upper end
74
+ if (upper_size_t >= src_bv.size ())
75
+ {
76
+ bvt upper_oob_bits =
77
+ prop.new_variables (upper_size_t - std::max (offset, src_bv.size ()) + 1 );
78
+ result_bv.insert (
79
+ result_bv.end (), upper_oob_bits.begin (), upper_oob_bits.end ());
80
+ }
62
81
63
82
return result_bv;
64
83
}
0 commit comments