Skip to content

Commit efb49fc

Browse files
authored
Merge pull request github#14336 from aschackmull/java/switch-rule-stmt-cfg
Java: Fix CFG for case rule statements.
2 parents d7beda7 + 15e1098 commit efb49fc

File tree

6 files changed

+47
-3
lines changed

6 files changed

+47
-3
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Fixed a control-flow bug where case rule statements would incorrectly include a fall-through edge.
5+
* Added support for default cases as proper guards in switch expressions to match switch statements.

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,13 @@ private module ControlFlowGraphImpl {
871871
)
872872
or
873873
// the last node in a case rule is the last node in the right-hand side
874-
last(n.(SwitchCase).getRuleStatement(), last, completion)
874+
// if the rhs is a statement we wrap the completion as a break
875+
exists(Completion caseCompletion |
876+
last(n.(SwitchCase).getRuleStatement(), last, caseCompletion) and
877+
if caseCompletion instanceof NormalOrBooleanCompletion
878+
then completion = anonymousBreakCompletion()
879+
else completion = caseCompletion
880+
)
875881
or
876882
// ...and if the rhs is an expression we wrap the completion as a yield
877883
exists(Completion caseCompletion |

java/ql/lib/semmle/code/java/controlflow/internal/GuardsLogic.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ predicate implies_v1(Guard g1, boolean b1, Guard g2, boolean b2) {
5757
or
5858
g1.(DefaultCase).getSwitch().getAConstCase() = g2 and b1 = true and b2 = false
5959
or
60+
g1.(DefaultCase).getSwitchExpr().getAConstCase() = g2 and b1 = true and b2 = false
61+
or
6062
exists(MethodAccess check, int argIndex | check = g1 |
6163
conditionCheckArgument(check, argIndex, _) and
6264
g2 = check.getArgument(argIndex) and

java/ql/test/library-tests/guards12/PrintAst.expected

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,22 @@ Test.java:
1919
# 5| 1: [ConstCase] case ...
2020
# 5| -1: [IntegerLiteral] 2
2121
# 5| 0: [StringLiteral] "c"
22-
# 6| 2: [DefaultCase] default
23-
# 6| -1: [IntegerLiteral] 3
22+
# 6| 2: [ConstCase] case ...
23+
# 6| -1: [IntegerLiteral] 2
24+
# 6| 0: [StringLiteral] "d"
25+
# 7| 3: [DefaultCase] default
26+
# 7| -1: [IntegerLiteral] 3
27+
# 9| 1: [SwitchStmt] switch (...)
28+
# 9| -1: [VarAccess] s
29+
# 10| 0: [ConstCase] case ...
30+
# 10| -1: [BlockStmt] { ... }
31+
# 10| 0: [StringLiteral] "a"
32+
# 10| 1: [StringLiteral] "b"
33+
# 11| 1: [ConstCase] case ...
34+
# 11| -1: [BlockStmt] { ... }
35+
# 11| 0: [StringLiteral] "c"
36+
# 12| 2: [ConstCase] case ...
37+
# 12| -1: [BlockStmt] { ... }
38+
# 12| 0: [StringLiteral] "d"
39+
# 13| 3: [DefaultCase] default
40+
# 13| -1: [BlockStmt] { ... }

java/ql/test/library-tests/guards12/Test.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ void foo(String s) {
33
int x = switch(s) {
44
case "a", "b" -> 1;
55
case "c" -> 2;
6+
case "d" -> 2;
67
default -> 3;
78
};
9+
switch (s) {
10+
case "a", "b" -> { }
11+
case "c" -> { }
12+
case "d" -> { }
13+
default -> { }
14+
}
815
}
916
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1+
| Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | false | Test.java:7:7:7:16 | default |
12
| Test.java:5:7:5:17 | case ... | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | true | Test.java:5:7:5:17 | case ... |
3+
| Test.java:6:7:6:17 | case ... | Test.java:3:20:3:20 | s | Test.java:6:12:6:14 | "d" | true | false | Test.java:7:7:7:16 | default |
4+
| Test.java:6:7:6:17 | case ... | Test.java:3:20:3:20 | s | Test.java:6:12:6:14 | "d" | true | true | Test.java:6:7:6:17 | case ... |
5+
| Test.java:11:7:11:17 | case ... | Test.java:9:13:9:13 | s | Test.java:11:12:11:14 | "c" | true | false | Test.java:13:7:13:16 | default |
6+
| Test.java:11:7:11:17 | case ... | Test.java:9:13:9:13 | s | Test.java:11:12:11:14 | "c" | true | true | Test.java:11:7:11:17 | case ... |
7+
| Test.java:12:7:12:17 | case ... | Test.java:9:13:9:13 | s | Test.java:12:12:12:14 | "d" | true | false | Test.java:13:7:13:16 | default |
8+
| Test.java:12:7:12:17 | case ... | Test.java:9:13:9:13 | s | Test.java:12:12:12:14 | "d" | true | true | Test.java:12:7:12:17 | case ... |

0 commit comments

Comments
 (0)