Merge pull request #10758 from hvitved/ruby/type-tracking-level-step

Type tracking: Split up `levelStep` into `levelStepCall` and `levelStepNoCall`
This commit is contained in:
Tom Hvitved
2022-10-12 10:42:01 +02:00
committed by GitHub
4 changed files with 30 additions and 18 deletions

View File

@@ -186,7 +186,7 @@ private module Cached {
jumpStep(nodeFrom, nodeTo) and
summary = JumpStep()
or
levelStep(nodeFrom, nodeTo) and
levelStepNoCall(nodeFrom, nodeTo) and
summary = LevelStep()
or
exists(TypeTrackerContent content |
@@ -216,6 +216,9 @@ private module Cached {
or
returnStep(nodeFrom, nodeTo) and
summary = ReturnStep()
or
levelStepCall(nodeFrom, nodeTo) and
summary = LevelStep()
}
}

View File

@@ -45,8 +45,11 @@ predicate simpleLocalFlowStep = DataFlowPrivate::simpleLocalFlowStepForTypetrack
predicate jumpStep = DataFlowPrivate::jumpStepSharedWithTypeTracker/2;
/** Holds if there is a level step from `pred` to `succ`. */
predicate levelStep(Node pred, Node succ) { none() }
/** Holds if there is a level step from `nodeFrom` to `nodeTo`, which may depend on the call graph. */
predicate levelStepCall(Node nodeFrom, Node nodeTo) { none() }
/** Holds if there is a level step from `nodeFrom` to `nodeTo`, which does not depend on the call graph. */
predicate levelStepNoCall(Node nodeFrom, Node nodeTo) { none() }
/**
* Gets the name of a possible piece of content. For Python, this is currently only attribute names,

View File

@@ -186,7 +186,7 @@ private module Cached {
jumpStep(nodeFrom, nodeTo) and
summary = JumpStep()
or
levelStep(nodeFrom, nodeTo) and
levelStepNoCall(nodeFrom, nodeTo) and
summary = LevelStep()
or
exists(TypeTrackerContent content |
@@ -216,6 +216,9 @@ private module Cached {
or
returnStep(nodeFrom, nodeTo) and
summary = ReturnStep()
or
levelStepCall(nodeFrom, nodeTo) and
summary = LevelStep()
}
}

View File

@@ -76,20 +76,28 @@ predicate simpleLocalFlowStep = DataFlowPrivate::localFlowStepTypeTracker/2;
*/
predicate jumpStep = DataFlowPrivate::jumpStep/2;
/**
* Holds if there is a summarized local flow step from `nodeFrom` to `nodeTo`,
* because there is direct flow from a parameter to a return. That is, summarized
* steps are not applied recursively.
*/
/** Holds if there is direct flow from `param` to a return. */
pragma[nomagic]
private predicate summarizedLocalStep(Node nodeFrom, Node nodeTo) {
exists(DataFlowPublic::ParameterNode param, DataFlowPrivate::ReturningNode returnNode |
private predicate flowThrough(DataFlowPublic::ParameterNode param) {
exists(DataFlowPrivate::ReturningNode returnNode |
DataFlowPrivate::LocalFlow::getParameterDefNode(param.getParameter())
.(TypeTrackingNode)
.flowsTo(returnNode) and
.flowsTo(returnNode)
)
}
/** Holds if there is a level step from `nodeFrom` to `nodeTo`, which may depend on the call graph. */
pragma[nomagic]
predicate levelStepCall(Node nodeFrom, Node nodeTo) {
exists(DataFlowPublic::ParameterNode param |
flowThrough(param) and
callStep(nodeTo.asExpr(), nodeFrom, param)
)
or
}
/** Holds if there is a level step from `nodeFrom` to `nodeTo`, which does not depend on the call graph. */
pragma[nomagic]
predicate levelStepNoCall(Node nodeFrom, Node nodeTo) {
exists(
SummarizedCallable callable, DataFlowPublic::CallNode call, SummaryComponentStack input,
SummaryComponentStack output
@@ -99,11 +107,6 @@ private predicate summarizedLocalStep(Node nodeFrom, Node nodeTo) {
nodeFrom = evaluateSummaryComponentStackLocal(callable, call, input) and
nodeTo = evaluateSummaryComponentStackLocal(callable, call, output)
)
}
/** Holds if there is a level step from `nodeFrom` to `nodeTo`. */
predicate levelStep(Node nodeFrom, Node nodeTo) {
summarizedLocalStep(nodeFrom, nodeTo)
or
localFieldStep(nodeFrom, nodeTo)
}