diff --git a/java/ql/lib/change-notes/2024-11-14-unreachable-basic-block-in-constant-switch-statement.md b/java/ql/lib/change-notes/2024-11-14-unreachable-basic-block-in-constant-switch-statement.md new file mode 100644 index 000000000000..50df55a4c1a9 --- /dev/null +++ b/java/ql/lib/change-notes/2024-11-14-unreachable-basic-block-in-constant-switch-statement.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* In a switch statement with a constant switch expression, all non-matching cases were being marked as unreachable, including those that can be reached by falling through from the matching case. This has now been fixed. diff --git a/java/ql/lib/semmle/code/java/controlflow/UnreachableBlocks.qll b/java/ql/lib/semmle/code/java/controlflow/UnreachableBlocks.qll index 3145371561a7..f34ace10d314 100644 --- a/java/ql/lib/semmle/code/java/controlflow/UnreachableBlocks.qll +++ b/java/ql/lib/semmle/code/java/controlflow/UnreachableBlocks.qll @@ -217,13 +217,15 @@ class UnreachableBasicBlock extends BasicBlock { not this instanceof CatchClause or // Switch statements with a constant comparison expression may have unreachable cases. - exists(ConstSwitchStmt constSwitchStmt, BasicBlock failingCaseBlock | - failingCaseBlock = constSwitchStmt.getAFailingCase().getBasicBlock() - | + exists(ConstSwitchStmt constSwitchStmt, BasicBlock unreachableCaseBlock | + // Not accessible from the switch expression + unreachableCaseBlock = constSwitchStmt.getAFailingCase().getBasicBlock() and // Not accessible from the successful case - not constSwitchStmt.getMatchingCase().getBasicBlock().getABBSuccessor*() = failingCaseBlock and - // Blocks dominated by the failing case block are unreachable - constSwitchStmt.getAFailingCase().getBasicBlock().bbDominates(this) + not constSwitchStmt.getMatchingCase().getBasicBlock().getABBSuccessor*() = + unreachableCaseBlock + | + // Blocks dominated by an unreachable case block are unreachable + unreachableCaseBlock.bbDominates(this) ) } } diff --git a/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected b/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected index 35178b0a3493..6bd76ea4b96e 100644 --- a/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected +++ b/java/ql/test/library-tests/unreachableblocks/UnreachableBlocks.expected @@ -3,7 +3,6 @@ | unreachableblocks/Unreachable.java:12:22:14:3 | { ... } | | unreachableblocks/Unreachable.java:17:3:17:9 | case ... | | unreachableblocks/Unreachable.java:19:3:19:9 | case ... | -| unreachableblocks/Unreachable.java:22:3:22:9 | case ... | | unreachableblocks/Unreachable.java:24:3:24:9 | case ... | | unreachableblocks/Unreachable.java:26:3:26:10 | case ... | | unreachableblocks/Unreachable.java:27:3:27:10 | default |