Skip to content

Commit 30891ca

Browse files
authored
Merge pull request #14861 from yoff/python/demonstrate-def-use-explosion
Python: test demonstrating the need for phi nodes
2 parents ace633c + d288c4a commit 30891ca

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
def_count
2+
| 4 |
3+
def
4+
| def_use_flow.py:10:5:10:5 | Essa node definition |
5+
| def_use_flow.py:17:11:17:11 | Essa node definition |
6+
| def_use_flow.py:19:9:19:9 | Essa node definition |
7+
| def_use_flow.py:21:7:21:7 | Essa node definition |
8+
implicit_use_count
9+
| 0 |
10+
implicit_use
11+
source_use_count
12+
| 3 |
13+
source_use
14+
| def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
15+
| def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
16+
| def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
17+
def_use_edge_count
18+
| 12 |
19+
def_use_edge
20+
| def_use_flow.py:10:5:10:5 | SSA variable x | def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
21+
| def_use_flow.py:10:5:10:5 | SSA variable x | def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
22+
| def_use_flow.py:10:5:10:5 | SSA variable x | def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
23+
| def_use_flow.py:17:11:17:11 | SSA variable x | def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
24+
| def_use_flow.py:17:11:17:11 | SSA variable x | def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
25+
| def_use_flow.py:17:11:17:11 | SSA variable x | def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
26+
| def_use_flow.py:19:9:19:9 | SSA variable x | def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
27+
| def_use_flow.py:19:9:19:9 | SSA variable x | def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
28+
| def_use_flow.py:19:9:19:9 | SSA variable x | def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
29+
| def_use_flow.py:21:7:21:7 | SSA variable x | def_use_flow.py:28:15:28:15 | ControlFlowNode for x |
30+
| def_use_flow.py:21:7:21:7 | SSA variable x | def_use_flow.py:30:13:30:13 | ControlFlowNode for x |
31+
| def_use_flow.py:21:7:21:7 | SSA variable x | def_use_flow.py:32:11:32:11 | ControlFlowNode for x |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import python
2+
private import semmle.python.dataflow.new.internal.DataFlowPrivate
3+
4+
query int def_count() {
5+
exists(SsaSourceVariable x | x.getName() = "x" |
6+
result = count(EssaNodeDefinition def | def.getSourceVariable() = x)
7+
)
8+
}
9+
10+
query EssaNodeDefinition def() {
11+
exists(SsaSourceVariable x | x.getName() = "x" | result.getSourceVariable() = x)
12+
}
13+
14+
query int implicit_use_count() {
15+
exists(SsaSourceVariable x | x.getName() = "x" | result = count(x.getAnImplicitUse()))
16+
}
17+
18+
query ControlFlowNode implicit_use() {
19+
exists(SsaSourceVariable x | x.getName() = "x" | result = x.getAnImplicitUse())
20+
}
21+
22+
query int source_use_count() {
23+
exists(SsaSourceVariable x | x.getName() = "x" | result = count(x.getASourceUse()))
24+
}
25+
26+
query ControlFlowNode source_use() {
27+
exists(SsaSourceVariable x | x.getName() = "x" | result = x.getASourceUse())
28+
}
29+
30+
query int def_use_edge_count() {
31+
exists(SsaSourceVariable x | x.getName() = "x" |
32+
result =
33+
count(EssaVariable v, NameNode use |
34+
v.getSourceVariable() = x and
35+
use = x.getAUse() and
36+
LocalFlow::defToFirstUse(v, use)
37+
)
38+
)
39+
}
40+
41+
query predicate def_use_edge(EssaVariable v, NameNode use) {
42+
exists(SsaSourceVariable x | x.getName() = "x" |
43+
v.getSourceVariable() = x and
44+
use = x.getAUse() and
45+
LocalFlow::defToFirstUse(v, use)
46+
)
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# This test file is inspired by
2+
# `csharp/ql/test/library-tests/dataflow/local/UseUseExplosion.cs`
3+
# but with `n=3` kept small, since we do have the explosion.
4+
5+
cond = ...
6+
7+
# global variables are slightly special,
8+
# so we go into a function scope
9+
def scope():
10+
x = 0
11+
12+
if(cond > 3):
13+
if(cond > 2):
14+
if(cond > 1):
15+
pass
16+
else:
17+
x = 1
18+
else:
19+
x = 2
20+
else:
21+
x = 3
22+
23+
if(cond > 3):
24+
if(cond > 2):
25+
if(cond > 1):
26+
pass
27+
else:
28+
use(x)
29+
else:
30+
use(x)
31+
else:
32+
use(x)
33+
34+
def use(v):
35+
# this could just be `pass` but we do not want it optimized away.
36+
y = v+2

0 commit comments

Comments
 (0)