@@ -65,7 +65,51 @@ void bv_endianness_mapt::build_big_endian(const typet &src)
65
65
endianness_mapt
66
66
bv_pointerst::endianness_map (const typet &type, bool little_endian) const
67
67
{
68
- return bv_endianness_mapt{type, little_endian, ns, bv_width};
68
+ return bv_endianness_mapt{type, little_endian, ns, bv_pointers_width};
69
+ }
70
+
71
+ std::size_t bv_pointerst::bv_pointers_widtht::
72
+ operator ()(const typet &type) const
73
+ {
74
+ if (type.id () != ID_pointer)
75
+ return boolbv_widtht::operator ()(type);
76
+
77
+ // check or update the cache, just like boolbv_widtht does
78
+ std::pair<cachet::iterator, bool > cache_result =
79
+ cache.insert (std::pair<typet, entryt>(type, entryt ()));
80
+
81
+ if (cache_result.second )
82
+ {
83
+ std::size_t &total_width = cache_result.first ->second .total_width ;
84
+
85
+ total_width = get_address_width (to_pointer_type (type));
86
+ DATA_INVARIANT (total_width > 0 , " pointer width shall be greater than zero" );
87
+ }
88
+
89
+ return cache_result.first ->second .total_width ;
90
+ }
91
+
92
+ std::size_t bv_pointerst::bv_pointers_widtht::get_object_width (
93
+ const pointer_typet &type) const
94
+ {
95
+ // not actually type-dependent for now
96
+ (void )type;
97
+ return config.bv_encoding .object_bits ;
98
+ }
99
+
100
+ std::size_t bv_pointerst::bv_pointers_widtht::get_offset_width (
101
+ const pointer_typet &type) const
102
+ {
103
+ const std::size_t pointer_width = type.get_width ();
104
+ const std::size_t object_width = get_object_width (type);
105
+ PRECONDITION (pointer_width >= object_width);
106
+ return pointer_width - object_width;
107
+ }
108
+
109
+ std::size_t bv_pointerst::bv_pointers_widtht::get_address_width (
110
+ const pointer_typet &type) const
111
+ {
112
+ return type.get_width ();
69
113
}
70
114
71
115
literalt bv_pointerst::convert_rest (const exprt &expr)
@@ -83,8 +127,15 @@ literalt bv_pointerst::convert_rest(const exprt &expr)
83
127
84
128
if (!bv.empty ())
85
129
{
130
+ const pointer_typet &type = to_pointer_type (operands[0 ].type ());
131
+
86
132
bvt invalid_bv;
87
- encode (pointer_logic.get_invalid_object (), invalid_bv);
133
+ encode (pointer_logic.get_invalid_object (), type, invalid_bv);
134
+
135
+ const std::size_t object_bits =
136
+ bv_pointers_width.get_object_width (type);
137
+ const std::size_t offset_bits =
138
+ bv_pointers_width.get_offset_width (type);
88
139
89
140
bvt equal_invalid_bv;
90
141
equal_invalid_bv.resize (object_bits);
@@ -139,12 +190,9 @@ bv_pointerst::bv_pointerst(
139
190
message_handlert &message_handler,
140
191
bool get_array_constraints)
141
192
: boolbvt(_ns, _prop, message_handler, get_array_constraints),
142
- pointer_logic(_ns)
193
+ pointer_logic(_ns),
194
+ bv_pointers_width(_ns)
143
195
{
144
- object_bits=config.bv_encoding .object_bits ;
145
- std::size_t pointer_width = boolbv_width (pointer_type (empty_typet ()));
146
- offset_bits=pointer_width-object_bits;
147
- bits=pointer_width;
148
196
}
149
197
150
198
bool bv_pointerst::convert_address_of_rec (
@@ -163,7 +211,8 @@ bool bv_pointerst::convert_address_of_rec(
163
211
}
164
212
else if (expr.id () == ID_null_object)
165
213
{
166
- encode (pointer_logic.get_null_object (), bv);
214
+ pointer_typet pt = pointer_type (expr.type ());
215
+ encode (pointer_logic.get_null_object (), pt, bv);
167
216
return false ;
168
217
}
169
218
else if (expr.id ()==ID_index)
@@ -173,6 +222,9 @@ bool bv_pointerst::convert_address_of_rec(
173
222
const exprt &index=index_expr.index ();
174
223
const typet &array_type = array.type ();
175
224
225
+ pointer_typet type = pointer_type (expr.type ());
226
+ const std::size_t bits = boolbv_width (type);
227
+
176
228
// recursive call
177
229
if (array_type.id ()==ID_pointer)
178
230
{
@@ -194,7 +246,7 @@ bool bv_pointerst::convert_address_of_rec(
194
246
auto size = pointer_offset_size (array_type.subtype (), ns);
195
247
CHECK_RETURN (size.has_value () && *size >= 0 );
196
248
197
- offset_arithmetic (bv, *size, index);
249
+ offset_arithmetic (type, bv, *size, index);
198
250
CHECK_RETURN (bv.size ()==bits);
199
251
return false ;
200
252
}
@@ -207,9 +259,11 @@ bool bv_pointerst::convert_address_of_rec(
207
259
if (convert_address_of_rec (byte_extract_expr.op (), bv))
208
260
return true ;
209
261
262
+ pointer_typet type = pointer_type (expr.type ());
263
+ const std::size_t bits = boolbv_width (type);
210
264
CHECK_RETURN (bv.size ()==bits);
211
265
212
- offset_arithmetic (bv, 1 , byte_extract_expr.offset ());
266
+ offset_arithmetic (type, bv, 1 , byte_extract_expr.offset ());
213
267
CHECK_RETURN (bv.size ()==bits);
214
268
return false ;
215
269
}
@@ -230,7 +284,8 @@ bool bv_pointerst::convert_address_of_rec(
230
284
CHECK_RETURN (offset.has_value ());
231
285
232
286
// add offset
233
- offset_arithmetic (bv, *offset);
287
+ pointer_typet type = pointer_type (expr.type ());
288
+ offset_arithmetic (type, bv, *offset);
234
289
}
235
290
else
236
291
{
@@ -273,15 +328,13 @@ bool bv_pointerst::convert_address_of_rec(
273
328
274
329
bvt bv_pointerst::convert_pointer_type (const exprt &expr)
275
330
{
276
- PRECONDITION (expr.type (). id () == ID_pointer );
331
+ const pointer_typet &type = to_pointer_type (expr.type ());
277
332
278
- // make sure the config hasn't been changed
279
- PRECONDITION (bits==boolbv_width (expr.type ()));
333
+ const std::size_t bits = boolbv_width (expr.type ());
280
334
281
335
if (expr.id ()==ID_symbol)
282
336
{
283
337
const irep_idt &identifier=to_symbol_expr (expr).get_identifier ();
284
- const typet &type=expr.type ();
285
338
286
339
return map.get_literals (identifier, type, bits);
287
340
}
@@ -352,7 +405,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
352
405
bv.resize (bits);
353
406
354
407
if (value==ID_NULL)
355
- encode (pointer_logic.get_null_object (), bv);
408
+ encode (pointer_logic.get_null_object (), type, bv);
356
409
else
357
410
{
358
411
mp_integer i = bvrep2integer (value, bits, false );
@@ -433,7 +486,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
433
486
sum=bv_utils.add (sum, op);
434
487
}
435
488
436
- offset_arithmetic (bv, size, sum);
489
+ offset_arithmetic (type, bv, size, sum);
437
490
438
491
return bv;
439
492
}
@@ -476,7 +529,7 @@ bvt bv_pointerst::convert_pointer_type(const exprt &expr)
476
529
element_size = *element_size_opt;
477
530
}
478
531
479
- offset_arithmetic (bv, element_size, neg_op1);
532
+ offset_arithmetic (type, bv, element_size, neg_op1);
480
533
481
534
return bv;
482
535
}
@@ -556,18 +609,20 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr)
556
609
expr.id () == ID_pointer_offset &&
557
610
to_unary_expr (expr).op ().type ().id () == ID_pointer)
558
611
{
559
- bvt op0 = convert_bv (to_unary_expr (expr).op ());
612
+ const exprt &op0 = to_unary_expr (expr).op ();
613
+ bvt op0_bv = convert_bv (op0);
560
614
561
615
std::size_t width=boolbv_width (expr.type ());
562
616
563
617
if (width==0 )
564
618
return conversion_failed (expr);
565
619
566
620
// we need to strip off the object part
567
- op0.resize (offset_bits);
621
+ op0_bv.resize (
622
+ bv_pointers_width.get_offset_width (to_pointer_type (op0.type ())));
568
623
569
624
// we do a sign extension to permit negative offsets
570
- return bv_utils.sign_extension (op0 , width);
625
+ return bv_utils.sign_extension (op0_bv , width);
571
626
}
572
627
else if (
573
628
expr.id () == ID_object_size &&
@@ -594,7 +649,8 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr)
594
649
expr.id () == ID_pointer_object &&
595
650
to_unary_expr (expr).op ().type ().id () == ID_pointer)
596
651
{
597
- bvt op0 = convert_bv (to_unary_expr (expr).op ());
652
+ const exprt &op0 = to_unary_expr (expr).op ();
653
+ bvt op0_bv = convert_bv (op0);
598
654
599
655
std::size_t width=boolbv_width (expr.type ());
600
656
@@ -603,9 +659,12 @@ bvt bv_pointerst::convert_bitvector(const exprt &expr)
603
659
604
660
// erase offset bits
605
661
606
- op0.erase (op0.begin ()+0 , op0.begin ()+offset_bits);
662
+ op0_bv.erase (
663
+ op0_bv.begin () + 0 ,
664
+ op0_bv.begin () +
665
+ bv_pointers_width.get_offset_width (to_pointer_type (op0.type ())));
607
666
608
- return bv_utils.zero_extension (op0 , width);
667
+ return bv_utils.zero_extension (op0_bv , width);
609
668
}
610
669
else if (
611
670
expr.id () == ID_typecast &&
@@ -638,6 +697,9 @@ exprt bv_pointerst::bv_get_rec(
638
697
639
698
std::string value_addr, value_offset, value;
640
699
700
+ const std::size_t bits = boolbv_width (to_pointer_type (type));
701
+ const std::size_t offset_bits =
702
+ bv_pointers_width.get_offset_width (to_pointer_type (type));
641
703
for (std::size_t i=0 ; i<bits; i++)
642
704
{
643
705
char ch=0 ;
@@ -681,9 +743,13 @@ exprt bv_pointerst::bv_get_rec(
681
743
return std::move (result);
682
744
}
683
745
684
- void bv_pointerst::encode (std::size_t addr, bvt &bv)
746
+ void bv_pointerst::encode (std::size_t addr, const pointer_typet &type, bvt &bv)
747
+ const
685
748
{
686
- bv.resize (bits);
749
+ const std::size_t offset_bits = bv_pointers_width.get_offset_width (type);
750
+ const std::size_t object_bits = bv_pointers_width.get_object_width (type);
751
+
752
+ bv.resize (boolbv_width (type));
687
753
688
754
// set offset to zero
689
755
for (std::size_t i=0 ; i<offset_bits; i++)
@@ -694,8 +760,13 @@ void bv_pointerst::encode(std::size_t addr, bvt &bv)
694
760
bv[offset_bits+i]=const_literal ((addr&(std::size_t (1 )<<i))!=0 );
695
761
}
696
762
697
- void bv_pointerst::offset_arithmetic (bvt &bv, const mp_integer &x)
763
+ void bv_pointerst::offset_arithmetic (
764
+ const pointer_typet &type,
765
+ bvt &bv,
766
+ const mp_integer &x)
698
767
{
768
+ const std::size_t offset_bits = bv_pointers_width.get_offset_width (type);
769
+
699
770
bvt bv1=bv;
700
771
bv1.resize (offset_bits); // strip down
701
772
@@ -709,6 +780,7 @@ void bv_pointerst::offset_arithmetic(bvt &bv, const mp_integer &x)
709
780
}
710
781
711
782
void bv_pointerst::offset_arithmetic (
783
+ const pointer_typet &type,
712
784
bvt &bv,
713
785
const mp_integer &factor,
714
786
const exprt &index)
@@ -719,12 +791,14 @@ void bv_pointerst::offset_arithmetic(
719
791
index.type ().id ()==ID_signedbv?bv_utilst::representationt::SIGNED:
720
792
bv_utilst::representationt::UNSIGNED;
721
793
794
+ const std::size_t offset_bits = bv_pointers_width.get_offset_width (type);
722
795
bv_index=bv_utils.extension (bv_index, offset_bits, rep);
723
796
724
- offset_arithmetic (bv, factor, bv_index);
797
+ offset_arithmetic (type, bv, factor, bv_index);
725
798
}
726
799
727
800
void bv_pointerst::offset_arithmetic (
801
+ const pointer_typet &type,
728
802
bvt &bv,
729
803
const mp_integer &factor,
730
804
const bvt &index)
@@ -744,6 +818,7 @@ void bv_pointerst::offset_arithmetic(
744
818
bvt bv_tmp=bv_utils.add (bv, bv_index);
745
819
746
820
// copy lower parts of result
821
+ const std::size_t offset_bits = bv_pointers_width.get_offset_width (type);
747
822
for (std::size_t i=0 ; i<offset_bits; i++)
748
823
bv[i]=bv_tmp[i];
749
824
}
@@ -752,6 +827,8 @@ void bv_pointerst::add_addr(const exprt &expr, bvt &bv)
752
827
{
753
828
std::size_t a=pointer_logic.add_object (expr);
754
829
830
+ const pointer_typet type = pointer_type (expr.type ());
831
+ const std::size_t object_bits = bv_pointers_width.get_object_width (type);
755
832
const std::size_t max_objects=std::size_t (1 )<<object_bits;
756
833
757
834
if (a==max_objects)
@@ -761,14 +838,17 @@ void bv_pointerst::add_addr(const exprt &expr, bvt &bv)
761
838
" ); " +
762
839
" use the `--object-bits n` option to increase the maximum number" );
763
840
764
- encode (a, bv);
841
+ encode (a, type, bv);
765
842
}
766
843
767
844
void bv_pointerst::do_postponed (
768
845
const postponedt &postponed)
769
846
{
770
847
if (postponed.expr .id () == ID_is_dynamic_object)
771
848
{
849
+ const std::size_t offset_bits = bv_pointers_width.get_offset_width (
850
+ to_pointer_type (to_unary_expr (postponed.expr ).op ().type ()));
851
+
772
852
const auto &objects = pointer_logic.objects ;
773
853
std::size_t number=0 ;
774
854
@@ -780,7 +860,8 @@ void bv_pointerst::do_postponed(
780
860
781
861
// only compare object part
782
862
bvt bv;
783
- encode (number, bv);
863
+ pointer_typet pt = pointer_type (expr.type ());
864
+ encode (number, pt, bv);
784
865
785
866
bv.erase (bv.begin (), bv.begin ()+offset_bits);
786
867
@@ -801,6 +882,9 @@ void bv_pointerst::do_postponed(
801
882
}
802
883
else if (postponed.expr .id ()==ID_object_size)
803
884
{
885
+ const std::size_t offset_bits = bv_pointers_width.get_offset_width (
886
+ to_pointer_type (to_unary_expr (postponed.expr ).op ().type ()));
887
+
804
888
const auto &objects = pointer_logic.objects ;
805
889
std::size_t number=0 ;
806
890
@@ -821,7 +905,8 @@ void bv_pointerst::do_postponed(
821
905
822
906
// only compare object part
823
907
bvt bv;
824
- encode (number, bv);
908
+ pointer_typet pt = pointer_type (expr.type ());
909
+ encode (number, pt, bv);
825
910
826
911
bv.erase (bv.begin (), bv.begin ()+offset_bits);
827
912
0 commit comments