Skip to content

is_invalid_pointer is now defined as a bi-implication #6366

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions regression/cbmc-primitives/r_w_ok_bug/test.desc
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
CORE
main.c
--pointer-check --no-simplify --no-propagation
^\[main.pointer_dereference.\d+\] line 8 dereference failure: pointer outside object bounds in \*p1: FAILURE$
^\*\* 1 of \d+ failed
^VERIFICATION FAILED$
^EXIT=10$
^VERIFICATION SUCCESSFUL$
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this pattern being removed?

Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
FUTURE
CORE
main.c
--pointer-check --no-simplify --no-propagation
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
^warning: ignoring
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this pattern being removed?

--
Tests that an inconsistent assumption involving a pointer initialized to an
integer address not pointing to memory and __CPROVER_r_ok() can be detected via
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
FUTURE
CORE
main.c
--pointer-check
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
^warning: ignoring
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this pattern being removed?

--
Tests that an inconsistent assumption involving a pointer initialized to an
integer address not pointing to memory and __CPROVER_r_ok() can be detected via
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
FUTURE
CORE
main.c
--pointer-check --no-simplify --no-propagation
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
^warning: ignoring
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this pattern being removed?

--
Tests that an inconsistent assumption involving a nondet pointer and
__CPROVER_r_ok() can be detected via assert(0). We use --no-simplify and
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
FUTURE
CORE
main.c
--pointer-check
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
--
^warning: ignoring
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this pattern being removed?

--
Tests that an inconsistent assumption involving a nondet pointer and
__CPROVER_r_ok() can be detected via assert(0).
6 changes: 3 additions & 3 deletions regression/cbmc-primitives/same-object-01/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
void main()
{
char *p = malloc(1);
assert(__CPROVER_POINTER_OBJECT(p) == 2);
assert(__CPROVER_POINTER_OBJECT(p) == 1);

assert(
__CPROVER_same_object(p, (char *)((size_t)2 << (sizeof(char *) * 8 - 8))));
__CPROVER_same_object(p, (char *)((size_t)1 << (sizeof(char *) * 8 - 8))));
assert(
!__CPROVER_same_object(p, (char *)((size_t)3 << (sizeof(char *) * 8 - 8))));
!__CPROVER_same_object(p, (char *)((size_t)2 << (sizeof(char *) * 8 - 8))));
}
54 changes: 23 additions & 31 deletions src/solvers/flattening/bv_pointers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,37 +119,7 @@ literalt bv_pointerst::convert_rest(const exprt &expr)

const exprt::operandst &operands=expr.operands();

if(expr.id() == ID_is_invalid_pointer)
{
if(operands.size()==1 &&
operands[0].type().id()==ID_pointer)
{
const bvt &bv=convert_bv(operands[0]);

if(!bv.empty())
{
const pointer_typet &type = to_pointer_type(operands[0].type());
bvt object_bv = object_literals(bv, type);

bvt invalid_bv = object_literals(
encode(pointer_logic.get_invalid_object(), type), type);

const std::size_t object_bits =
bv_pointers_width.get_object_width(type);

bvt equal_invalid_bv;
equal_invalid_bv.reserve(object_bits);

for(std::size_t i=0; i<object_bits; i++)
{
equal_invalid_bv.push_back(prop.lequal(object_bv[i], invalid_bv[i]));
}

return prop.land(equal_invalid_bv);
}
}
}
else if(expr.id() == ID_is_dynamic_object)
if(expr.id() == ID_is_dynamic_object || expr.id() == ID_is_invalid_pointer)
{
if(operands.size()==1 &&
operands[0].type().id()==ID_pointer)
Expand Down Expand Up @@ -910,6 +880,28 @@ void bv_pointerst::do_postponed(
prop.l_set_to_true(prop.limplies(l1, l2));
}
}
else if(postponed.expr.id() == ID_is_invalid_pointer)
{
const auto &type =
to_pointer_type(to_unary_expr(postponed.expr).op().type());
const auto &objects = pointer_logic.objects;

// only compare object part
bvt bv = object_literals(encode(objects.size(), type), type);

bvt saved_bv = object_literals(postponed.op, type);

POSTCONDITION(bv.size() == saved_bv.size());
PRECONDITION(postponed.bv.size() == 1);

// the pointer is invalid iff the object number is greater or
// equal objects.size()
literalt l1 = bv_utils.lt_or_le(
true, bv, saved_bv, bv_utilst::representationt::UNSIGNED);
literalt l2 = postponed.bv.front();

prop.l_set_to_true(prop.lequal(l1, l2));
}
else if(postponed.expr.id()==ID_object_size)
{
const auto &type =
Expand Down
3 changes: 0 additions & 3 deletions src/solvers/flattening/pointer_logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,6 @@ pointer_logict::pointer_logict(const namespacet &_ns):ns(_ns)
// add NULL
null_object=objects.number(exprt(ID_NULL));
CHECK_RETURN(null_object == 0);

// add INVALID
invalid_object=objects.number(exprt("INVALID"));
}

pointer_logict::~pointer_logict()
Expand Down
6 changes: 0 additions & 6 deletions src/solvers/flattening/pointer_logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,6 @@ class pointer_logict
return null_object;
}

/// \return number of INVALID object
std::size_t get_invalid_object() const
{
return invalid_object;
}

bool is_dynamic_object(const exprt &expr) const;

void get_dynamic_objects(std::vector<std::size_t> &objects) const;
Expand Down
33 changes: 28 additions & 5 deletions src/solvers/smt2/smt2_conv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ void smt2_convt::define_object_size(

decision_proceduret::resultt smt2_convt::dec_solve()
{
post_process();
write_footer();
out.flush();
return decision_proceduret::resultt::D_ERROR;
Expand Down Expand Up @@ -1615,14 +1616,14 @@ void smt2_convt::convert_expr(const exprt &expr)
}
else if(expr.id() == ID_is_invalid_pointer)
{
// we don't know the number of objects until conversion
// is finished
const auto &op = to_unary_expr(expr).op();
std::size_t pointer_width = boolbv_width(op.type());
out << "(= ((_ extract "
<< pointer_width-1 << " "
<< pointer_width-config.bv_encoding.object_bits << ") ";
out << "(bvuge ((_ extract " << pointer_width - 1 << " "
<< pointer_width - config.bv_encoding.object_bits << ") ";
convert_expr(op);
out << ") (_ bv" << pointer_logic.get_invalid_object()
<< " " << config.bv_encoding.object_bits << "))";
out << ") number-of-objects)";
}
else if(expr.id()==ID_string_constant)
{
Expand Down Expand Up @@ -2133,6 +2134,17 @@ void smt2_convt::convert_expr(const exprt &expr)
expr.id_string());
}

void smt2_convt::post_process()
{
// we now know how many objects there are
if(number_of_objects_declared)
{
out << "; fix number of objects\n";
out << "(assert (= number-of-objects (_ bv" << pointer_logic.objects.size()
<< ' ' << config.bv_encoding.object_bits << ")))\n";
}
}

void smt2_convt::convert_typecast(const typecast_exprt &expr)
{
const exprt &src = expr.op();
Expand Down Expand Up @@ -4723,6 +4735,17 @@ void smt2_convt::find_symbols(const exprt &expr)
defined_expressions[expr]=id;
}
}
else if(expr.id() == ID_is_invalid_pointer)
{
if(!number_of_objects_declared)
{
out << "; the following is for is_invalid_pointer\n";
out << "(declare-fun number-of-objects () ";
out << "(_ BitVec " << config.bv_encoding.object_bits << ')';
out << ")\n";
number_of_objects_declared = true;
}
}
else if(expr.id() == ID_object_size)
{
const exprt &op = to_unary_expr(expr).op();
Expand Down
4 changes: 4 additions & 0 deletions src/solvers/smt2/smt2_conv.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ class smt2_convt : public stack_decision_proceduret
std::vector<exprt> assumptions;
boolbv_widtht boolbv_width;

// post-processing for number-of-objects
bool number_of_objects_declared = false;
void post_process();

std::size_t number_of_solver_calls = 0;

resultt dec_solve() override;
Expand Down
2 changes: 2 additions & 0 deletions src/solvers/smt2/smt2_dec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ std::string smt2_dect::decision_procedure_text() const

decision_proceduret::resultt smt2_dect::dec_solve()
{
post_process();

++number_of_solver_calls;

temporary_filet temp_file_problem("smt2_dec_problem_", ""),
Expand Down