mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
JS: Avoid misoptimization in mayReturnImplicitValue
This commit is contained in:
@@ -299,11 +299,21 @@ class ControlFlowNode extends @cfg_node, Locatable, NodeInStmtContainer {
|
||||
*/
|
||||
predicate isStart() { this = any(StmtContainer sc).getStart() }
|
||||
|
||||
/**
|
||||
* Holds if this is a final node of the given container, that is, a CFG node where execution
|
||||
* of that toplevel or function terminates.
|
||||
*/
|
||||
predicate isAFinalNodeOfContainer(StmtContainer container) {
|
||||
getASuccessor().(SyntheticControlFlowNode).isAFinalNodeOfContainer(container)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this is a final node, that is, a CFG node where execution of a
|
||||
* toplevel or function terminates.
|
||||
*/
|
||||
predicate isAFinalNode() { getASuccessor().(SyntheticControlFlowNode).isAFinalNode() }
|
||||
final predicate isAFinalNode() {
|
||||
isAFinalNodeOfContainer(_)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this node is unreachable, that is, it has no predecessors in the CFG.
|
||||
@@ -361,7 +371,7 @@ class ControlFlowEntryNode extends SyntheticControlFlowNode, @entry_node {
|
||||
|
||||
/** A synthetic CFG node marking the exit of a function or toplevel script. */
|
||||
class ControlFlowExitNode extends SyntheticControlFlowNode, @exit_node {
|
||||
override predicate isAFinalNode() { any() }
|
||||
override predicate isAFinalNodeOfContainer(StmtContainer container) { exit_cfg_node(this, container) }
|
||||
|
||||
override string toString() { result = "exit node of " + getContainer().toString() }
|
||||
}
|
||||
|
||||
@@ -256,15 +256,17 @@ class AnalyzedFunction extends DataFlow::AnalyzedValueNode {
|
||||
* account for `finally` blocks and does not check reachability.
|
||||
*/
|
||||
private predicate mayReturnImplicitly() {
|
||||
exists(ConcreteControlFlowNode final |
|
||||
final.getContainer() = astNode and
|
||||
final.isAFinalNode() and
|
||||
not final instanceof ReturnStmt and
|
||||
not final instanceof ThrowStmt
|
||||
)
|
||||
terminalNode(astNode, any(ExprOrStmt st))
|
||||
}
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate terminalNode(Function f, ControlFlowNode final) {
|
||||
final.isAFinalNodeOfContainer(f) and
|
||||
not final instanceof ReturnStmt and
|
||||
not final instanceof ThrowStmt
|
||||
}
|
||||
|
||||
/**
|
||||
* Flow analysis for generator functions.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user