Skip to content

Commit a7e9ac2

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 df5e3b8 commit a7e9ac2

File tree

2 files changed

+89
-20
lines changed

2 files changed

+89
-20
lines changed

src/goto-symex/symex_builtin_functions.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -184,18 +184,20 @@ void goto_symext::symex_allocate(
184184

185185
exprt rhs;
186186

187+
symbol_exprt v=value_symbol.symbol_expr();
188+
v.add("#dynamic_guard", state.guard);
189+
187190
if(object_type.id()==ID_array)
188191
{
189-
const auto &array_type = to_array_type(object_type);
192+
const auto &array_type = to_array_type(value_symbol.type);
190193
index_exprt index_expr(array_type.subtype());
191-
index_expr.array()=value_symbol.symbol_expr();
194+
index_expr.array() = v;
192195
index_expr.index()=from_integer(0, index_type());
193196
rhs = address_of_exprt(index_expr, pointer_type(array_type.subtype()));
194197
}
195198
else
196199
{
197-
rhs=address_of_exprt(
198-
value_symbol.symbol_expr(), pointer_type(value_symbol.type));
200+
rhs = address_of_exprt(v, pointer_type(value_symbol.type));
199201
}
200202

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

src/solvers/flattening/bv_pointers.cpp

+83-16
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ Author: Daniel Kroening, [email protected]
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

1721
literalt 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

Comments
 (0)