JS: exclude direct flow from the RHS in a destructuring assignment

This commit is contained in:
Esben Sparre Andreasen
2019-02-07 01:02:14 +01:00
parent f333419bb4
commit 687b7f0a7f
6 changed files with 26 additions and 7 deletions

View File

@@ -19,7 +19,7 @@ import DeadStore
*/
predicate deadStoreOfLocal(VarDef vd, PurelyLocalVariable v) {
v = vd.getAVariable() and
exists(vd.getSource()) and
(exists(vd.getSource()) or exists(vd.getDestructuringSource())) and
// the definition is not in dead code
exists(ReachableBasicBlock rbb | vd = rbb.getANode()) and
// but it has no associated SSA definition, that is, it is dead

View File

@@ -187,9 +187,23 @@ class VarDef extends ControlFlowNode {
* the value that this definition assigns to its target.
*
* This predicate is not defined for `VarDef`s where the source is implicit,
* such as `for-in` loops or parameters.
* such as `for-in` loops, parameters or destructuring assignments.
*/
AST::ValueNode getSource() { defn(this, _, result) }
AST::ValueNode getSource() {
exists(Expr target |
not target instanceof DestructuringPattern and defn(this, target, result)
)
}
/**
* Gets the source that this definition destructs, that is, the
* right hand side of a destructuring assignment.
*/
AST::ValueNode getDestructuringSource() {
exists(Expr target |
target instanceof DestructuringPattern and defn(this, target, result)
)
}
/**
* Holds if this definition of `v` is overwritten by another definition, that is,

View File

@@ -992,7 +992,9 @@ module DataFlow {
* flow through IIFE calls into account.
*/
private AST::ValueNode defSourceNode(VarDef def) {
result = def.getSource() or localArgumentPassing(result, def)
result = def.getSource() or
result = def.getDestructuringSource() or
localArgumentPassing(result, def)
}
/**

View File

@@ -53,9 +53,7 @@ private class SsaVarAccessWithNonLocalAnalysis extends SsaVarAccessAnalysis {
exists(VarDef varDef |
varDef = def.(SsaExplicitDefinition).getDef() and
varDef.getSource().flow() = src and
src instanceof CallWithNonLocalAnalyzedReturnFlow and
// avoid relating `v` and `f()` in `var {v} = f();`
not varDef.getTarget() instanceof DestructuringPattern
src instanceof CallWithNonLocalAnalyzedReturnFlow
)
}

View File

@@ -0,0 +1 @@
| tst.js:23:6:23:23 | {a = b, c = d} = e | tst.js:23:23:23:23 | e |

View File

@@ -0,0 +1,4 @@
import javascript
from VarDef d
select d, d.getDestructuringSource()