13
13
#include < util/arith_tools.h>
14
14
#include < util/invariant.h>
15
15
#include < util/prefix.h>
16
+ #include < util/ssa_expr.h>
16
17
#include < util/std_expr.h>
17
18
#include < util/pointer_offset_size.h>
18
19
#include < util/threeval.h>
@@ -29,39 +30,25 @@ literalt bv_pointerst::convert_rest(const exprt &expr)
29
30
if (operands.size ()==1 &&
30
31
operands[0 ].type ().id ()==ID_pointer)
31
32
{
32
- const bvt &bv=convert_bv (operands[0 ]);
33
+ // condition can only be evaluated once all (address-taken)
34
+ // objects are known, thus postpone
35
+ literalt l=prop.new_variable ();
33
36
34
- if (!bv.empty ())
35
- {
36
- bvt invalid_bv, null_bv;
37
- encode (pointer_logic.get_invalid_object (), invalid_bv);
38
- encode (pointer_logic.get_null_object (), null_bv);
39
-
40
- bvt equal_invalid_bv, equal_null_bv;
41
- equal_invalid_bv.resize (object_bits);
42
- equal_null_bv.resize (object_bits);
43
-
44
- for (std::size_t i=0 ; i<object_bits; i++)
45
- {
46
- equal_invalid_bv[i]=prop.lequal (bv[offset_bits+i],
47
- invalid_bv[offset_bits+i]);
48
- equal_null_bv[i] =prop.lequal (bv[offset_bits+i],
49
- null_bv[offset_bits+i]);
50
- }
51
-
52
- literalt equal_invalid=prop.land (equal_invalid_bv);
53
- literalt equal_null=prop.land (equal_null_bv);
54
-
55
- return prop.lor (equal_invalid, equal_null);
56
- }
37
+ postponed_list.push_back (postponedt ());
38
+ postponed_list.back ().op =convert_bv (operands[0 ]);
39
+ postponed_list.back ().bv .push_back (l);
40
+ postponed_list.back ().expr =expr;
41
+
42
+ return l;
57
43
}
58
44
}
59
45
else if (expr.id ()==ID_dynamic_object)
60
46
{
61
47
if (operands.size ()==1 &&
62
48
operands[0 ].type ().id ()==ID_pointer)
63
49
{
64
- // we postpone
50
+ // condition can only be evaluated once all (address-taken)
51
+ // objects are known, thus postpone
65
52
literalt l=prop.new_variable ();
66
53
67
54
postponed_list.push_back (postponedt ());
@@ -779,6 +766,82 @@ void bv_pointerst::do_postponed(
779
766
prop.l_set_to (prop.limplies (l1, l2), true );
780
767
}
781
768
}
769
+ else if (postponed.expr .id ()==ID_invalid_pointer)
770
+ {
771
+ const pointer_logict::objectst &objects=pointer_logic.objects ;
772
+
773
+ bvt disj;
774
+ disj.reserve (objects.size ());
775
+
776
+ bvt saved_bv=postponed.op ;
777
+ saved_bv.erase (saved_bv.begin (), saved_bv.begin ()+offset_bits);
778
+
779
+ bvt invalid_bv, null_bv;
780
+ encode (pointer_logic.get_invalid_object (), invalid_bv);
781
+ invalid_bv.erase (invalid_bv.begin (), invalid_bv.begin ()+offset_bits);
782
+ encode (pointer_logic.get_null_object (), null_bv);
783
+ null_bv.erase (null_bv.begin (), null_bv.begin ()+offset_bits);
784
+
785
+ disj.push_back (bv_utils.equal (saved_bv, invalid_bv));
786
+ disj.push_back (bv_utils.equal (saved_bv, null_bv));
787
+
788
+ // the pointer is invalid if its object part compares equal to
789
+ // any of the object parts of dynamic objects that have *not*
790
+ // been allocated (as their path condition, stored in
791
+ // ID_C_dynamic_guard, evaluates to false)
792
+ std::size_t number=0 ;
793
+
794
+ for (pointer_logict::objectst::const_iterator
795
+ it=objects.begin ();
796
+ it!=objects.end ();
797
+ ++it, ++number)
798
+ {
799
+ const exprt &expr=*it;
800
+
801
+ if (!pointer_logic.is_dynamic_object (expr) ||
802
+ !is_ssa_expr (expr))
803
+ continue ;
804
+
805
+ // only compare object part
806
+ bvt bv;
807
+ encode (number, bv);
808
+
809
+ bv.erase (bv.begin (), bv.begin ()+offset_bits);
810
+ POSTCONDITION (bv.size ()==saved_bv.size ());
811
+
812
+ literalt l1=bv_utils.equal (bv, saved_bv);
813
+
814
+ const ssa_exprt &ssa=to_ssa_expr (expr);
815
+
816
+ const exprt &guard=
817
+ static_cast <const exprt&>(
818
+ ssa.get_original_expr ().find (ID_C_dynamic_guard));
819
+
820
+ if (guard.is_nil ())
821
+ continue ;
822
+
823
+ const bvt &guard_bv=convert_bv (guard);
824
+ DATA_INVARIANT (guard_bv.size ()==1 , " guard expected to be Boolean" );
825
+ literalt l_guard=guard_bv[0 ];
826
+
827
+ disj.push_back (prop.land (!l_guard, l1));
828
+ }
829
+
830
+ // compare object part to max object number
831
+ bvt bv;
832
+ encode (number, bv);
833
+
834
+ bv.erase (bv.begin (), bv.begin ()+offset_bits);
835
+ POSTCONDITION (bv.size ()==saved_bv.size ());
836
+
837
+ disj.push_back (
838
+ bv_utils.rel (
839
+ saved_bv, ID_ge, bv, bv_utilst::representationt::UNSIGNED));
840
+
841
+ PRECONDITION (postponed.bv .size ()==1 );
842
+ literalt l=postponed.bv .front ();
843
+ prop.l_set_to (prop.lequal (prop.lor (disj), l), true );
844
+ }
782
845
else
783
846
UNREACHABLE;
784
847
}
0 commit comments