Skip to content

Commit 8eb5e4a

Browse files
author
Remi Delmas
committed
Make dirtyt traverses operands of OTHER instructions
1 parent b69a945 commit 8eb5e4a

File tree

3 files changed

+57
-67
lines changed

3 files changed

+57
-67
lines changed

src/analyses/dirty.cpp

+46-11
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,49 @@ Date: March 2013
1919
void dirtyt::build(const goto_functiont &goto_function)
2020
{
2121
for(const auto &i : goto_function.body.instructions)
22-
i.apply([this](const exprt &e) { find_dirty(e); });
22+
{
23+
if(i.is_other())
24+
{
25+
search_other(i);
26+
}
27+
else
28+
{
29+
i.apply([this](const exprt &e) { find_dirty(e); });
30+
}
31+
}
32+
}
33+
34+
void dirtyt::search_other(const goto_programt::instructiont &instruction)
35+
{
36+
INVARIANT(instruction.is_other(), "instruction type must be OTHER");
37+
if(instruction.get_other().id() == ID_code)
38+
{
39+
const codet &code = instruction.get_other();
40+
const irep_idt &statement = code.get_statement();
41+
if(
42+
statement == ID_expression || statement == ID_array_set ||
43+
statement == ID_array_equal || statement == ID_array_copy ||
44+
statement == ID_array_replace || statement == ID_havoc_object ||
45+
statement == ID_input || statement == ID_output)
46+
{
47+
forall_operands(it, code)
48+
find_dirty(*it);
49+
}
50+
// other possible cases according to goto_programt::instructiont::output
51+
// and goto_symext::symex_other:
52+
// statement == ID_fence ||
53+
// statement == ID_user_specified_predicate ||
54+
// statement == ID_user_specified_parameter_predicates ||
55+
// statement == ID_user_specified_return_predicates ||
56+
// statement == ID_decl || statement == ID_nondet || statement == ID_asm)
57+
}
2358
}
2459

2560
void dirtyt::find_dirty(const exprt &expr)
2661
{
27-
if(expr.id()==ID_address_of)
62+
if(expr.id() == ID_address_of)
2863
{
29-
const address_of_exprt &address_of_expr=to_address_of_expr(expr);
64+
const address_of_exprt &address_of_expr = to_address_of_expr(expr);
3065
find_dirty_address_of(address_of_expr.object());
3166
return;
3267
}
@@ -37,27 +72,26 @@ void dirtyt::find_dirty(const exprt &expr)
3772

3873
void dirtyt::find_dirty_address_of(const exprt &expr)
3974
{
40-
if(expr.id()==ID_symbol)
75+
if(expr.id() == ID_symbol)
4176
{
42-
const irep_idt &identifier=
43-
to_symbol_expr(expr).get_identifier();
77+
const irep_idt &identifier = to_symbol_expr(expr).get_identifier();
4478

4579
dirty.insert(identifier);
4680
}
47-
else if(expr.id()==ID_member)
81+
else if(expr.id() == ID_member)
4882
{
4983
find_dirty_address_of(to_member_expr(expr).struct_op());
5084
}
51-
else if(expr.id()==ID_index)
85+
else if(expr.id() == ID_index)
5286
{
5387
find_dirty_address_of(to_index_expr(expr).array());
5488
find_dirty(to_index_expr(expr).index());
5589
}
56-
else if(expr.id()==ID_dereference)
90+
else if(expr.id() == ID_dereference)
5791
{
5892
find_dirty(to_dereference_expr(expr).pointer());
5993
}
60-
else if(expr.id()==ID_if)
94+
else if(expr.id() == ID_if)
6195
{
6296
find_dirty_address_of(to_if_expr(expr).true_case());
6397
find_dirty_address_of(to_if_expr(expr).false_case());
@@ -76,7 +110,8 @@ void dirtyt::output(std::ostream &out) const
76110
/// \param id: function id to analyse
77111
/// \param function: function to analyse
78112
void incremental_dirtyt::populate_dirty_for_function(
79-
const irep_idt &id, const goto_functionst::goto_functiont &function)
113+
const irep_idt &id,
114+
const goto_functionst::goto_functiont &function)
80115
{
81116
auto insert_result = dirty_processed_functions.insert(id);
82117
if(insert_result.second)

src/analyses/dirty.h

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ Date: March 2013
1414
#ifndef CPROVER_ANALYSES_DIRTY_H
1515
#define CPROVER_ANALYSES_DIRTY_H
1616

17-
#include <unordered_set>
18-
19-
#include <util/std_expr.h>
2017
#include <util/invariant.h>
18+
#include <util/std_expr.h>
19+
2120
#include <goto-programs/goto_functions.h>
2221

22+
#include <unordered_set>
23+
2324
/// Dirty variables are ones which have their address taken so we can't
2425
/// reliably work out where they may be assigned and are also considered shared
2526
/// state in the presence of multi-threading.
@@ -65,7 +66,7 @@ class dirtyt
6566
bool operator()(const irep_idt &id) const
6667
{
6768
die_if_uninitialized();
68-
return dirty.find(id)!=dirty.end();
69+
return dirty.find(id) != dirty.end();
6970
}
7071

7172
bool operator()(const symbol_exprt &expr) const
@@ -100,14 +101,12 @@ class dirtyt
100101

101102
// variables whose address is taken
102103
std::unordered_set<irep_idt> dirty;
103-
104+
void search_other(const goto_programt::instructiont &instruction);
104105
void find_dirty(const exprt &expr);
105106
void find_dirty_address_of(const exprt &expr);
106107
};
107108

108-
inline std::ostream &operator<<(
109-
std::ostream &out,
110-
const dirtyt &dirty)
109+
inline std::ostream &operator<<(std::ostream &out, const dirtyt &dirty)
111110
{
112111
dirty.output(out);
113112
return out;
@@ -119,7 +118,8 @@ class incremental_dirtyt
119118
{
120119
public:
121120
void populate_dirty_for_function(
122-
const irep_idt &id, const goto_functionst::goto_functiont &function);
121+
const irep_idt &id,
122+
const goto_functionst::goto_functiont &function);
123123

124124
bool operator()(const irep_idt &id) const
125125
{

src/goto-instrument/contracts/cfg_info.h

+2-47
Original file line numberDiff line numberDiff line change
@@ -31,51 +31,6 @@ 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-
7934
/// Stores information about a goto function computed from its CFG.
8035
///
8136
/// The methods of this class provide information about identifiers
@@ -177,7 +132,7 @@ class function_cfg_infot : public cfg_infot
177132
}
178133

179134
private:
180-
const dirty_altt is_dirty;
135+
const dirtyt is_dirty;
181136
const localst locals;
182137
std::unordered_set<irep_idt> parameters;
183138
};
@@ -230,7 +185,7 @@ class loop_cfg_infot : public cfg_infot
230185
}
231186

232187
private:
233-
const dirty_altt is_dirty;
188+
const dirtyt is_dirty;
234189
std::unordered_set<irep_idt> locals;
235190
};
236191
#endif

0 commit comments

Comments
 (0)