Skip to content

Commit 4a1fcde

Browse files
committed
Python: abandon synthetic node
for `CapturingClosureArgumentNode`. Unless we define it for every single `CallNode`, we need a more sophisticated mutual recursion with the call graph construction. There is built-in support for that, but we are currently not using it.
1 parent e36b079 commit 4a1fcde

File tree

3 files changed

+23
-8
lines changed

3 files changed

+23
-8
lines changed

python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ class ArgumentPosition extends TArgumentPosition {
179179
string toString() {
180180
this.isSelf() and result = "self"
181181
or
182+
this.isLambdaSelf() and result = "lambda self"
183+
or
182184
exists(int pos | this.isPositional(pos) and result = "position " + pos)
183185
or
184186
exists(string name | this.isKeyword(name) and result = "keyword " + name)
@@ -1647,23 +1649,34 @@ private class SynthCapturePostUpdateNode extends PostUpdateNodeImpl, SynthCaptur
16471649
* separate node and parameter/argument positions in order to distinguish
16481650
* "lambda self" from "normal self", as lambdas may also access outer `self`
16491651
* variables (through variable capture).
1652+
*
1653+
* TODO:
1654+
* We might want a synthetic node here, but currently that incurs problems
1655+
* with non-monotonic recursion, because of the use of `resolveCall` in the
1656+
* char pred. This may be solvable by using
1657+
* `CallGraphConstruction::Make` in staed of
1658+
* `CallGraphConstruction::Simple::Make` appropriately.
16501659
*/
1651-
class SynthCaptureArgumentNode extends TSynthCapturingClosureArgumentNode, ArgumentNode {
1660+
class CapturingClosureArgumentNode extends CfgNode, ArgumentNode {
16521661
CallNode callNode;
16531662

1654-
SynthCaptureArgumentNode() {
1655-
this = TSynthCapturingClosureArgumentNode(callNode) and
1656-
// We would prefer to put this restriction in the charpred for the branch,
1657-
// but that incurs non-monotonic recursion.
1663+
CapturingClosureArgumentNode() {
1664+
this.getNode() = callNode.getFunction() and
16581665
exists(Function target | resolveCall(callNode, target, _) |
16591666
target = any(VariableCapture::CapturedVariable v).getACapturingScope()
16601667
)
16611668
}
16621669

1670+
override string toString() { result = "Capturing closure argument" }
1671+
1672+
// final override Location getLocation() { result = callNode.getLocation() }
16631673
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
16641674
callNode = call.getNode() and
16651675
pos.isLambdaSelf()
16661676
}
1677+
1678+
/** Gets the `CallNode` that is being passed as an argument to itself. */
1679+
CallNode getCallNode() { result = callNode }
16671680
}
16681681

16691682
/** Gets a viable run-time target for the call `call`. */

python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,7 @@ newtype TNode =
120120
/** A synthetic node representing the heap of a function. Used for variable capture. */
121121
TSynthCapturingClosureParameterNode(Function f) {
122122
f = any(VariableCapture::CapturedVariable v).getACapturingScope()
123-
} or
124-
/** A synthetic node representing the heap of a function. Used for variable capture. */
125-
TSynthCapturingClosureArgumentNode(CallNode callNode)
123+
}
126124

127125
private import semmle.python.internal.CachedStages
128126

python/ql/lib/semmle/python/dataflow/new/internal/VariableCapture.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,8 @@ private module Debug {
188188
Flow::localFlowStep(closureNodeFrom, closureNodeTo) and
189189
not flowValueStep(_, closureNodeFrom, closureNodeTo, _)
190190
}
191+
192+
predicate unmappedFlowClosureNode(Flow::ClosureNode closureNode) {
193+
not exists(Node node | closureNode = asClosureNode(node))
194+
}
191195
}

0 commit comments

Comments
 (0)