|
|
|
|
@@ -235,17 +235,6 @@ private predicate stepProj(TypeTrackingNode nodeFrom, StepSummary summary) {
|
|
|
|
|
step(nodeFrom, _, summary)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bindingset[nodeFrom, t]
|
|
|
|
|
pragma[inline_late]
|
|
|
|
|
pragma[noopt]
|
|
|
|
|
private TypeTracker stepInlineLate(TypeTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) {
|
|
|
|
|
exists(StepSummary summary |
|
|
|
|
|
stepProj(nodeFrom, summary) and
|
|
|
|
|
result = t.append(summary) and
|
|
|
|
|
step(nodeFrom, nodeTo, summary)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private predicate smallstep(Node nodeFrom, TypeTrackingNode nodeTo, StepSummary summary) {
|
|
|
|
|
smallstepNoCall(nodeFrom, nodeTo, summary)
|
|
|
|
|
or
|
|
|
|
|
@@ -257,17 +246,6 @@ private predicate smallstepProj(Node nodeFrom, StepSummary summary) {
|
|
|
|
|
smallstep(nodeFrom, _, summary)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bindingset[nodeFrom, t]
|
|
|
|
|
pragma[inline_late]
|
|
|
|
|
pragma[noopt]
|
|
|
|
|
private TypeTracker smallstepInlineLate(TypeTracker t, Node nodeFrom, Node nodeTo) {
|
|
|
|
|
exists(StepSummary summary |
|
|
|
|
|
smallstepProj(nodeFrom, summary) and
|
|
|
|
|
result = t.append(summary) and
|
|
|
|
|
smallstep(nodeFrom, nodeTo, summary)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Holds if `nodeFrom` is being written to the `content` of the object in `nodeTo`.
|
|
|
|
|
*
|
|
|
|
|
@@ -501,9 +479,26 @@ class TypeTracker extends TTypeTracker {
|
|
|
|
|
* Gets the summary that corresponds to having taken a forwards
|
|
|
|
|
* heap and/or inter-procedural step from `nodeFrom` to `nodeTo`.
|
|
|
|
|
*/
|
|
|
|
|
pragma[inline]
|
|
|
|
|
bindingset[nodeFrom, this]
|
|
|
|
|
pragma[inline_late]
|
|
|
|
|
pragma[noopt]
|
|
|
|
|
TypeTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) {
|
|
|
|
|
result = stepInlineLate(this, nodeFrom, nodeTo)
|
|
|
|
|
exists(StepSummary summary |
|
|
|
|
|
stepProj(nodeFrom, summary) and
|
|
|
|
|
result = this.append(summary) and
|
|
|
|
|
step(nodeFrom, nodeTo, summary)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bindingset[nodeFrom, this]
|
|
|
|
|
pragma[inline_late]
|
|
|
|
|
pragma[noopt]
|
|
|
|
|
private TypeTracker smallstepNoSimpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
|
|
|
|
exists(StepSummary summary |
|
|
|
|
|
smallstepProj(nodeFrom, summary) and
|
|
|
|
|
result = this.append(summary) and
|
|
|
|
|
smallstep(nodeFrom, nodeTo, summary)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -532,7 +527,7 @@ class TypeTracker extends TTypeTracker {
|
|
|
|
|
*/
|
|
|
|
|
pragma[inline]
|
|
|
|
|
TypeTracker smallstep(Node nodeFrom, Node nodeTo) {
|
|
|
|
|
result = smallstepInlineLate(this, nodeFrom, nodeTo)
|
|
|
|
|
result = this.smallstepNoSimpleLocalFlowStep(nodeFrom, nodeTo)
|
|
|
|
|
or
|
|
|
|
|
simpleLocalFlowStep(nodeFrom, nodeTo) and
|
|
|
|
|
result = this
|
|
|
|
|
@@ -552,34 +547,10 @@ private predicate backStepProj(TypeTrackingNode nodeTo, StepSummary summary) {
|
|
|
|
|
step(_, nodeTo, summary)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bindingset[nodeTo, t]
|
|
|
|
|
pragma[inline_late]
|
|
|
|
|
pragma[noopt]
|
|
|
|
|
private TypeBackTracker backStepInlineLate(
|
|
|
|
|
TypeBackTracker t, TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo
|
|
|
|
|
) {
|
|
|
|
|
exists(StepSummary summary |
|
|
|
|
|
backStepProj(nodeTo, summary) and
|
|
|
|
|
result = t.prepend(summary) and
|
|
|
|
|
step(nodeFrom, nodeTo, summary)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private predicate backSmallstepProj(TypeTrackingNode nodeTo, StepSummary summary) {
|
|
|
|
|
smallstep(_, nodeTo, summary)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bindingset[nodeTo, t]
|
|
|
|
|
pragma[inline_late]
|
|
|
|
|
pragma[noopt]
|
|
|
|
|
private TypeBackTracker backSmallstepInlineLate(TypeBackTracker t, Node nodeFrom, Node nodeTo) {
|
|
|
|
|
exists(StepSummary summary |
|
|
|
|
|
backSmallstepProj(nodeTo, summary) and
|
|
|
|
|
result = t.prepend(summary) and
|
|
|
|
|
smallstep(nodeFrom, nodeTo, summary)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A summary of the steps needed to back-track a use of a value to a given dataflow node.
|
|
|
|
|
*
|
|
|
|
|
@@ -661,9 +632,26 @@ class TypeBackTracker extends TTypeBackTracker {
|
|
|
|
|
* Gets the summary that corresponds to having taken a backwards
|
|
|
|
|
* heap and/or inter-procedural step from `nodeTo` to `nodeFrom`.
|
|
|
|
|
*/
|
|
|
|
|
pragma[inline]
|
|
|
|
|
bindingset[nodeTo, result]
|
|
|
|
|
pragma[inline_late]
|
|
|
|
|
pragma[noopt]
|
|
|
|
|
TypeBackTracker step(TypeTrackingNode nodeFrom, TypeTrackingNode nodeTo) {
|
|
|
|
|
this = backStepInlineLate(result, nodeFrom, nodeTo)
|
|
|
|
|
exists(StepSummary summary |
|
|
|
|
|
backStepProj(nodeTo, summary) and
|
|
|
|
|
this = result.prepend(summary) and
|
|
|
|
|
step(nodeFrom, nodeTo, summary)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bindingset[nodeTo, result]
|
|
|
|
|
pragma[inline_late]
|
|
|
|
|
pragma[noopt]
|
|
|
|
|
private TypeBackTracker smallstepNoSimpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
|
|
|
|
exists(StepSummary summary |
|
|
|
|
|
backSmallstepProj(nodeTo, summary) and
|
|
|
|
|
this = result.prepend(summary) and
|
|
|
|
|
smallstep(nodeFrom, nodeTo, summary)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -692,7 +680,7 @@ class TypeBackTracker extends TTypeBackTracker {
|
|
|
|
|
*/
|
|
|
|
|
pragma[inline]
|
|
|
|
|
TypeBackTracker smallstep(Node nodeFrom, Node nodeTo) {
|
|
|
|
|
this = backSmallstepInlineLate(result, nodeFrom, nodeTo)
|
|
|
|
|
this = this.smallstepNoSimpleLocalFlowStep(nodeFrom, nodeTo)
|
|
|
|
|
or
|
|
|
|
|
simpleLocalFlowStep(nodeFrom, nodeTo) and
|
|
|
|
|
this = result
|
|
|
|
|
|