Skip to content

Introduce value-set supported simplifier for goto-symex #8642

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 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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: 7 additions & 0 deletions regression/cbmc/pointer-offset-02/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <stdlib.h>

int main()
{
int *p = malloc(sizeof(int));
__CPROVER_assert(__CPROVER_POINTER_OFFSET(p) == 0, "");
}
9 changes: 9 additions & 0 deletions regression/cbmc/pointer-offset-02/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
CORE
main.c
--verbosity 8
^Generated \d+ VCC\(s\), 0 remaining after simplification$
^VERIFICATION SUCCESSFUL$
^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
55 changes: 55 additions & 0 deletions src/goto-symex/simplify_expr_with_value_set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,58 @@ simplify_exprt::resultt<> simplify_expr_with_value_sett::simplify_inequality(
else
return unchanged(expr);
}

simplify_exprt::resultt<>
simplify_expr_with_value_sett::simplify_pointer_offset(
Comment on lines +230 to +231
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd include a header comment here with your commit description

When all candidates in the value set have the same offset we can replace
a pointer_offset expression by the offset value found in the value set.

Since there is only one simplification applied. This is nitpick since one may infer from the code.

const pointer_offset_exprt &expr)
{
const exprt &ptr = expr.pointer();

if(ptr.type().id() != ID_pointer)
return unchanged(expr);

const ssa_exprt *ssa_symbol_expr = expr_try_dynamic_cast<ssa_exprt>(ptr);

if(!ssa_symbol_expr)
return simplify_exprt::simplify_pointer_offset(expr);

ssa_exprt l1_expr{*ssa_symbol_expr};
l1_expr.remove_level_2();
const std::vector<exprt> value_set_elements =
value_set.get_value_set(l1_expr, ns);

std::optional<exprt> offset;

for(const auto &value_set_element : value_set_elements)
{
if(
value_set_element.id() == ID_unknown ||
value_set_element.id() == ID_invalid ||
is_failed_symbol(
to_object_descriptor_expr(value_set_element).root_object()) ||
to_object_descriptor_expr(value_set_element).offset().id() == ID_unknown)
{
offset.reset();
break;
}

exprt this_offset = to_object_descriptor_expr(value_set_element).offset();
if(
this_offset.id() == ID_unknown ||
(offset.has_value() && this_offset != *offset))
{
offset.reset();
break;
}
else if(!offset.has_value())
{
offset = this_offset;
}
}

if(!offset.has_value())
return simplify_exprt::simplify_pointer_offset(expr);

return changed(
simplify_rec(typecast_exprt::conditional_cast(*offset, expr.type())));
}
2 changes: 2 additions & 0 deletions src/goto-symex/simplify_expr_with_value_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class simplify_expr_with_value_sett : public simplify_exprt

[[nodiscard]] resultt<>
simplify_inequality(const binary_relation_exprt &) override;
[[nodiscard]] resultt<>
simplify_pointer_offset(const pointer_offset_exprt &) override;

protected:
const value_sett &value_set;
Expand Down
3 changes: 2 additions & 1 deletion src/util/simplify_expr_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,8 @@ class simplify_exprt
[[nodiscard]] resultt<>
simplify_dereference_preorder(const dereference_exprt &);
[[nodiscard]] resultt<> simplify_address_of(const address_of_exprt &);
[[nodiscard]] resultt<> simplify_pointer_offset(const pointer_offset_exprt &);
[[nodiscard]] virtual resultt<>
simplify_pointer_offset(const pointer_offset_exprt &);
[[nodiscard]] resultt<> simplify_bswap(const bswap_exprt &);
[[nodiscard]] resultt<> simplify_isinf(const unary_exprt &);
[[nodiscard]] resultt<> simplify_isnan(const unary_exprt &);
Expand Down