12
12
#include < util/c_types.h>
13
13
#include < util/config.h>
14
14
#include < util/exception_utils.h>
15
+ #include < util/invariant.h>
15
16
#include < util/pointer_offset_size.h>
17
+ #include < util/prefix.h>
18
+ #include < util/ssa_expr.h>
19
+ #include < util/std_expr.h>
16
20
17
21
literalt bv_pointerst::convert_rest (const exprt &expr)
18
22
{
@@ -25,24 +29,15 @@ literalt bv_pointerst::convert_rest(const exprt &expr)
25
29
if (operands.size ()==1 &&
26
30
operands[0 ].type ().id ()==ID_pointer)
27
31
{
28
- const bvt &bv=convert_bv (operands[0 ]);
29
-
30
- if (!bv.empty ())
31
- {
32
- bvt invalid_bv;
33
- encode (pointer_logic.get_invalid_object (), invalid_bv);
34
-
35
- bvt equal_invalid_bv;
36
- equal_invalid_bv.resize (object_bits);
32
+ // we postpone
33
+ literalt l=prop.new_variable ();
37
34
38
- for (std::size_t i=0 ; i<object_bits; i++)
39
- {
40
- equal_invalid_bv[i]=prop.lequal (bv[offset_bits+i],
41
- invalid_bv[offset_bits+i]);
42
- }
35
+ postponed_list.push_back (postponedt ());
36
+ postponed_list.back ().op =convert_bv (operands[0 ]);
37
+ postponed_list.back ().bv .push_back (l);
38
+ postponed_list.back ().expr =expr;
43
39
44
- return prop.land (equal_invalid_bv);
45
- }
40
+ return l;
46
41
}
47
42
}
48
43
else if (expr.id ()==ID_dynamic_object)
@@ -820,6 +815,78 @@ void bv_pointerst::do_postponed(
820
815
prop.l_set_to (prop.limplies (l1, l2), true );
821
816
}
822
817
}
818
+ else if (postponed.expr .id ()==ID_invalid_pointer)
819
+ {
820
+ const pointer_logict::objectst &objects=pointer_logic.objects ;
821
+
822
+ bvt disj;
823
+ disj.reserve (objects.size ());
824
+
825
+ bvt saved_bv=postponed.op ;
826
+ saved_bv.erase (saved_bv.begin (), saved_bv.begin ()+offset_bits);
827
+
828
+ bvt invalid_bv, null_bv;
829
+ encode (pointer_logic.get_invalid_object (), invalid_bv);
830
+ invalid_bv.erase (invalid_bv.begin (), invalid_bv.begin ()+offset_bits);
831
+ encode (pointer_logic.get_null_object (), null_bv);
832
+ null_bv.erase (null_bv.begin (), null_bv.begin ()+offset_bits);
833
+
834
+ disj.push_back (bv_utils.equal (saved_bv, invalid_bv));
835
+ disj.push_back (bv_utils.equal (saved_bv, null_bv));
836
+
837
+ // compare object part to non-allocated dynamic objects
838
+ std::size_t number=0 ;
839
+
840
+ for (pointer_logict::objectst::const_iterator
841
+ it=objects.begin ();
842
+ it!=objects.end ();
843
+ it++, number++)
844
+ {
845
+ const exprt &expr=*it;
846
+
847
+ if (!pointer_logic.is_dynamic_object (expr) ||
848
+ !is_ssa_expr (expr))
849
+ continue ;
850
+
851
+ // only compare object part
852
+ bvt bv;
853
+ encode (number, bv);
854
+
855
+ bv.erase (bv.begin (), bv.begin ()+offset_bits);
856
+ assert (bv.size ()==saved_bv.size ());
857
+
858
+ literalt l1=bv_utils.equal (bv, saved_bv);
859
+
860
+ const ssa_exprt &ssa=to_ssa_expr (expr);
861
+
862
+ const exprt &guard=
863
+ static_cast <const exprt&>(
864
+ ssa.get_original_expr ().find (" #dynamic_guard" ));
865
+
866
+ if (guard.is_nil ())
867
+ continue ;
868
+
869
+ const bvt &guard_bv=convert_bv (guard);
870
+ assert (guard_bv.size ()==1 );
871
+ literalt l_guard=guard_bv[0 ];
872
+
873
+ disj.push_back (prop.land (!l_guard, l1));
874
+ }
875
+
876
+ // compare object part to max object number
877
+ bvt bv;
878
+ encode (number, bv);
879
+
880
+ bv.erase (bv.begin (), bv.begin ()+offset_bits);
881
+ assert (bv.size ()==saved_bv.size ());
882
+
883
+ disj.push_back (
884
+ bv_utils.rel (saved_bv, ID_ge, bv, bv_utilst::representationt::UNSIGNED));
885
+
886
+ assert (postponed.bv .size ()==1 );
887
+ literalt l=postponed.bv .front ();
888
+ prop.l_set_to (prop.lequal (prop.lor (disj), l), true );
889
+ }
823
890
else
824
891
UNREACHABLE;
825
892
}
0 commit comments