Skip to content

Commit f4d92f2

Browse files
author
Remi Delmas
committed
CONTRACTS: look for dirty symbols in OTHER instructions.
Traverse `OTHER` instructions subexpressions when the `statement` is `ID_array_*` or `ID_havoc_object`.
1 parent 585039a commit f4d92f2

File tree

1 file changed

+51
-12
lines changed

1 file changed

+51
-12
lines changed

src/goto-instrument/contracts/cfg_info.h

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,51 @@ Date: June 2022
3131
#include <set>
3232
#include <vector>
3333

34+
/// Work around the fact that dirtyt does not look into
35+
/// OTHER instructions
36+
class dirty_altt : public dirtyt
37+
{
38+
public:
39+
dirty_altt() : dirtyt()
40+
{
41+
}
42+
43+
explicit dirty_altt(const goto_functiont &goto_function)
44+
: dirtyt(goto_function)
45+
{
46+
collect_other(goto_function);
47+
}
48+
49+
explicit dirty_altt(const goto_functionst &goto_functions)
50+
: dirtyt(goto_functions)
51+
{
52+
for(const auto &gf_entry : goto_functions.function_map)
53+
collect_other(gf_entry.second);
54+
}
55+
56+
protected:
57+
void collect_other(const goto_functiont &goto_function)
58+
{
59+
for(const auto &i : goto_function.body.instructions)
60+
{
61+
if(i.is_other())
62+
{
63+
auto &statement = i.get_other().get_statement();
64+
if(
65+
statement == ID_array_set || statement == ID_array_copy ||
66+
statement == ID_array_replace || statement == ID_array_equal ||
67+
statement == ID_havoc_object)
68+
{
69+
for(const auto &op : i.get_other().operands())
70+
{
71+
find_dirty(op);
72+
}
73+
}
74+
}
75+
}
76+
}
77+
};
78+
3479
/// Stores information about a goto function computed from its CFG.
3580
///
3681
/// The methods of this class provide information about identifiers
@@ -110,7 +155,7 @@ class function_cfg_infot : public cfg_infot
110155
{
111156
public:
112157
explicit function_cfg_infot(const goto_functiont &_goto_function)
113-
: dirty_analysis(_goto_function), locals(_goto_function)
158+
: is_dirty(_goto_function), locals(_goto_function)
114159
{
115160
parameters.insert(
116161
_goto_function.parameter_identifiers.begin(),
@@ -128,15 +173,11 @@ class function_cfg_infot : public cfg_infot
128173
/// or is a local that is dirty.
129174
bool is_not_local_or_dirty_local(const irep_idt &ident) const override
130175
{
131-
if(is_local(ident))
132-
return dirty_analysis.get_dirty_ids().find(ident) !=
133-
dirty_analysis.get_dirty_ids().end();
134-
else
135-
return true;
176+
return is_local(ident) ? is_dirty(ident) : true;
136177
}
137178

138179
private:
139-
const dirtyt dirty_analysis;
180+
const dirty_altt is_dirty;
140181
const localst locals;
141182
std::unordered_set<irep_idt> parameters;
142183
};
@@ -146,7 +187,7 @@ class loop_cfg_infot : public cfg_infot
146187
{
147188
public:
148189
loop_cfg_infot(goto_functiont &_goto_function, const loopt &loop)
149-
: dirty_analysis(_goto_function)
190+
: is_dirty(_goto_function)
150191
{
151192
for(const auto &t : loop)
152193
{
@@ -166,8 +207,7 @@ class loop_cfg_infot : public cfg_infot
166207
bool is_not_local_or_dirty_local(const irep_idt &ident) const override
167208
{
168209
if(is_local(ident))
169-
return dirty_analysis.get_dirty_ids().find(ident) !=
170-
dirty_analysis.get_dirty_ids().end();
210+
return is_dirty(ident);
171211
else
172212
return true;
173213
}
@@ -190,8 +230,7 @@ class loop_cfg_infot : public cfg_infot
190230
}
191231

192232
private:
193-
const dirtyt dirty_analysis;
233+
const dirty_altt is_dirty;
194234
std::unordered_set<irep_idt> locals;
195235
};
196-
197236
#endif

0 commit comments

Comments
 (0)