Skip to content

Commit 5879cf2

Browse files
author
Daniel Kroening
authored
Merge pull request #327 from tautschnig/fix-325
Data-flow analysis must always enter new function
2 parents b250ddc + bda847f commit 5879cf2

17 files changed

+175
-73
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
int d=0;
2+
3+
void f1()
4+
{
5+
d=1;
6+
}
7+
8+
int main()
9+
{
10+
int x=2;
11+
int y=3;
12+
13+
f1();
14+
15+
if(x && y && d)
16+
return 0;
17+
}
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
"--show-dependence-graph"
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
Data dependencies: .*33.*
7+
--
8+
^warning: ignoring

src/analyses/ai.cpp

+6-5
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,7 @@ Function: ai_baset::entry_state
120120

121121
void ai_baset::entry_state(const goto_programt &goto_program)
122122
{
123-
// The first instruction of 'goto_program' is the entry point,
124-
// and we make that 'top'.
123+
// The first instruction of 'goto_program' is the entry point
125124
get_state(goto_program.instructions.begin()).make_entry();
126125
}
127126

@@ -226,9 +225,11 @@ bool ai_baset::fixedpoint(
226225
{
227226
working_sett working_set;
228227

229-
// We will put all locations at least once into the working set.
230-
forall_goto_program_instructions(i_it, goto_program)
231-
put_in_working_set(working_set, i_it);
228+
// Put the first location in the working set
229+
if(!goto_program.empty())
230+
put_in_working_set(
231+
working_set,
232+
goto_program.instructions.begin());
232233

233234
bool new_data=false;
234235

src/analyses/custom_bitvector_analysis.cpp

+10-5
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ void custom_bitvector_domaint::transform(
326326
ai_baset &ai,
327327
const namespacet &ns)
328328
{
329+
if(has_values.is_false()) return;
330+
329331
// upcast of ai
330332
custom_bitvector_analysist &cba=
331333
static_cast<custom_bitvector_analysist &>(ai);
@@ -565,8 +567,11 @@ void custom_bitvector_domaint::output(
565567
const ai_baset &ai,
566568
const namespacet &ns) const
567569
{
568-
if(is_bottom)
569-
out << "BOTTOM\n";
570+
if(has_values.is_known())
571+
{
572+
out << has_values.to_string() << '\n';
573+
return;
574+
}
570575

571576
const custom_bitvector_analysist &cba=
572577
static_cast<const custom_bitvector_analysist &>(ai);
@@ -625,10 +630,10 @@ bool custom_bitvector_domaint::merge(
625630
locationt from,
626631
locationt to)
627632
{
628-
if(b.is_bottom)
633+
if(b.has_values.is_false())
629634
return false; // no change
630635

631-
if(is_bottom)
636+
if(has_values.is_false())
632637
{
633638
*this=b;
634639
return true; // change
@@ -858,7 +863,7 @@ void custom_bitvector_analysist::check(
858863
if(!custom_bitvector_domaint::has_get_must_or_may(i_it->guard))
859864
continue;
860865

861-
if(operator[](i_it).is_bottom) continue;
866+
if(operator[](i_it).has_values.is_false()) continue;
862867

863868
exprt tmp=eval(i_it->guard, i_it);
864869
result=simplify_expr(tmp, ns);

src/analyses/custom_bitvector_analysis.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Author: Daniel Kroening, [email protected]
1010
#define CPROVER_ANALYSES_CUSTOM_BITVECTOR_ANALYSIS_H
1111

1212
#include <util/numbering.h>
13+
#include <util/threeval.h>
1314

1415
#include "ai.h"
1516
#include "local_may_alias.h"
@@ -42,20 +43,19 @@ class custom_bitvector_domaint:public ai_domain_baset
4243
{
4344
may_bits.clear();
4445
must_bits.clear();
45-
is_bottom=true;
46+
has_values=tvt(false);
4647
}
4748

4849
void make_top() final override
4950
{
50-
// We don't have a proper top, and refuse to do this.
51-
assert(false);
51+
may_bits.clear();
52+
must_bits.clear();
53+
has_values=tvt(true);
5254
}
5355

5456
void make_entry() final override
5557
{
56-
may_bits.clear();
57-
must_bits.clear();
58-
is_bottom=false;
58+
make_top();
5959
}
6060

6161
bool merge(
@@ -90,9 +90,9 @@ class custom_bitvector_domaint:public ai_domain_baset
9090
vectorst get_rhs(const exprt &) const;
9191
vectorst get_rhs(const irep_idt &) const;
9292

93-
bool is_bottom;
93+
tvt has_values;
9494

95-
custom_bitvector_domaint():is_bottom(true)
95+
custom_bitvector_domaint():has_values(true)
9696
{
9797
}
9898

src/analyses/dependence_graph.cpp

+5-4
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ bool dep_graph_domaint::merge(
3232
goto_programt::const_targett from,
3333
goto_programt::const_targett to)
3434
{
35-
bool change=false;
35+
bool changed=has_values.is_false();
36+
has_values=tvt::unknown();
3637

3738
depst::iterator it=control_deps.begin();
3839
for(depst::const_iterator ito=src.control_deps.begin();
@@ -44,7 +45,7 @@ bool dep_graph_domaint::merge(
4445
if(it==control_deps.end() || *ito<*it)
4546
{
4647
control_deps.insert(it, *ito);
47-
change=true;
48+
changed=true;
4849
}
4950
else if(it!=control_deps.end())
5051
++it;
@@ -60,13 +61,13 @@ bool dep_graph_domaint::merge(
6061
if(it==data_deps.end() || *ito<*it)
6162
{
6263
data_deps.insert(it, *ito);
63-
change=true;
64+
changed=true;
6465
}
6566
else if(it!=data_deps.end())
6667
++it;
6768
}
6869

69-
return change;
70+
return changed;
7071
}
7172

7273
/*******************************************************************\

src/analyses/dependence_graph.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Date: August 2013
1313
#define CPROVER_ANALYSES_DEPENDENCE_GRAPH_H
1414

1515
#include <util/graph.h>
16+
#include <util/threeval.h>
1617

1718
#include "ai.h"
1819
#include "cfg_dominators.h"
@@ -70,6 +71,7 @@ class dep_graph_domaint:public ai_domain_baset
7071
typedef graph<dep_nodet>::node_indext node_indext;
7172

7273
dep_graph_domaint():
74+
has_values(false),
7375
node_id(std::numeric_limits<node_indext>::max())
7476
{
7577
}
@@ -89,20 +91,22 @@ class dep_graph_domaint:public ai_domain_baset
8991
std::ostream &out,
9092
const ai_baset &ai,
9193
const namespacet &ns) const final override;
92-
94+
9395
void make_top() final override
9496
{
97+
has_values=tvt(true);
9598
node_id=std::numeric_limits<node_indext>::max();
9699
}
97100

98101
void make_bottom() final override
99102
{
103+
has_values=tvt(false);
100104
node_id=std::numeric_limits<node_indext>::max();
101105
}
102106

103107
void make_entry() final override
104108
{
105-
node_id=std::numeric_limits<node_indext>::max();
109+
make_top();
106110
}
107111

108112
void set_node_id(node_indext id)
@@ -117,6 +121,7 @@ class dep_graph_domaint:public ai_domain_baset
117121
}
118122

119123
protected:
124+
tvt has_values;
120125
node_indext node_id;
121126

122127
typedef std::set<goto_programt::const_targett> depst;

src/analyses/escape_analysis.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ void escape_domaint::transform(
266266
ai_baset &ai,
267267
const namespacet &ns)
268268
{
269+
if(has_values.is_false()) return;
270+
269271
// upcast of ai
270272
//escape_analysist &ea=
271273
// static_cast<escape_analysist &>(ai);
@@ -364,9 +366,9 @@ void escape_domaint::output(
364366
const ai_baset &ai,
365367
const namespacet &ns) const
366368
{
367-
if(is_bottom)
369+
if(has_values.is_known())
368370
{
369-
out << "BOTTOM\n";
371+
out << has_values.to_string() << '\n';
370372
return;
371373
}
372374

@@ -422,10 +424,10 @@ bool escape_domaint::merge(
422424
locationt from,
423425
locationt to)
424426
{
425-
if(b.is_bottom)
427+
if(b.has_values.is_false())
426428
return false; // no change
427429

428-
if(is_bottom)
430+
if(has_values.is_false())
429431
{
430432
*this=b;
431433
return true; // change

src/analyses/escape_analysis.h

+11-9
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111
#define CPROVER_ANALYSES_ESCAPE_ANALYSIS_H
1212

1313
#include <util/numbering.h>
14+
#include <util/threeval.h>
1415
#include <util/union_find.h>
1516

1617
#include "ai.h"
@@ -28,7 +29,7 @@ class escape_analysist;
2829
class escape_domaint:public ai_domain_baset
2930
{
3031
public:
31-
escape_domaint():is_bottom(true)
32+
escape_domaint():has_values(false)
3233
{
3334
}
3435

@@ -51,19 +52,20 @@ class escape_domaint:public ai_domain_baset
5152
void make_bottom() override final
5253
{
5354
cleanup_map.clear();
54-
is_bottom=true;
55+
aliases.clear();
56+
has_values=tvt(false);
5557
}
5658

5759
void make_top() override final
5860
{
59-
// We don't have a proper top.
60-
assert(false);
61+
cleanup_map.clear();
62+
aliases.clear();
63+
has_values=tvt(true);
6164
}
62-
65+
6366
void make_entry() override final
6467
{
65-
cleanup_map.clear();
66-
is_bottom=false;
68+
make_top();
6769
}
6870

6971
typedef union_find<irep_idt> aliasest;
@@ -80,9 +82,9 @@ class escape_domaint:public ai_domain_baset
8082
typedef std::map<irep_idt, cleanupt > cleanup_mapt;
8183
cleanup_mapt cleanup_map;
8284

83-
bool is_bottom;
84-
8585
protected:
86+
tvt has_values;
87+
8688
void assign_lhs_cleanup(const exprt &, const std::set<irep_idt> &);
8789
void get_rhs_cleanup(const exprt &, std::set<irep_idt> &);
8890
void assign_lhs_aliases(const exprt &, const std::set<irep_idt> &);

src/analyses/global_may_alias.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ void global_may_alias_domaint::transform(
130130
ai_baset &ai,
131131
const namespacet &ns)
132132
{
133+
if(has_values.is_false()) return;
134+
133135
const goto_programt::instructiont &instruction=*from;
134136

135137
switch(instruction.type)
@@ -179,6 +181,12 @@ void global_may_alias_domaint::output(
179181
const ai_baset &ai,
180182
const namespacet &ns) const
181183
{
184+
if(has_values.is_known())
185+
{
186+
out << has_values.to_string() << '\n';
187+
return;
188+
}
189+
182190
for(aliasest::const_iterator a_it1=aliases.begin();
183191
a_it1!=aliases.end();
184192
a_it1++)
@@ -218,7 +226,8 @@ bool global_may_alias_domaint::merge(
218226
locationt from,
219227
locationt to)
220228
{
221-
bool changed=false;
229+
bool changed=has_values.is_false();
230+
has_values=tvt::unknown();
222231

223232
// do union
224233
for(aliasest::const_iterator it=b.aliases.begin();

src/analyses/global_may_alias.h

+11-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, [email protected]
1111
#define CPROVER_ANALYSES_GLOBAL_MAY_ALIAS_H
1212

1313
#include <util/numbering.h>
14+
#include <util/threeval.h>
1415
#include <util/union_find.h>
1516

1617
#include "ai.h"
@@ -28,6 +29,10 @@ class global_may_alias_analysist;
2829
class global_may_alias_domaint:public ai_domain_baset
2930
{
3031
public:
32+
global_may_alias_domaint():has_values(false)
33+
{
34+
}
35+
3136
void transform(
3237
locationt from,
3338
locationt to,
@@ -47,23 +52,26 @@ class global_may_alias_domaint:public ai_domain_baset
4752
void make_bottom() final override
4853
{
4954
aliases.clear();
55+
has_values=tvt(false);
5056
}
5157

5258
void make_top() final override
5359
{
54-
// We don't have a proper top.
55-
assert(false);
60+
aliases.clear();
61+
has_values=tvt(true);
5662
}
5763

5864
void make_entry() final override
5965
{
60-
aliases.clear();
66+
make_top();
6167
}
6268

6369
typedef union_find<irep_idt> aliasest;
6470
aliasest aliases;
6571

6672
protected:
73+
tvt has_values;
74+
6775
void assign_lhs_aliases(const exprt &, const std::set<irep_idt> &);
6876
void get_rhs_aliases(const exprt &, std::set<irep_idt> &);
6977
void get_rhs_aliases_address_of(const exprt &, std::set<irep_idt> &);

0 commit comments

Comments
 (0)