@@ -12,7 +12,11 @@ Author: Daniel Kroening, kroening@kroening.com
1212#include < util/c_types.h>
1313#include < util/config.h>
1414#include < util/exception_utils.h>
15+ #include < util/invariant.h>
1516#include < util/pointer_offset_size.h>
17+ #include < util/prefix.h>
18+ #include < util/ssa_expr.h>
19+ #include < util/std_expr.h>
1620
1721literalt bv_pointerst::convert_rest (const exprt &expr)
1822{
@@ -25,24 +29,15 @@ literalt bv_pointerst::convert_rest(const exprt &expr)
2529 if (operands.size ()==1 &&
2630 operands[0 ].type ().id ()==ID_pointer)
2731 {
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 ();
3734
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;
4339
44- return prop.land (equal_invalid_bv);
45- }
40+ return l;
4641 }
4742 }
4843 else if (expr.id ()==ID_dynamic_object)
@@ -820,6 +815,78 @@ void bv_pointerst::do_postponed(
820815 prop.l_set_to (prop.limplies (l1, l2), true );
821816 }
822817 }
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+ }
823890 else
824891 UNREACHABLE;
825892}
0 commit comments