Skip to content

Commit a6da499

Browse files
authored
Merge pull request #1398 from aschackmull/java/switchexpr-guards
Java: Add SwitchExpr support in Guards.qll
2 parents 3789cb2 + 98c5dc1 commit a6da499

File tree

6 files changed

+40
-8
lines changed

6 files changed

+40
-8
lines changed

java/ql/src/semmle/code/java/Statement.qll

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,14 @@ class SwitchCase extends Stmt, @case {
423423
*/
424424
SwitchExpr getSwitchExpr() { result.getACase() = this }
425425

426+
/**
427+
* Gets the expression of the surrounding switch that this case is compared
428+
* against.
429+
*/
430+
Expr getSelectorExpr() {
431+
result = this.getSwitch().getExpr() or result = this.getSwitchExpr().getExpr()
432+
}
433+
426434
/**
427435
* PREVIEW FEATURE in Java 12. Subject to removal in a future release.
428436
*
@@ -625,7 +633,10 @@ class BreakStmt extends Stmt, @breakstmt {
625633
override string pp() {
626634
if this.hasLabel()
627635
then result = "break " + this.getLabel()
628-
else if this.hasValue() then result = "break ..." else result = "break"
636+
else
637+
if this.hasValue()
638+
then result = "break ..."
639+
else result = "break"
629640
}
630641

631642
/** This statement's Halstead ID (used to compute Halstead metrics). */

java/ql/src/semmle/code/java/controlflow/Guards.qll

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ class Guard extends ExprParent {
9393
/** Gets the statement containing this guard. */
9494
Stmt getEnclosingStmt() {
9595
result = this.(Expr).getEnclosingStmt() or
96-
result = this.(SwitchCase).getSwitch()
96+
result = this.(SwitchCase).getSwitch() or
97+
result = this.(SwitchCase).getSwitchExpr().getEnclosingStmt()
9798
}
9899

99100
/**
@@ -126,7 +127,7 @@ class Guard extends ExprParent {
126127
branch = true and
127128
bb2.getFirstNode() = sc.getControlFlowNode() and
128129
pred = sc.getControlFlowNode().getAPredecessor() and
129-
pred.(Expr).getParent*() = sc.getSwitch().getExpr() and
130+
pred.(Expr).getParent*() = sc.getSelectorExpr() and
130131
bb1 = pred.getBasicBlock()
131132
)
132133
or
@@ -160,12 +161,12 @@ class Guard extends ExprParent {
160161
}
161162

162163
private predicate switchCaseControls(SwitchCase sc, BasicBlock bb) {
163-
exists(BasicBlock caseblock, SwitchStmt ss |
164-
ss.getACase() = sc and
164+
exists(BasicBlock caseblock, Expr selector |
165+
selector = sc.getSelectorExpr() and
165166
caseblock.getFirstNode() = sc.getControlFlowNode() and
166167
caseblock.bbDominates(bb) and
167168
forall(ControlFlowNode pred | pred = sc.getControlFlowNode().getAPredecessor() |
168-
pred.(Expr).getParent*() = ss.getExpr()
169+
pred.(Expr).getParent*() = selector
169170
)
170171
)
171172
}
@@ -254,7 +255,8 @@ private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) {
254255
exists(ConstCase cc |
255256
cc = g and
256257
polarity = true and
257-
cc.getSwitch().getExpr().getProperExpr() = e1 and
258-
cc.getValue() = e2
258+
cc.getSelectorExpr().getProperExpr() = e1 and
259+
cc.getValue() = e2 and
260+
strictcount(cc.getValue(_)) = 1
259261
)
260262
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Test {
2+
void foo(String s) {
3+
int x = switch(s) {
4+
case "a", "b" -> 1;
5+
case "c" -> 2;
6+
default -> 3;
7+
};
8+
}
9+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| Test.java:5:7:5:17 | stmt | Test.java:3:20:3:20 | s | Test.java:5:12:5:14 | "c" | true | true | Test.java:5:7:5:17 | stmt |
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import java
2+
import semmle.code.java.controlflow.Guards
3+
4+
from Guard g, BasicBlock bb, boolean branch, VarAccess e1, Expr e2, boolean pol
5+
where
6+
g.controls(bb, branch) and
7+
g.isEquality(e1, e2, pol)
8+
select g, e1, e2, pol, branch, bb
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//semmle-extractor-options: --javac-args --enable-preview -source 12 -target 12

0 commit comments

Comments
 (0)