JS: introduce TypeInferredCalleeWithAnalyzedReturnFlow

This commit is contained in:
Esben Sparre Andreasen
2018-09-06 15:53:43 +02:00
parent fef3573152
commit a07c094437
13 changed files with 161 additions and 19 deletions

View File

@@ -756,7 +756,7 @@ module DataFlow {
/**
* A data flow node representing an explicit (that is, non-reflective) function call.
*/
private class ExplicitCallNode extends CallNodeDef, ExplicitInvokeNode {
class ExplicitCallNode extends CallNodeDef, ExplicitInvokeNode {
override CallExpr astNode;
}

View File

@@ -143,6 +143,23 @@ abstract class CallWithAnalyzedReturnFlow extends DataFlow::AnalyzedValueNode {
}
}
/**
* A call with inter-procedural type inference for the return value.
*
* Unlike `CallWithAnalyzedReturnFlow`, this only contributes to `getAValue()`, not `getALocalValue()`.
*/
abstract class CallWithNonLocalAnalyzedReturnFlow extends DataFlow::AnalyzedValueNode {
/**
* Gets a called function.
*/
abstract AnalyzedFunction getACallee();
override AbstractValue getAValue() {
result = getACallee().getAReturnValue()
}
}
/**
* Flow analysis for the return value of IIFEs.
*/
@@ -210,4 +227,30 @@ private class LocalFunctionCallWithAnalyzedReturnFlow extends CallWithAnalyzedRe
result = f.analyze()
}
}
}
pragma[noinline]
private predicate hasExplicitDefiniteCallee(DataFlow::Impl::ExplicitCallNode call, DataFlow::AnalyzedNode callee) {
callee = call.getCalleeNode() and
not callee.getALocalValue().isIndefinite(_)
}
/**
* Enables inter-procedural type inference for the return value of a call to a type-inferred callee.
*/
private class TypeInferredCalleeWithAnalyzedReturnFlow extends CallWithNonLocalAnalyzedReturnFlow {
DataFlow::FunctionNode fun;
TypeInferredCalleeWithAnalyzedReturnFlow() {
exists (DataFlow::AnalyzedNode calleeNode |
hasExplicitDefiniteCallee(this, calleeNode) and
calleeNode.getALocalValue().(AbstractFunction).getFunction().flow() = fun
)
}
override AnalyzedFunction getACallee() {
result = fun
}
}