Skip to content

CONTRACTS: look for dirty symbols in OTHER instructions. #7085

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
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
63 changes: 51 additions & 12 deletions src/goto-instrument/contracts/cfg_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,51 @@ Date: June 2022
#include <set>
#include <vector>

/// Work around the fact that dirtyt does not look into
/// OTHER instructions
class dirty_altt : public dirtyt
{
public:
dirty_altt() : dirtyt()
{
}

explicit dirty_altt(const goto_functiont &goto_function)
: dirtyt(goto_function)
{
collect_other(goto_function);
}

explicit dirty_altt(const goto_functionst &goto_functions)
: dirtyt(goto_functions)
{
for(const auto &gf_entry : goto_functions.function_map)
collect_other(gf_entry.second);
}

protected:
void collect_other(const goto_functiont &goto_function)
{
for(const auto &i : goto_function.body.instructions)
{
if(i.is_other())
{
auto &statement = i.get_other().get_statement();
if(
statement == ID_array_set || statement == ID_array_copy ||
statement == ID_array_replace || statement == ID_array_equal ||
statement == ID_havoc_object)
{
for(const auto &op : i.get_other().operands())
{
find_dirty(op);
}
}
}
}
}
Comment on lines +57 to +76
Copy link
Collaborator

Choose a reason for hiding this comment

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

LGTM, but why not incorporate this change into dirtyt class itself?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Modifying dirtyt could have wide-ranging repercussions since many other analyses depend on it.

};

/// Stores information about a goto function computed from its CFG.
///
/// The methods of this class provide information about identifiers
Expand Down Expand Up @@ -110,7 +155,7 @@ class function_cfg_infot : public cfg_infot
{
public:
explicit function_cfg_infot(const goto_functiont &_goto_function)
: dirty_analysis(_goto_function), locals(_goto_function)
: is_dirty(_goto_function), locals(_goto_function)
{
parameters.insert(
_goto_function.parameter_identifiers.begin(),
Expand All @@ -128,15 +173,11 @@ class function_cfg_infot : public cfg_infot
/// or is a local that is dirty.
bool is_not_local_or_dirty_local(const irep_idt &ident) const override
{
if(is_local(ident))
return dirty_analysis.get_dirty_ids().find(ident) !=
dirty_analysis.get_dirty_ids().end();
else
return true;
return is_local(ident) ? is_dirty(ident) : true;
}

private:
const dirtyt dirty_analysis;
const dirty_altt is_dirty;
const localst locals;
std::unordered_set<irep_idt> parameters;
};
Expand All @@ -146,7 +187,7 @@ class loop_cfg_infot : public cfg_infot
{
public:
loop_cfg_infot(goto_functiont &_goto_function, const loopt &loop)
: dirty_analysis(_goto_function)
: is_dirty(_goto_function)
{
for(const auto &t : loop)
{
Expand All @@ -166,8 +207,7 @@ class loop_cfg_infot : public cfg_infot
bool is_not_local_or_dirty_local(const irep_idt &ident) const override
{
if(is_local(ident))
return dirty_analysis.get_dirty_ids().find(ident) !=
dirty_analysis.get_dirty_ids().end();
return is_dirty(ident);
else
return true;
}
Expand All @@ -190,8 +230,7 @@ class loop_cfg_infot : public cfg_infot
}

private:
const dirtyt dirty_analysis;
const dirty_altt is_dirty;
std::unordered_set<irep_idt> locals;
};

#endif