23
23
#include < util/prefix.h>
24
24
#include < util/range.h>
25
25
#include < util/simplify_expr.h>
26
+ #include < util/ssa_expr.h>
26
27
#include < util/std_code.h>
27
28
#include < util/symbol.h>
28
29
#include < util/xml.h>
29
30
30
31
#ifdef DEBUG
31
- #include < iostream>
32
- #include < util/format_expr.h>
33
- #include < util/format_type.h>
32
+ # include < iostream>
34
33
#endif
35
34
36
35
#include " add_failed_symbols.h"
@@ -184,7 +183,7 @@ void value_sett::output(std::ostream &out, const std::string &indent) const
184
183
stream << " <" << format (o) << " , " ;
185
184
186
185
if (o_it->second )
187
- stream << *o_it->second ;
186
+ stream << format ( *o_it->second ) ;
188
187
else
189
188
stream << ' *' ;
190
189
@@ -261,7 +260,7 @@ exprt value_sett::to_expr(const object_map_dt::value_type &it) const
261
260
od.object ()=object;
262
261
263
262
if (it.second )
264
- od.offset () = from_integer ( *it.second , c_index_type ()) ;
263
+ od.offset () = *it.second ;
265
264
266
265
od.type ()=od.object ().type ();
267
266
@@ -352,7 +351,7 @@ bool value_sett::eval_pointer_offset(
352
351
it=object_map.begin ();
353
352
it!=object_map.end ();
354
353
it++)
355
- if (!it->second )
354
+ if (!it->second || !it-> second -> is_constant () )
356
355
return false ;
357
356
else
358
357
{
@@ -362,7 +361,8 @@ bool value_sett::eval_pointer_offset(
362
361
if (!ptr_offset.has_value ())
363
362
return false ;
364
363
365
- *ptr_offset += *it->second ;
364
+ *ptr_offset +=
365
+ numeric_cast_v<mp_integer>(to_constant_expr (*it->second ));
366
366
367
367
if (mod && *ptr_offset != previous_offset)
368
368
return false ;
@@ -556,8 +556,11 @@ void value_sett::get_value_set_rec(
556
556
}
557
557
else if (expr.id ()==ID_symbol)
558
558
{
559
- auto entry_index = get_index_of_symbol (
560
- to_symbol_expr (expr).get_identifier (), expr.type (), suffix, ns);
559
+ const symbol_exprt expr_l1 = is_ssa_expr (expr)
560
+ ? remove_level_2 (to_ssa_expr (expr))
561
+ : to_symbol_expr (expr);
562
+ auto entry_index =
563
+ get_index_of_symbol (expr_l1.get_identifier (), expr.type (), suffix, ns);
561
564
562
565
if (entry_index.has_value ())
563
566
make_union (dest, find_entry (*entry_index)->object_map );
@@ -623,7 +626,7 @@ void value_sett::get_value_set_rec(
623
626
insert (
624
627
dest,
625
628
exprt (ID_null_object, to_pointer_type (expr.type ()).base_type ()),
626
- mp_integer{ 0 } );
629
+ from_integer ( 0 , c_index_type ()) );
627
630
}
628
631
else if (
629
632
expr.type ().id () == ID_unsignedbv || expr.type ().id () == ID_signedbv)
@@ -655,7 +658,10 @@ void value_sett::get_value_set_rec(
655
658
656
659
if (op.is_zero ())
657
660
{
658
- insert (dest, exprt (ID_null_object, empty_typet{}), mp_integer{0 });
661
+ insert (
662
+ dest,
663
+ exprt (ID_null_object, empty_typet{}),
664
+ from_integer (0 , c_index_type ()));
659
665
}
660
666
else
661
667
{
@@ -696,15 +702,14 @@ void value_sett::get_value_set_rec(
696
702
throw expr.id_string ()+" expected to have at least two operands" ;
697
703
698
704
object_mapt pointer_expr_set;
699
- std::optional<mp_integer> i ;
705
+ std::optional<exprt> additional_offset ;
700
706
701
707
// special case for plus/minus and exactly one pointer
702
708
std::optional<exprt> ptr_operand;
703
709
if (
704
710
expr.type ().id () == ID_pointer &&
705
711
(expr.id () == ID_plus || expr.id () == ID_minus))
706
712
{
707
- bool non_const_offset = false ;
708
713
for (const auto &op : expr.operands ())
709
714
{
710
715
if (op.type ().id () == ID_pointer)
@@ -717,24 +722,20 @@ void value_sett::get_value_set_rec(
717
722
718
723
ptr_operand = op;
719
724
}
720
- else if (!non_const_offset)
725
+ else
721
726
{
722
- auto offset = numeric_cast<mp_integer>(op);
723
- if (!offset.has_value ())
724
- {
725
- i.reset ();
726
- non_const_offset = true ;
727
- }
727
+ if (!additional_offset.has_value ())
728
+ additional_offset = op;
728
729
else
729
730
{
730
- if (!i. has_value ())
731
- i = mp_integer{ 0 };
732
- i = *i + *offset ;
731
+ additional_offset = plus_exprt{
732
+ *additional_offset,
733
+ typecast_exprt::conditional_cast (op, additional_offset-> type ())} ;
733
734
}
734
735
}
735
736
}
736
737
737
- if (ptr_operand.has_value () && i .has_value ())
738
+ if (ptr_operand.has_value () && additional_offset .has_value ())
738
739
{
739
740
typet pointer_base_type =
740
741
to_pointer_type (ptr_operand->type ()).base_type ();
@@ -745,18 +746,22 @@ void value_sett::get_value_set_rec(
745
746
746
747
if (!size.has_value () || (*size) == 0 )
747
748
{
748
- i .reset ();
749
+ additional_offset .reset ();
749
750
}
750
751
else
751
752
{
752
- *i *= *size;
753
+ additional_offset = mult_exprt{
754
+ *additional_offset, from_integer (*size, additional_offset->type ())};
753
755
754
756
if (expr.id ()==ID_minus)
755
757
{
756
758
DATA_INVARIANT (
757
759
to_minus_expr (expr).lhs () == *ptr_operand,
758
760
" unexpected subtraction of pointer from integer" );
759
- i->negate ();
761
+ DATA_INVARIANT (
762
+ additional_offset->type ().id () != ID_unsignedbv,
763
+ " offset type must support negation" );
764
+ additional_offset = unary_minus_exprt{*additional_offset};
760
765
}
761
766
}
762
767
}
@@ -790,8 +795,15 @@ void value_sett::get_value_set_rec(
790
795
offsett offset = it->second ;
791
796
792
797
// adjust by offset
793
- if (offset && i.has_value ())
794
- *offset += *i;
798
+ if (offset && additional_offset.has_value ())
799
+ {
800
+ offset = simplify_expr (
801
+ plus_exprt{
802
+ *offset,
803
+ typecast_exprt::conditional_cast (
804
+ *additional_offset, offset->type ())},
805
+ ns);
806
+ }
795
807
else
796
808
offset.reset ();
797
809
@@ -871,7 +883,7 @@ void value_sett::get_value_set_rec(
871
883
dynamic_object.set_instance (location_number);
872
884
dynamic_object.valid ()=true_exprt ();
873
885
874
- insert (dest, dynamic_object, mp_integer{ 0 } );
886
+ insert (dest, dynamic_object, from_integer ( 0 , c_index_type ()) );
875
887
}
876
888
else if (statement==ID_cpp_new ||
877
889
statement==ID_cpp_new_array)
@@ -884,7 +896,7 @@ void value_sett::get_value_set_rec(
884
896
dynamic_object.set_instance (location_number);
885
897
dynamic_object.valid ()=true_exprt ();
886
898
887
- insert (dest, dynamic_object, mp_integer{ 0 } );
899
+ insert (dest, dynamic_object, from_integer ( 0 , c_index_type ()) );
888
900
}
889
901
else
890
902
insert (dest, exprt (ID_unknown, original_type));
@@ -1331,12 +1343,17 @@ void value_sett::get_reference_set_rec(
1331
1343
expr.id ()==ID_string_constant ||
1332
1344
expr.id ()==ID_array)
1333
1345
{
1346
+ exprt l1_expr =
1347
+ is_ssa_expr (expr) ? remove_level_2 (to_ssa_expr (expr)) : expr;
1348
+
1334
1349
if (
1335
1350
expr.type ().id () == ID_array &&
1336
1351
to_array_type (expr.type ()).element_type ().id () == ID_array)
1337
- insert (dest, expr);
1352
+ {
1353
+ insert (dest, l1_expr);
1354
+ }
1338
1355
else
1339
- insert (dest, expr, mp_integer{ 0 } );
1356
+ insert (dest, l1_expr, from_integer ( 0 , c_index_type ()) );
1340
1357
1341
1358
return ;
1342
1359
}
@@ -1365,7 +1382,7 @@ void value_sett::get_reference_set_rec(
1365
1382
1366
1383
const index_exprt &index_expr=to_index_expr (expr);
1367
1384
const exprt &array=index_expr.array ();
1368
- const exprt &offset= index_expr.index ();
1385
+ const exprt &index = index_expr.index ();
1369
1386
1370
1387
DATA_INVARIANT (
1371
1388
array.type ().id () == ID_array, " index takes array-typed operand" );
@@ -1393,22 +1410,24 @@ void value_sett::get_reference_set_rec(
1393
1410
from_integer (0 , c_index_type ()));
1394
1411
1395
1412
offsett o = a_it->second ;
1396
- const auto i = numeric_cast<mp_integer>(offset);
1397
1413
1398
- if (offset.is_zero ())
1399
- {
1400
- }
1401
- else if (i.has_value () && o)
1414
+ if (!index.is_zero () && o.has_value ())
1402
1415
{
1403
1416
auto size = pointer_offset_size (array_type.element_type (), ns);
1404
1417
1405
1418
if (!size.has_value () || *size == 0 )
1406
1419
o.reset ();
1407
1420
else
1408
- *o = *i * (*size);
1421
+ {
1422
+ o = simplify_expr (
1423
+ plus_exprt{
1424
+ *o,
1425
+ typecast_exprt::conditional_cast (
1426
+ mult_exprt{index, from_integer (*size, index.type ())},
1427
+ o->type ())},
1428
+ ns);
1429
+ }
1409
1430
}
1410
- else
1411
- o.reset ();
1412
1431
1413
1432
insert (dest, deref_index_expr, o);
1414
1433
}
@@ -1658,7 +1677,9 @@ void value_sett::assign_rec(
1658
1677
1659
1678
if (lhs.id ()==ID_symbol)
1660
1679
{
1661
- const irep_idt &identifier=to_symbol_expr (lhs).get_identifier ();
1680
+ const symbol_exprt lhs_l1 =
1681
+ is_ssa_expr (lhs) ? remove_level_2 (to_ssa_expr (lhs)) : to_symbol_expr (lhs);
1682
+ const irep_idt &identifier = lhs_l1.get_identifier ();
1662
1683
1663
1684
update_entry (
1664
1685
entryt{identifier, suffix}, lhs.type (), values_rhs, add_to_sets);
@@ -1864,8 +1885,11 @@ void value_sett::apply_code_rec(
1864
1885
(lhs_type.id () == ID_array &&
1865
1886
to_array_type (lhs_type).element_type ().id () == ID_pointer))
1866
1887
{
1888
+ const symbol_exprt lhs_l1 = is_ssa_expr (lhs)
1889
+ ? remove_level_2 (to_ssa_expr (lhs))
1890
+ : to_symbol_expr (lhs);
1867
1891
// assign the address of the failed object
1868
- if (auto failed = get_failed_symbol (to_symbol_expr (lhs ), ns))
1892
+ if (auto failed = get_failed_symbol (to_symbol_expr (lhs_l1 ), ns))
1869
1893
{
1870
1894
address_of_exprt address_of_expr (*failed, to_pointer_type (lhs.type ()));
1871
1895
assign (lhs, address_of_expr, ns, false , false );
0 commit comments