JS: Avoid misoptimization in mayReturnImplicitValue

This commit is contained in:
Asger Feldthaus
2020-05-01 08:40:09 +01:00
parent eddbdffe62
commit d9123833af
2 changed files with 20 additions and 8 deletions

View File

@@ -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() }
}

View File

@@ -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.
*/