@@ -13,6 +13,7 @@ Author: Daniel Kroening, kroening@kroening.com
1313#include < util/arith_tools.h>
1414#include < util/invariant.h>
1515#include < util/prefix.h>
16+ #include < util/ssa_expr.h>
1617#include < util/std_expr.h>
1718#include < util/pointer_offset_size.h>
1819#include < util/threeval.h>
@@ -29,31 +30,15 @@ literalt bv_pointerst::convert_rest(const exprt &expr)
2930 if (operands.size ()==1 &&
3031 operands[0 ].type ().id ()==ID_pointer)
3132 {
32- const bvt &bv=convert_bv (operands[0 ]);
33+ // we postpone
34+ literalt l=prop.new_variable ();
3335
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- }
36+ postponed_list.push_back (postponedt ());
37+ postponed_list.back ().op =convert_bv (operands[0 ]);
38+ postponed_list.back ().bv .push_back (l);
39+ postponed_list.back ().expr =expr;
40+
41+ return l;
5742 }
5843 }
5944 else if (expr.id ()==ID_dynamic_object)
@@ -788,6 +773,78 @@ void bv_pointerst::do_postponed(
788773 prop.l_set_to (prop.limplies (l1, l2), true );
789774 }
790775 }
776+ else if (postponed.expr .id ()==ID_invalid_pointer)
777+ {
778+ const pointer_logict::objectst &objects=pointer_logic.objects ;
779+
780+ bvt disj;
781+ disj.reserve (objects.size ());
782+
783+ bvt saved_bv=postponed.op ;
784+ saved_bv.erase (saved_bv.begin (), saved_bv.begin ()+offset_bits);
785+
786+ bvt invalid_bv, null_bv;
787+ encode (pointer_logic.get_invalid_object (), invalid_bv);
788+ invalid_bv.erase (invalid_bv.begin (), invalid_bv.begin ()+offset_bits);
789+ encode (pointer_logic.get_null_object (), null_bv);
790+ null_bv.erase (null_bv.begin (), null_bv.begin ()+offset_bits);
791+
792+ disj.push_back (bv_utils.equal (saved_bv, invalid_bv));
793+ disj.push_back (bv_utils.equal (saved_bv, null_bv));
794+
795+ // compare object part to non-allocated dynamic objects
796+ std::size_t number=0 ;
797+
798+ for (pointer_logict::objectst::const_iterator
799+ it=objects.begin ();
800+ it!=objects.end ();
801+ it++, number++)
802+ {
803+ const exprt &expr=*it;
804+
805+ if (!pointer_logic.is_dynamic_object (expr) ||
806+ !is_ssa_expr (expr))
807+ continue ;
808+
809+ // only compare object part
810+ bvt bv;
811+ encode (number, bv);
812+
813+ bv.erase (bv.begin (), bv.begin ()+offset_bits);
814+ assert (bv.size ()==saved_bv.size ());
815+
816+ literalt l1=bv_utils.equal (bv, saved_bv);
817+
818+ const ssa_exprt &ssa=to_ssa_expr (expr);
819+
820+ const exprt &guard=
821+ static_cast <const exprt&>(
822+ ssa.get_original_expr ().find (" #dynamic_guard" ));
823+
824+ if (guard.is_nil ())
825+ continue ;
826+
827+ const bvt &guard_bv=convert_bv (guard);
828+ assert (guard_bv.size ()==1 );
829+ literalt l_guard=guard_bv[0 ];
830+
831+ disj.push_back (prop.land (!l_guard, l1));
832+ }
833+
834+ // compare object part to max object number
835+ bvt bv;
836+ encode (number, bv);
837+
838+ bv.erase (bv.begin (), bv.begin ()+offset_bits);
839+ assert (bv.size ()==saved_bv.size ());
840+
841+ disj.push_back (
842+ bv_utils.rel (saved_bv, ID_ge, bv, bv_utilst::representationt::UNSIGNED));
843+
844+ assert (postponed.bv .size ()==1 );
845+ literalt l=postponed.bv .front ();
846+ prop.l_set_to (prop.lequal (prop.lor (disj), l), true );
847+ }
791848 else
792849 UNREACHABLE;
793850}
0 commit comments