Skip to content

Commit 1485d70

Browse files
authored
Merge pull request #19885 from aschackmull/java/annotated-exit-cfg
Java: Add AnnotatedExitNodes to the CFG.
2 parents 2f29459 + 448cc82 commit 1485d70

File tree

39 files changed

+478
-170
lines changed

39 files changed

+478
-170
lines changed

java/ql/lib/semmle/code/java/ControlFlowGraph.qll

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ module;
8282
*/
8383

8484
import java
85+
private import codeql.util.Boolean
8586
private import Completion
8687
private import controlflow.internal.Preconditions
8788
private import controlflow.internal.SwitchCases
@@ -102,6 +103,7 @@ module ControlFlow {
102103
private newtype TNode =
103104
TExprNode(Expr e) { hasControlFlow(e) } or
104105
TStmtNode(Stmt s) or
106+
TAnnotatedExitNode(Callable c, Boolean normal) { exists(c.getBody()) } or
105107
TExitNode(Callable c) { exists(c.getBody()) } or
106108
TAssertThrowNode(AssertStmt s)
107109

@@ -191,6 +193,38 @@ module ControlFlow {
191193
override Location getLocation() { result = s.getLocation() }
192194
}
193195

196+
/** A control flow node indicating the normal or exceptional termination of a callable. */
197+
class AnnotatedExitNode extends Node, TAnnotatedExitNode {
198+
Callable c;
199+
boolean normal;
200+
201+
AnnotatedExitNode() { this = TAnnotatedExitNode(c, normal) }
202+
203+
override Callable getEnclosingCallable() { result = c }
204+
205+
override ExprParent getAstNode() { result = c }
206+
207+
/** Gets a textual representation of this element. */
208+
override string toString() {
209+
normal = true and result = "Normal Exit"
210+
or
211+
normal = false and result = "Exceptional Exit"
212+
}
213+
214+
/** Gets the source location for this element. */
215+
override Location getLocation() { result = c.getLocation() }
216+
}
217+
218+
/** A control flow node indicating normal termination of a callable. */
219+
class NormalExitNode extends AnnotatedExitNode {
220+
NormalExitNode() { this = TAnnotatedExitNode(_, true) }
221+
}
222+
223+
/** A control flow node indicating exceptional termination of a callable. */
224+
class ExceptionalExitNode extends AnnotatedExitNode {
225+
ExceptionalExitNode() { this = TAnnotatedExitNode(_, false) }
226+
}
227+
194228
/** A control flow node indicating the termination of a callable. */
195229
class ExitNode extends Node, TExitNode {
196230
Callable c;
@@ -1266,11 +1300,17 @@ private module ControlFlowGraphImpl {
12661300
*/
12671301
cached
12681302
Node succ(Node n, Completion completion) {
1269-
// After executing the callable body, the final node is the exit node.
1303+
// After executing the callable body, the final nodes are first the
1304+
// annotated exit node and then the final exit node.
12701305
exists(Callable c | last(c.getBody(), n, completion) |
1271-
result.(ExitNode).getEnclosingCallable() = c
1306+
if completion instanceof ThrowCompletion
1307+
then result.(ExceptionalExitNode).getEnclosingCallable() = c
1308+
else result.(NormalExitNode).getEnclosingCallable() = c
12721309
)
12731310
or
1311+
completion = NormalCompletion() and
1312+
n.(AnnotatedExitNode).getEnclosingCallable() = result.(ExitNode).getEnclosingCallable()
1313+
or
12741314
// Logic expressions and conditional expressions execute in AST pre-order.
12751315
completion = NormalCompletion() and
12761316
(

java/ql/lib/semmle/code/java/controlflow/Paths.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ private class JoinBlock extends BasicBlock {
6666
JoinBlock() { 2 <= strictcount(this.getAPredecessor()) }
6767
}
6868

69+
private class ReachableBlock extends BasicBlock {
70+
ReachableBlock() { hasDominanceInformation(this) }
71+
}
72+
6973
/**
7074
* Holds if `bb` is a block that is collectively dominated by a set of one or
7175
* more actions that individually does not dominate the exit.
@@ -74,7 +78,7 @@ private predicate postActionBlock(BasicBlock bb, ActionConfiguration conf) {
7478
bb = nonDominatingActionBlock(conf)
7579
or
7680
if bb instanceof JoinBlock
77-
then forall(BasicBlock pred | pred = bb.getAPredecessor() | postActionBlock(pred, conf))
81+
then forall(ReachableBlock pred | pred = bb.getAPredecessor() | postActionBlock(pred, conf))
7882
else postActionBlock(bb.getAPredecessor(), conf)
7983
}
8084

java/ql/lib/semmle/code/java/security/PathSanitizer.qll

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,10 @@ private module ValidationMethod<DataFlow::guardChecksSig/3 validationGuard> {
3131
* Holds if `m` validates its `arg`th parameter by using `validationGuard`.
3232
*/
3333
private predicate validationMethod(Method m, int arg) {
34-
exists(
35-
Guard g, SsaImplicitInit var, ControlFlow::ExitNode exit, ControlFlowNode normexit,
36-
boolean branch
37-
|
34+
exists(Guard g, SsaImplicitInit var, ControlFlow::NormalExitNode normexit, boolean branch |
3835
validationGuard(g, var.getAUse(), branch) and
3936
var.isParameterDefinition(m.getParameter(arg)) and
40-
exit.getEnclosingCallable() = m and
41-
normexit.getANormalSuccessor() = exit and
42-
1 = strictcount(ControlFlowNode n | n.getANormalSuccessor() = exit)
43-
|
44-
exists(ConditionNode conditionNode |
45-
g = conditionNode.getCondition() and conditionNode.getABranchSuccessor(branch) = exit
46-
)
47-
or
37+
normexit.getEnclosingCallable() = m and
4838
g.controls(normexit.getBasicBlock(), branch)
4939
)
5040
}

java/ql/test-kotlin1/library-tests/controlflow/basic/bbStmts.expected

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
| Test.kt:3:8:80:1 | Exceptional Exit | 0 | Test.kt:3:8:80:1 | Exceptional Exit |
2+
| Test.kt:3:8:80:1 | Exit | 0 | Test.kt:3:8:80:1 | Exit |
13
| Test.kt:3:8:80:1 | { ... } | 0 | Test.kt:3:8:80:1 | { ... } |
24
| Test.kt:3:8:80:1 | { ... } | 1 | Test.kt:3:1:80:1 | super(...) |
35
| Test.kt:3:8:80:1 | { ... } | 2 | Test.kt:3:8:80:1 | { ... } |
4-
| Test.kt:3:8:80:1 | { ... } | 3 | Test.kt:3:8:80:1 | Exit |
6+
| Test.kt:3:8:80:1 | { ... } | 3 | Test.kt:3:8:80:1 | Normal Exit |
7+
| Test.kt:4:2:79:2 | Exceptional Exit | 0 | Test.kt:4:2:79:2 | Exceptional Exit |
58
| Test.kt:4:2:79:2 | Exit | 0 | Test.kt:4:2:79:2 | Exit |
9+
| Test.kt:4:2:79:2 | Normal Exit | 0 | Test.kt:4:2:79:2 | Normal Exit |
610
| Test.kt:4:13:79:2 | { ... } | 0 | Test.kt:4:13:79:2 | { ... } |
711
| Test.kt:4:13:79:2 | { ... } | 1 | Test.kt:5:7:5:7 | var ...; |
812
| Test.kt:4:13:79:2 | { ... } | 2 | Test.kt:5:16:5:16 | 0 |
@@ -102,7 +106,9 @@
102106
| Test.kt:43:3:43:3 | <Expr>; | 8 | Test.kt:77:3:77:8 | ...=... |
103107
| Test.kt:43:3:43:3 | <Expr>; | 9 | Test.kt:78:3:78:8 | INSTANCE |
104108
| Test.kt:43:3:43:3 | <Expr>; | 10 | Test.kt:78:3:78:8 | return ... |
109+
| Test.kt:82:1:89:1 | Exceptional Exit | 0 | Test.kt:82:1:89:1 | Exceptional Exit |
105110
| Test.kt:82:1:89:1 | Exit | 0 | Test.kt:82:1:89:1 | Exit |
111+
| Test.kt:82:1:89:1 | Normal Exit | 0 | Test.kt:82:1:89:1 | Normal Exit |
106112
| Test.kt:82:21:89:1 | { ... } | 0 | Test.kt:82:21:89:1 | { ... } |
107113
| Test.kt:82:21:89:1 | { ... } | 1 | Test.kt:83:2:88:2 | try ... |
108114
| Test.kt:82:21:89:1 | { ... } | 2 | Test.kt:83:6:86:2 | { ... } |
@@ -117,7 +123,9 @@
117123
| Test.kt:86:4:88:2 | catch (...) | 2 | Test.kt:86:34:88:2 | { ... } |
118124
| Test.kt:86:4:88:2 | catch (...) | 3 | Test.kt:87:10:87:10 | 2 |
119125
| Test.kt:86:4:88:2 | catch (...) | 4 | Test.kt:87:3:87:10 | return ... |
126+
| Test.kt:91:1:98:1 | Exceptional Exit | 0 | Test.kt:91:1:98:1 | Exceptional Exit |
120127
| Test.kt:91:1:98:1 | Exit | 0 | Test.kt:91:1:98:1 | Exit |
128+
| Test.kt:91:1:98:1 | Normal Exit | 0 | Test.kt:91:1:98:1 | Normal Exit |
121129
| Test.kt:91:22:98:1 | { ... } | 0 | Test.kt:91:22:98:1 | { ... } |
122130
| Test.kt:91:22:98:1 | { ... } | 1 | Test.kt:92:2:97:2 | try ... |
123131
| Test.kt:91:22:98:1 | { ... } | 2 | Test.kt:92:6:95:2 | { ... } |
@@ -133,6 +141,7 @@
133141
| Test.kt:95:4:97:2 | catch (...) | 3 | Test.kt:96:10:96:10 | 2 |
134142
| Test.kt:95:4:97:2 | catch (...) | 4 | Test.kt:96:3:96:10 | return ... |
135143
| Test.kt:100:1:110:1 | Exit | 0 | Test.kt:100:1:110:1 | Exit |
144+
| Test.kt:100:1:110:1 | Normal Exit | 0 | Test.kt:100:1:110:1 | Normal Exit |
136145
| Test.kt:100:25:110:1 | { ... } | 0 | Test.kt:100:25:110:1 | { ... } |
137146
| Test.kt:100:25:110:1 | { ... } | 1 | Test.kt:101:5:103:5 | <Expr>; |
138147
| Test.kt:100:25:110:1 | { ... } | 2 | Test.kt:101:5:103:5 | when ... |
@@ -147,6 +156,7 @@
147156
| Test.kt:101:33:103:5 | { ... } | 0 | Test.kt:101:33:103:5 | { ... } |
148157
| Test.kt:101:33:103:5 | { ... } | 1 | Test.kt:102:15:102:25 | new Exception(...) |
149158
| Test.kt:101:33:103:5 | { ... } | 2 | Test.kt:102:9:102:25 | throw ... |
159+
| Test.kt:101:33:103:5 | { ... } | 3 | Test.kt:100:1:110:1 | Exceptional Exit |
150160
| Test.kt:105:5:109:5 | <Expr>; | 0 | Test.kt:105:5:109:5 | <Expr>; |
151161
| Test.kt:105:5:109:5 | <Expr>; | 1 | Test.kt:105:5:109:5 | when ... |
152162
| Test.kt:105:5:109:5 | <Expr>; | 2 | Test.kt:105:9:107:5 | ... -> ... |
@@ -165,7 +175,9 @@
165175
| Test.kt:107:27:109:5 | { ... } | 1 | Test.kt:108:9:108:29 | <Expr>; |
166176
| Test.kt:107:27:109:5 | { ... } | 2 | Test.kt:108:17:108:28 | "y not null" |
167177
| Test.kt:107:27:109:5 | { ... } | 3 | Test.kt:108:9:108:29 | println(...) |
178+
| Test.kt:112:1:116:1 | Exceptional Exit | 0 | Test.kt:112:1:116:1 | Exceptional Exit |
168179
| Test.kt:112:1:116:1 | Exit | 0 | Test.kt:112:1:116:1 | Exit |
180+
| Test.kt:112:1:116:1 | Normal Exit | 0 | Test.kt:112:1:116:1 | Normal Exit |
169181
| Test.kt:112:32:116:1 | { ... } | 0 | Test.kt:112:32:116:1 | { ... } |
170182
| Test.kt:112:32:116:1 | { ... } | 1 | Test.kt:113:5:115:5 | <Expr>; |
171183
| Test.kt:112:32:116:1 | { ... } | 2 | Test.kt:113:5:115:5 | when ... |
@@ -174,7 +186,9 @@
174186
| Test.kt:112:32:116:1 | { ... } | 5 | Test.kt:113:9:113:9 | x |
175187
| Test.kt:113:14:113:14 | y | 0 | Test.kt:113:14:113:14 | y |
176188
| Test.kt:113:17:115:5 | { ... } | 0 | Test.kt:113:17:115:5 | { ... } |
189+
| Test.kt:118:1:124:1 | Exceptional Exit | 0 | Test.kt:118:1:124:1 | Exceptional Exit |
177190
| Test.kt:118:1:124:1 | Exit | 0 | Test.kt:118:1:124:1 | Exit |
191+
| Test.kt:118:1:124:1 | Normal Exit | 0 | Test.kt:118:1:124:1 | Normal Exit |
178192
| Test.kt:118:37:124:1 | { ... } | 0 | Test.kt:118:37:124:1 | { ... } |
179193
| Test.kt:118:37:124:1 | { ... } | 1 | Test.kt:119:2:123:12 | <Expr>; |
180194
| Test.kt:118:37:124:1 | { ... } | 2 | Test.kt:119:2:123:12 | when ... |

java/ql/test-kotlin1/library-tests/controlflow/basic/bbStrictDominance.expected

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
| Test.kt:3:8:80:1 | { ... } | Test.kt:3:8:80:1 | Exit |
2+
| Test.kt:4:2:79:2 | Normal Exit | Test.kt:4:2:79:2 | Exit |
13
| Test.kt:4:13:79:2 | { ... } | Test.kt:4:2:79:2 | Exit |
4+
| Test.kt:4:13:79:2 | { ... } | Test.kt:4:2:79:2 | Normal Exit |
25
| Test.kt:4:13:79:2 | { ... } | Test.kt:11:3:16:3 | ... -> ... |
36
| Test.kt:4:13:79:2 | { ... } | Test.kt:11:14:14:3 | { ... } |
47
| Test.kt:4:13:79:2 | { ... } | Test.kt:18:3:18:3 | <Expr>; |
@@ -10,6 +13,7 @@
1013
| Test.kt:4:13:79:2 | { ... } | Test.kt:38:16:41:3 | { ... } |
1114
| Test.kt:4:13:79:2 | { ... } | Test.kt:43:3:43:3 | <Expr>; |
1215
| Test.kt:18:3:18:3 | <Expr>; | Test.kt:4:2:79:2 | Exit |
16+
| Test.kt:18:3:18:3 | <Expr>; | Test.kt:4:2:79:2 | Normal Exit |
1317
| Test.kt:18:3:18:3 | <Expr>; | Test.kt:21:3:24:9 | ... -> ... |
1418
| Test.kt:18:3:18:3 | <Expr>; | Test.kt:22:4:22:4 | <Expr>; |
1519
| Test.kt:18:3:18:3 | <Expr>; | Test.kt:30:15:33:3 | { ... } |
@@ -27,29 +31,39 @@
2731
| Test.kt:35:3:35:3 | <Expr>; | Test.kt:43:3:43:3 | <Expr>; |
2832
| Test.kt:38:9:38:9 | x | Test.kt:38:16:41:3 | { ... } |
2933
| Test.kt:38:9:38:9 | x | Test.kt:43:3:43:3 | <Expr>; |
34+
| Test.kt:82:1:89:1 | Normal Exit | Test.kt:82:1:89:1 | Exit |
3035
| Test.kt:82:21:89:1 | { ... } | Test.kt:82:1:89:1 | Exit |
36+
| Test.kt:82:21:89:1 | { ... } | Test.kt:82:1:89:1 | Normal Exit |
3137
| Test.kt:82:21:89:1 | { ... } | Test.kt:84:7:84:7 | x |
3238
| Test.kt:82:21:89:1 | { ... } | Test.kt:86:4:88:2 | catch (...) |
39+
| Test.kt:91:1:98:1 | Normal Exit | Test.kt:91:1:98:1 | Exit |
3340
| Test.kt:91:22:98:1 | { ... } | Test.kt:91:1:98:1 | Exit |
41+
| Test.kt:91:22:98:1 | { ... } | Test.kt:91:1:98:1 | Normal Exit |
3442
| Test.kt:91:22:98:1 | { ... } | Test.kt:93:7:93:7 | x |
3543
| Test.kt:91:22:98:1 | { ... } | Test.kt:95:4:97:2 | catch (...) |
3644
| Test.kt:100:25:110:1 | { ... } | Test.kt:100:1:110:1 | Exit |
45+
| Test.kt:100:25:110:1 | { ... } | Test.kt:100:1:110:1 | Normal Exit |
3746
| Test.kt:100:25:110:1 | { ... } | Test.kt:101:22:101:22 | y |
3847
| Test.kt:100:25:110:1 | { ... } | Test.kt:101:33:103:5 | { ... } |
3948
| Test.kt:100:25:110:1 | { ... } | Test.kt:105:5:109:5 | <Expr>; |
4049
| Test.kt:100:25:110:1 | { ... } | Test.kt:105:20:107:5 | { ... } |
4150
| Test.kt:100:25:110:1 | { ... } | Test.kt:107:16:109:5 | ... -> ... |
4251
| Test.kt:100:25:110:1 | { ... } | Test.kt:107:27:109:5 | { ... } |
4352
| Test.kt:101:22:101:22 | y | Test.kt:101:33:103:5 | { ... } |
53+
| Test.kt:105:5:109:5 | <Expr>; | Test.kt:100:1:110:1 | Normal Exit |
4454
| Test.kt:105:5:109:5 | <Expr>; | Test.kt:105:20:107:5 | { ... } |
4555
| Test.kt:105:5:109:5 | <Expr>; | Test.kt:107:16:109:5 | ... -> ... |
4656
| Test.kt:105:5:109:5 | <Expr>; | Test.kt:107:27:109:5 | { ... } |
4757
| Test.kt:107:16:109:5 | ... -> ... | Test.kt:107:27:109:5 | { ... } |
58+
| Test.kt:112:1:116:1 | Normal Exit | Test.kt:112:1:116:1 | Exit |
4859
| Test.kt:112:32:116:1 | { ... } | Test.kt:112:1:116:1 | Exit |
60+
| Test.kt:112:32:116:1 | { ... } | Test.kt:112:1:116:1 | Normal Exit |
4961
| Test.kt:112:32:116:1 | { ... } | Test.kt:113:14:113:14 | y |
5062
| Test.kt:112:32:116:1 | { ... } | Test.kt:113:17:115:5 | { ... } |
5163
| Test.kt:113:14:113:14 | y | Test.kt:113:17:115:5 | { ... } |
64+
| Test.kt:118:1:124:1 | Normal Exit | Test.kt:118:1:124:1 | Exit |
5265
| Test.kt:118:37:124:1 | { ... } | Test.kt:118:1:124:1 | Exit |
66+
| Test.kt:118:37:124:1 | { ... } | Test.kt:118:1:124:1 | Normal Exit |
5367
| Test.kt:118:37:124:1 | { ... } | Test.kt:121:9:121:9 | <Expr>; |
5468
| Test.kt:118:37:124:1 | { ... } | Test.kt:122:12:122:16 | ... -> ... |
5569
| Test.kt:118:37:124:1 | { ... } | Test.kt:123:8:123:10 | { ... } |
Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,58 @@
1+
| Test.kt:3:8:80:1 | Exceptional Exit | Test.kt:3:8:80:1 | Exit |
2+
| Test.kt:3:8:80:1 | { ... } | Test.kt:3:8:80:1 | Exit |
3+
| Test.kt:4:2:79:2 | Exceptional Exit | Test.kt:4:2:79:2 | Exit |
4+
| Test.kt:4:2:79:2 | Normal Exit | Test.kt:4:2:79:2 | Exit |
15
| Test.kt:4:13:79:2 | { ... } | Test.kt:11:3:16:3 | ... -> ... |
26
| Test.kt:4:13:79:2 | { ... } | Test.kt:11:14:14:3 | { ... } |
37
| Test.kt:11:3:16:3 | ... -> ... | Test.kt:18:3:18:3 | <Expr>; |
48
| Test.kt:11:14:14:3 | { ... } | Test.kt:18:3:18:3 | <Expr>; |
59
| Test.kt:18:3:18:3 | <Expr>; | Test.kt:21:3:24:9 | ... -> ... |
610
| Test.kt:18:3:18:3 | <Expr>; | Test.kt:22:4:22:4 | <Expr>; |
7-
| Test.kt:21:3:24:9 | ... -> ... | Test.kt:4:2:79:2 | Exit |
11+
| Test.kt:21:3:24:9 | ... -> ... | Test.kt:4:2:79:2 | Normal Exit |
812
| Test.kt:22:4:22:4 | <Expr>; | Test.kt:30:15:33:3 | { ... } |
913
| Test.kt:22:4:22:4 | <Expr>; | Test.kt:35:3:35:3 | <Expr>; |
1014
| Test.kt:30:15:33:3 | { ... } | Test.kt:35:3:35:3 | <Expr>; |
1115
| Test.kt:35:3:35:3 | <Expr>; | Test.kt:38:9:38:9 | x |
1216
| Test.kt:38:9:38:9 | x | Test.kt:38:16:41:3 | { ... } |
1317
| Test.kt:38:9:38:9 | x | Test.kt:43:3:43:3 | <Expr>; |
1418
| Test.kt:38:16:41:3 | { ... } | Test.kt:38:9:38:9 | x |
15-
| Test.kt:43:3:43:3 | <Expr>; | Test.kt:4:2:79:2 | Exit |
19+
| Test.kt:43:3:43:3 | <Expr>; | Test.kt:4:2:79:2 | Normal Exit |
20+
| Test.kt:82:1:89:1 | Exceptional Exit | Test.kt:82:1:89:1 | Exit |
21+
| Test.kt:82:1:89:1 | Normal Exit | Test.kt:82:1:89:1 | Exit |
1622
| Test.kt:82:21:89:1 | { ... } | Test.kt:84:7:84:7 | x |
1723
| Test.kt:82:21:89:1 | { ... } | Test.kt:86:4:88:2 | catch (...) |
18-
| Test.kt:84:7:84:7 | x | Test.kt:82:1:89:1 | Exit |
19-
| Test.kt:86:4:88:2 | catch (...) | Test.kt:82:1:89:1 | Exit |
24+
| Test.kt:84:7:84:7 | x | Test.kt:82:1:89:1 | Normal Exit |
25+
| Test.kt:86:4:88:2 | catch (...) | Test.kt:82:1:89:1 | Normal Exit |
26+
| Test.kt:91:1:98:1 | Exceptional Exit | Test.kt:91:1:98:1 | Exit |
27+
| Test.kt:91:1:98:1 | Normal Exit | Test.kt:91:1:98:1 | Exit |
2028
| Test.kt:91:22:98:1 | { ... } | Test.kt:93:7:93:7 | x |
2129
| Test.kt:91:22:98:1 | { ... } | Test.kt:95:4:97:2 | catch (...) |
22-
| Test.kt:93:7:93:7 | x | Test.kt:91:1:98:1 | Exit |
23-
| Test.kt:95:4:97:2 | catch (...) | Test.kt:91:1:98:1 | Exit |
30+
| Test.kt:93:7:93:7 | x | Test.kt:91:1:98:1 | Normal Exit |
31+
| Test.kt:95:4:97:2 | catch (...) | Test.kt:91:1:98:1 | Normal Exit |
32+
| Test.kt:100:1:110:1 | Normal Exit | Test.kt:100:1:110:1 | Exit |
2433
| Test.kt:100:25:110:1 | { ... } | Test.kt:101:22:101:22 | y |
2534
| Test.kt:100:25:110:1 | { ... } | Test.kt:105:5:109:5 | <Expr>; |
2635
| Test.kt:101:22:101:22 | y | Test.kt:101:33:103:5 | { ... } |
2736
| Test.kt:101:22:101:22 | y | Test.kt:105:5:109:5 | <Expr>; |
2837
| Test.kt:101:33:103:5 | { ... } | Test.kt:100:1:110:1 | Exit |
2938
| Test.kt:105:5:109:5 | <Expr>; | Test.kt:105:20:107:5 | { ... } |
3039
| Test.kt:105:5:109:5 | <Expr>; | Test.kt:107:16:109:5 | ... -> ... |
31-
| Test.kt:105:20:107:5 | { ... } | Test.kt:100:1:110:1 | Exit |
32-
| Test.kt:107:16:109:5 | ... -> ... | Test.kt:100:1:110:1 | Exit |
40+
| Test.kt:105:20:107:5 | { ... } | Test.kt:100:1:110:1 | Normal Exit |
41+
| Test.kt:107:16:109:5 | ... -> ... | Test.kt:100:1:110:1 | Normal Exit |
3342
| Test.kt:107:16:109:5 | ... -> ... | Test.kt:107:27:109:5 | { ... } |
34-
| Test.kt:107:27:109:5 | { ... } | Test.kt:100:1:110:1 | Exit |
35-
| Test.kt:112:32:116:1 | { ... } | Test.kt:112:1:116:1 | Exit |
43+
| Test.kt:107:27:109:5 | { ... } | Test.kt:100:1:110:1 | Normal Exit |
44+
| Test.kt:112:1:116:1 | Exceptional Exit | Test.kt:112:1:116:1 | Exit |
45+
| Test.kt:112:1:116:1 | Normal Exit | Test.kt:112:1:116:1 | Exit |
46+
| Test.kt:112:32:116:1 | { ... } | Test.kt:112:1:116:1 | Normal Exit |
3647
| Test.kt:112:32:116:1 | { ... } | Test.kt:113:14:113:14 | y |
37-
| Test.kt:113:14:113:14 | y | Test.kt:112:1:116:1 | Exit |
48+
| Test.kt:113:14:113:14 | y | Test.kt:112:1:116:1 | Normal Exit |
3849
| Test.kt:113:14:113:14 | y | Test.kt:113:17:115:5 | { ... } |
39-
| Test.kt:113:17:115:5 | { ... } | Test.kt:112:1:116:1 | Exit |
50+
| Test.kt:113:17:115:5 | { ... } | Test.kt:112:1:116:1 | Normal Exit |
51+
| Test.kt:118:1:124:1 | Exceptional Exit | Test.kt:118:1:124:1 | Exit |
52+
| Test.kt:118:1:124:1 | Normal Exit | Test.kt:118:1:124:1 | Exit |
4053
| Test.kt:118:37:124:1 | { ... } | Test.kt:121:9:121:9 | <Expr>; |
4154
| Test.kt:118:37:124:1 | { ... } | Test.kt:122:12:122:16 | ... -> ... |
42-
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:118:1:124:1 | Exit |
55+
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:118:1:124:1 | Normal Exit |
4356
| Test.kt:121:9:121:9 | <Expr>; | Test.kt:123:8:123:10 | { ... } |
44-
| Test.kt:122:12:122:16 | ... -> ... | Test.kt:118:1:124:1 | Exit |
45-
| Test.kt:123:8:123:10 | { ... } | Test.kt:118:1:124:1 | Exit |
57+
| Test.kt:122:12:122:16 | ... -> ... | Test.kt:118:1:124:1 | Normal Exit |
58+
| Test.kt:123:8:123:10 | { ... } | Test.kt:118:1:124:1 | Normal Exit |

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy