Skip to content

Commit f25413e

Browse files
committed
invalid_object(pointer) is true for all non-existent objects
Check whether the object part of a pointer is greater or equal the total number of objects, or equals a dynamic object that has not actually been allocated on a given trace.
1 parent a695814 commit f25413e

File tree

2 files changed

+86
-27
lines changed

2 files changed

+86
-27
lines changed

src/goto-symex/symex_builtin_functions.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -193,18 +193,20 @@ void goto_symext::symex_allocate(
193193

194194
exprt rhs;
195195

196+
symbol_exprt v=value_symbol.symbol_expr();
197+
v.add("#dynamic_guard", state.guard);
198+
196199
if(object_type.id()==ID_array)
197200
{
198201
index_exprt index_expr(value_symbol.type.subtype());
199-
index_expr.array()=value_symbol.symbol_expr();
202+
index_expr.array()=v;
200203
index_expr.index()=from_integer(0, index_type());
201204
rhs=address_of_exprt(
202205
index_expr, pointer_type(value_symbol.type.subtype()));
203206
}
204207
else
205208
{
206-
rhs=address_of_exprt(
207-
value_symbol.symbol_expr(), pointer_type(value_symbol.type));
209+
rhs = address_of_exprt(v, pointer_type(value_symbol.type));
208210
}
209211

210212
if(rhs.type()!=lhs.type())

src/solvers/flattening/bv_pointers.cpp

+81-24
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Author: Daniel Kroening, [email protected]
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

Comments
 (0)