Skip to content

Refactoring of symex_assign_symbol #4642

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

Merged
merged 13 commits into from
May 13, 2019
Merged
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
12 changes: 9 additions & 3 deletions src/goto-symex/field_sensitivity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,15 @@ void field_sensitivityt::field_assignments_rec(
exprt ssa_rhs = state.rename(lhs, ns).get();
simplify(ssa_rhs, ns);

ssa_exprt ssa_lhs = to_ssa_expr(lhs_fs);
state.assignment(
ssa_lhs, ssa_rhs, ns, true, true, allow_pointer_unsoundness);
const ssa_exprt ssa_lhs = state
.assignment(
to_ssa_expr(lhs_fs),
ssa_rhs,
ns,
true,
true,
allow_pointer_unsoundness)
.get();

// do the assignment
target.assignment(
Expand Down
36 changes: 20 additions & 16 deletions src/goto-symex/goto_symex_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ goto_symex_statet::goto_symex_statet(
source(_source),
guard_manager(manager),
symex_target(nullptr),
record_events(true),
record_events({true}),
fresh_l2_name_provider(fresh_l2_name_provider)
{
threads.emplace_back(guard_manager);
Expand All @@ -47,7 +47,8 @@ goto_symex_statet::goto_symex_statet(

goto_symex_statet::~goto_symex_statet()=default;

/// write to a variable
/// Check that \p expr is correctly renamed to level 2 and return true in case
/// an error is detected.
static bool check_renaming(const exprt &expr);

static bool check_renaming(const typet &type)
Expand Down Expand Up @@ -151,9 +152,9 @@ goto_symex_statet::set_indices<L2>(ssa_exprt ssa_expr, const namespacet &ns)
return level2(level1(level0(std::move(ssa_expr), ns, source.thread_nr)));
}

void goto_symex_statet::assignment(
ssa_exprt &lhs, // L0/L1
const exprt &rhs, // L2
renamedt<ssa_exprt, L2> goto_symex_statet::assignment(
ssa_exprt lhs, // L0/L1
const exprt &rhs, // L2
const namespacet &ns,
bool rhs_is_simplified,
bool record_value,
Expand Down Expand Up @@ -182,7 +183,8 @@ void goto_symex_statet::assignment(

// do the l2 renaming
increase_generation(l1_identifier, lhs);
lhs = set_indices<L2>(std::move(lhs), ns).get();
renamedt<ssa_exprt, L2> l2_lhs = set_indices<L2>(std::move(lhs), ns);
lhs = l2_lhs.get();

// in case we happen to be multi-threaded, record the memory access
bool is_shared=l2_thread_write_encoding(lhs, ns);
Expand Down Expand Up @@ -233,6 +235,8 @@ void goto_symex_statet::assignment(
value_set.output(ns, std::cout);
std::cout << "**********************\n";
#endif

return l2_lhs;
}

template <levelt level>
Expand Down Expand Up @@ -442,21 +446,21 @@ bool goto_symex_statet::l2_thread_read_encoding(
else
tmp = if_exprt{cond.as_expr(), l2_true_case.get(), l2_false_case.get()};

const bool record_events_bak=record_events;
record_events=false;
assignment(ssa_l1, tmp, ns, true, true);
record_events=record_events_bak;
record_events.push(false);
ssa_exprt ssa_l2 = assignment(std::move(ssa_l1), tmp, ns, true, true).get();
record_events.pop();

symex_target->assignment(
guard_as_expr,
ssa_l1,
ssa_l1,
ssa_l1.get_original_expr(),
ssa_l2,
ssa_l2,
ssa_l2.get_original_expr(),
tmp,
source,
symex_targett::assignment_typet::PHI);

expr = set_indices<L2>(std::move(ssa_l1), ns).get();
INVARIANT(!check_renaming(ssa_l2), "expr should be renamed to L2");
expr = std::move(ssa_l2);
Copy link
Collaborator

Choose a reason for hiding this comment

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

See my earlier comment: did you add an assertion to confirm this is doing what you expected across our regression tests?


a_s_read.second.push_back(guard);
if(!no_write.op().is_false())
Expand All @@ -466,7 +470,7 @@ bool goto_symex_statet::l2_thread_read_encoding(
}

// No event and no fresh index, but avoid constant propagation
if(!record_events)
if(!record_events.top())
{
expr = set_indices<L2>(std::move(ssa_l1), ns).get();
return true;
Expand All @@ -488,7 +492,7 @@ goto_symex_statet::write_is_shared_resultt goto_symex_statet::write_is_shared(
const ssa_exprt &expr,
const namespacet &ns) const
{
if(!record_events)
if(!record_events.top())
return write_is_shared_resultt::NOT_SHARED;

PRECONDITION(dirty != nullptr);
Expand Down
11 changes: 6 additions & 5 deletions src/goto-symex/goto_symex_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,14 @@ class goto_symex_statet final : public goto_statet
template <levelt level = L2>
void rename(typet &type, const irep_idt &l1_identifier, const namespacet &ns);

void assignment(
ssa_exprt &lhs, // L0/L1
const exprt &rhs, // L2
/// \return lhs renamed to level 2
renamedt<ssa_exprt, L2> assignment(
ssa_exprt lhs, // L0/L1
const exprt &rhs, // L2
const namespacet &ns,
bool rhs_is_simplified,
bool record_value,
bool allow_pointer_unsoundness=false);
bool allow_pointer_unsoundness = false);

field_sensitivityt field_sensitivity;

Expand Down Expand Up @@ -197,7 +198,7 @@ class goto_symex_statet final : public goto_statet
write_is_shared_resultt
write_is_shared(const ssa_exprt &expr, const namespacet &ns) const;

bool record_events;
std::stack<bool> record_events;

const incremental_dirtyt *dirty = nullptr;

Expand Down
7 changes: 3 additions & 4 deletions src/goto-symex/postcondition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ void postconditiont::strengthen(exprt &dest)
SSA_step.ssa_lhs.type().id()==ID_struct)
return;

equal_exprt equality(SSA_step.ssa_lhs, SSA_step.ssa_rhs);
get_original_name(equality);
exprt equality =
get_original_name(equal_exprt{SSA_step.ssa_lhs, SSA_step.ssa_rhs});

if(dest.is_true())
dest.swap(equality);
Expand Down Expand Up @@ -169,8 +169,7 @@ bool postconditiont::is_used(
it!=expr_set.end();
it++)
{
exprt tmp(*it);
get_original_name(tmp);
const exprt tmp = get_original_name(*it);
find_symbols(tmp, symbols);
}

Expand Down
3 changes: 1 addition & 2 deletions src/goto-symex/precondition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ void preconditiont::compute_rec(exprt &dest)
}
else if(dest==SSA_step.ssa_lhs.get_original_expr())
{
dest=SSA_step.ssa_rhs;
get_original_name(dest);
dest = get_original_name(SSA_step.ssa_rhs);
}
else
Forall_operands(it, dest)
Expand Down
23 changes: 14 additions & 9 deletions src/goto-symex/renaming_level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,37 +97,42 @@ void symex_level1t::restore_from(const current_namest &other)
}
}

void get_original_name(exprt &expr)
exprt get_original_name(exprt expr)
{
get_original_name(expr.type());
expr.type() = get_original_name(std::move(expr.type()));

if(expr.id() == ID_symbol && expr.get_bool(ID_C_SSA_symbol))
expr = to_ssa_expr(expr).get_original_expr();
return to_ssa_expr(expr).get_original_expr();
else
{
Forall_operands(it, expr)
get_original_name(*it);
*it = get_original_name(std::move(*it));
return expr;
}
}

void get_original_name(typet &type)
typet get_original_name(typet type)
{
// rename all the symbols with their last known value

if(type.id() == ID_array)
{
auto &array_type = to_array_type(type);
get_original_name(array_type.subtype());
get_original_name(array_type.size());
array_type.subtype() = get_original_name(std::move(array_type.subtype()));
array_type.size() = get_original_name(std::move(array_type.size()));
}
else if(type.id() == ID_struct || type.id() == ID_union)
{
struct_union_typet &s_u_type = to_struct_union_type(type);
struct_union_typet::componentst &components = s_u_type.components();

for(auto &component : components)
get_original_name(component.type());
component.type() = get_original_name(std::move(component.type()));
}
else if(type.id() == ID_pointer)
{
get_original_name(to_pointer_type(type).subtype());
type.subtype() =
get_original_name(std::move(to_pointer_type(type).subtype()));
}
return type;
}
4 changes: 2 additions & 2 deletions src/goto-symex/renaming_level.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ struct symex_level2t : public symex_renaming_levelt
};

/// Undo all levels of renaming
void get_original_name(exprt &expr);
exprt get_original_name(exprt expr);

/// Undo all levels of renaming
void get_original_name(typet &type);
typet get_original_name(typet type);

#endif // CPROVER_GOTO_SYMEX_RENAMING_LEVEL_H
Loading