Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e755cc9

Browse files
committed
Kotlin: Add controlflow/dominance test (copied from Java)
1 parent aebd8ed commit e755cc9

14 files changed

Lines changed: 261 additions & 0 deletions
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
class Test {
2+
fun test(px: Int, pw: Int, pz: Int): Int {
3+
var x = px
4+
var w = pw
5+
var z = pz
6+
7+
var j: Int
8+
var y: Long = 50
9+
10+
// if-else, multiple statements in block
11+
if (x > 0) {
12+
y = 20
13+
z = 10
14+
} else {
15+
y = 30
16+
}
17+
18+
z = (x + y) as Int
19+
20+
// if-else with return in one branch
21+
if (x < 0)
22+
y = 40
23+
else
24+
return z
25+
26+
// this is not the start of a BB due to the return
27+
z = 10
28+
29+
// single-branch if-else
30+
if (x == 0) {
31+
y = 60
32+
z = 10
33+
}
34+
35+
z += x
36+
37+
// while loop
38+
while (x > 0) {
39+
y = 10
40+
x--
41+
}
42+
43+
z += y as Int
44+
45+
/*
46+
TODO
47+
// for loop
48+
for (j = 0; j < 10; j++) {
49+
y = 0;
50+
w = 10;
51+
}
52+
53+
z += w;
54+
55+
// nested control flow
56+
for (j = 0; j < 10; j++) {
57+
y = 30;
58+
if (z > 0)
59+
if (y > 0) {
60+
w = 0;
61+
break;
62+
} else {
63+
w = 20;
64+
}
65+
else {
66+
w = 10;
67+
continue;
68+
}
69+
x = 0;
70+
}
71+
*/
72+
73+
z += x + y + w
74+
75+
// nested control-flow
76+
77+
w = 40
78+
return w
79+
}
80+
81+
fun test2(a: Int): Int {
82+
/* Some more complex flow control */
83+
var b: Int
84+
var c: Int
85+
c = 0
86+
while(true) {
87+
b = 10
88+
if (a > 100) {
89+
c = 10
90+
b = c
91+
}
92+
if (a == 10)
93+
break
94+
if (a == 20)
95+
return c
96+
}
97+
return b
98+
}
99+
100+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import java.math.*
2+
3+
class MyExn: Throwable() {}
4+
5+
public class Test2 {
6+
@Throws(Throwable::class)
7+
fun f() {}
8+
9+
@Throws(Throwable::class)
10+
fun g(b: Boolean) {
11+
while (b) {
12+
if (b) {
13+
} else {
14+
try {
15+
f()
16+
} catch (e: MyExn) {}
17+
;
18+
}
19+
}
20+
}
21+
22+
fun t(x: Int) {
23+
if (x < 0) {
24+
return
25+
}
26+
var y = x
27+
while(y >= 0) {
28+
if (y > 10) {
29+
try {
30+
val n: BigInteger = BigInteger( "wrong" );
31+
} catch (e: NumberFormatException) { // unchecked exception
32+
}
33+
}
34+
y--
35+
}
36+
}
37+
}

java/ql/test/kotlin/library-tests/controlflow/dominance/dominanceBad.expected

Whitespace-only changes.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import java
2+
import semmle.code.java.controlflow.Dominance
3+
4+
from IfStmt i, BlockStmt b
5+
where
6+
b = i.getThen() and
7+
dominates(i.getThen(), b) and
8+
dominates(i.getElse(), b)
9+
select i, b

java/ql/test/kotlin/library-tests/controlflow/dominance/dominanceWrong.expected

Whitespace-only changes.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import java
2+
import semmle.code.java.controlflow.Dominance
3+
4+
/**
5+
* Represents a path from `entry` to `node` that doesn't go through `dom`. If
6+
* `entry` is the entry node for the CFG then this shows that `dom` does not
7+
* dominate `node`.
8+
*/
9+
predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, ControlFlowNode node) {
10+
node = entry
11+
or
12+
exists(ControlFlowNode mid |
13+
dominanceCounterExample(entry, dom, mid) and mid != dom and mid.getASuccessor() = node
14+
)
15+
}
16+
17+
from Callable c, ControlFlowNode dom, ControlFlowNode node
18+
where
19+
(strictlyDominates(dom, node) or bbStrictlyDominates(dom, node)) and
20+
dominanceCounterExample(c.getBody(), dom, node)
21+
select c, dom, node

java/ql/test/kotlin/library-tests/controlflow/dominance/dominatedByStart.expected

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// All nodes should be dominated by their associated start node
2+
import default
3+
import semmle.code.java.controlflow.Dominance
4+
5+
ControlFlowNode reachableIn(Method func) {
6+
result = func.getBody() or
7+
result = reachableIn(func).getASuccessor()
8+
}
9+
10+
from Method func, ControlFlowNode entry, ControlFlowNode node
11+
where
12+
func.getBody() = entry and
13+
reachableIn(func) = node and
14+
entry != node and
15+
not strictlyDominates(func.getBody(), node)
16+
select func, node
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
| Test.kt:1:1:100:1 | { ... } | Test.kt:1:1:100:1 | <obinit> |
2+
| Test.kt:2:43:79:2 | { ... } | Test.kt:3:9:3:18 | var ...; |
3+
| Test.kt:3:9:3:18 | var ...; | Test.kt:3:17:3:18 | px |
4+
| Test.kt:4:9:4:18 | var ...; | Test.kt:4:17:4:18 | pw |
5+
| Test.kt:5:9:5:18 | var ...; | Test.kt:5:17:5:18 | pz |
6+
| Test.kt:7:3:7:12 | var ...; | Test.kt:7:3:7:12 | j |
7+
| Test.kt:8:3:8:18 | var ...; | Test.kt:8:17:8:18 | 50 |
8+
| Test.kt:11:3:16:3 | <Expr>; | Test.kt:11:3:16:3 | when ... |
9+
| Test.kt:11:14:14:3 | { ... } | Test.kt:12:4:12:4 | <Expr>; |
10+
| Test.kt:12:4:12:4 | <Expr>; | Test.kt:12:8:12:9 | 20 |
11+
| Test.kt:13:4:13:4 | <Expr>; | Test.kt:13:8:13:9 | 10 |
12+
| Test.kt:14:10:16:3 | { ... } | Test.kt:15:4:15:4 | <Expr>; |
13+
| Test.kt:15:4:15:4 | <Expr>; | Test.kt:15:8:15:9 | 30 |
14+
| Test.kt:18:3:18:3 | <Expr>; | Test.kt:18:3:18:3 | ...=... |
15+
| Test.kt:21:3:24:11 | <Expr>; | Test.kt:21:3:24:11 | when ... |
16+
| Test.kt:22:4:22:4 | <Expr>; | Test.kt:22:8:22:9 | 40 |
17+
| Test.kt:27:3:27:3 | <Expr>; | Test.kt:27:7:27:8 | 10 |
18+
| Test.kt:30:3:33:3 | <Expr>; | Test.kt:30:3:33:3 | when ... |
19+
| Test.kt:30:15:33:3 | { ... } | Test.kt:31:4:31:4 | <Expr>; |
20+
| Test.kt:31:4:31:4 | <Expr>; | Test.kt:31:8:31:9 | 60 |
21+
| Test.kt:32:4:32:4 | <Expr>; | Test.kt:32:8:32:9 | 10 |
22+
| Test.kt:35:3:35:3 | <Expr>; | Test.kt:35:3:35:3 | z |
23+
| Test.kt:38:3:41:3 | while (...) | Test.kt:38:10:38:10 | x |
24+
| Test.kt:38:17:41:3 | { ... } | Test.kt:39:4:39:4 | <Expr>; |
25+
| Test.kt:39:4:39:4 | <Expr>; | Test.kt:39:8:39:9 | 10 |
26+
| Test.kt:43:3:43:3 | <Expr>; | Test.kt:43:3:43:3 | z |
27+
| Test.kt:73:3:73:3 | <Expr>; | Test.kt:73:3:73:3 | z |
28+
| Test.kt:77:3:77:3 | <Expr>; | Test.kt:77:7:77:8 | 40 |
29+
| Test.kt:81:25:98:2 | { ... } | Test.kt:83:3:83:12 | var ...; |
30+
| Test.kt:83:3:83:12 | var ...; | Test.kt:83:3:83:12 | b |
31+
| Test.kt:84:3:84:12 | var ...; | Test.kt:84:3:84:12 | c |
32+
| Test.kt:85:3:85:3 | <Expr>; | Test.kt:85:7:85:7 | 0 |
33+
| Test.kt:86:3:96:3 | while (...) | Test.kt:86:9:86:12 | true |
34+
| Test.kt:86:15:96:3 | { ... } | Test.kt:87:4:87:4 | <Expr>; |
35+
| Test.kt:87:4:87:4 | <Expr>; | Test.kt:87:8:87:9 | 10 |
36+
| Test.kt:88:4:91:4 | <Expr>; | Test.kt:88:4:91:4 | when ... |
37+
| Test.kt:88:17:91:4 | { ... } | Test.kt:89:5:89:5 | <Expr>; |
38+
| Test.kt:89:5:89:5 | <Expr>; | Test.kt:89:9:89:10 | 10 |
39+
| Test.kt:90:5:90:5 | <Expr>; | Test.kt:90:9:90:9 | c |
40+
| Test.kt:92:4:93:9 | <Expr>; | Test.kt:92:4:93:9 | when ... |
41+
| Test.kt:93:5:93:9 | break | Test.kt:97:10:97:10 | b |
42+
| Test.kt:94:4:95:12 | <Expr>; | Test.kt:94:4:95:12 | when ... |
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import default
2+
import semmle.code.java.controlflow.Dominance
3+
4+
from Method func, ControlFlowNode dominator, ControlFlowNode node
5+
where
6+
iDominates(dominator, node) and
7+
dominator.getEnclosingStmt().getEnclosingCallable() = func and
8+
func.getDeclaringType().hasName("Test")
9+
select dominator, node

0 commit comments

Comments
 (0)