Skip to content

Commit 50383ed

Browse files
committed
Require bottom/top to be implemented by ai domains
Domains without bottom would not be able to distinguish states being uninitialized from ones being empty/the smallest element. Thus even the very first merge into such a state possibly had no effect, which in turn would cause functions not being entered. Thus effects, such as assignments to global variables, would not be seen. Als use and enforce the implementation of make_entry. ai_baset::entry_point now uses make_entry; implementations may still use make_top to implement make_entry. Fixes #325
1 parent 841e860 commit 50383ed

17 files changed

+170
-70
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

+1-2
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

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)