mirror of
https://github.com/github/codeql.git
synced 2026-05-01 11:45:14 +02:00
JS: only warn about dead code
This commit is contained in:
@@ -11,18 +11,49 @@
|
||||
import javascript
|
||||
|
||||
/**
|
||||
* Gets the guard node with the opposite outcome of `guard`.
|
||||
* Holds if there are any contradictory guard nodes in `container`.
|
||||
*
|
||||
* We use this to restrict reachability analysis to a small set of containers.
|
||||
*/
|
||||
ConditionGuardNode getOppositeGuard(ConditionGuardNode guard) {
|
||||
result.getTest() = guard.getTest() and
|
||||
result.getOutcome() = guard.getOutcome().booleanNot()
|
||||
predicate hasContradictoryGuardNodes(StmtContainer container) {
|
||||
exists (ConditionGuardNode guard |
|
||||
RangeAnalysis::isContradictoryGuardNode(guard) and
|
||||
container = guard.getContainer())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `block` is reachable and is in a container with contradictory guard nodes.
|
||||
*/
|
||||
predicate isReachable(BasicBlock block) {
|
||||
exists (StmtContainer container |
|
||||
hasContradictoryGuardNodes(container) and
|
||||
block = container.getEntryBB())
|
||||
or
|
||||
isReachable(block.getAPredecessor()) and
|
||||
not RangeAnalysis::isContradictoryGuardNode(block.getANode())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `block` is unreachable, but could be reached if `guard` was not contradictory.
|
||||
*/
|
||||
predicate isBlockedByContradictoryGuardNodes(BasicBlock block, ConditionGuardNode guard) {
|
||||
RangeAnalysis::isContradictoryGuardNode(guard) and
|
||||
isReachable(block.getAPredecessor()) and // the guard itself is reachable
|
||||
block = guard.getBasicBlock()
|
||||
or
|
||||
isBlockedByContradictoryGuardNodes(block.getAPredecessor(), guard) and
|
||||
not isReachable(block)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the given guard node is contradictory and causes an expression or statement to be unreachable.
|
||||
*/
|
||||
predicate isGuardNodeWithDeadCode(ConditionGuardNode guard) {
|
||||
exists (BasicBlock block |
|
||||
isBlockedByContradictoryGuardNodes(block, guard) and
|
||||
block.getANode() instanceof ExprOrStmt)
|
||||
}
|
||||
|
||||
from ConditionGuardNode guard
|
||||
where RangeAnalysis::isContradictoryGuardNode(guard)
|
||||
|
||||
// Do not report conditions that themselves are unreachable because of
|
||||
// a prior contradiction.
|
||||
and not RangeAnalysis::isContradictoryGuardNode(getOppositeGuard(guard))
|
||||
|
||||
where isGuardNodeWithDeadCode(guard)
|
||||
select guard.getTest(), "The condition '" + guard.getTest() + "' is always " + guard.getOutcome().booleanNot()
|
||||
|
||||
Reference in New Issue
Block a user