Python: fix dataflow inconsistencies

- adjust scope of argument, the argument is outside the called function
- add missing post-update nodes for the new arguments
This commit is contained in:
Rasmus Lerchedahl Petersen
2024-09-30 10:31:36 +02:00
parent d4ea62edec
commit 310819d392
3 changed files with 30 additions and 1 deletions

View File

@@ -1752,13 +1752,25 @@ class SynthCompCapturedVariablesArgumentNode extends Node, TSynthCompCapturedVar
override string toString() { result = "Capturing closure argument (comp)" }
override Scope getScope() { result = comp.getFunction() }
override Scope getScope() { result = comp.getScope() }
override Location getLocation() { result = comp.getLocation() }
Comp getComprehension() { result = comp }
}
class SynthCompCapturedVariablesArgumentPostUpdateNode extends PostUpdateNodeImpl,
TSynthCompCapturedVariablesArgumentPostUpdateNode
{
Comp comp;
SynthCompCapturedVariablesArgumentPostUpdateNode() {
this = TSynthCompCapturedVariablesArgumentPostUpdateNode(comp)
}
override Node getPreUpdateNode() { result = TSynthCompCapturedVariablesArgumentNode(comp) }
}
/** Gets a viable run-time target for the call `call`. */
DataFlowCallable viableCallable(DataFlowCall call) {
call instanceof ExtractedDataFlowCall and

View File

@@ -287,6 +287,12 @@ abstract class PostUpdateNodeImpl extends Node {
abstract Node getPreUpdateNode();
}
/**
* A post-update node synthesised for an existing control flow node.
* Add to `TSyntheticPostUpdateNode` to get the synthetic post-update node synthesised.
*
* Synthetic post-update nodes for synthetic nodes need to be listed one by one.
*/
class SyntheticPostUpdateNode extends PostUpdateNodeImpl, TSyntheticPostUpdateNode {
ControlFlowNode node;
@@ -301,6 +307,11 @@ class SyntheticPostUpdateNode extends PostUpdateNodeImpl, TSyntheticPostUpdateNo
override Location getLocation() { result = node.getLocation() }
}
/**
* An existsing control flow node being the post-update node of a synthetic pre-update node.
*
* Synthetic post-update nodes for synthetic nodes need to be listed one by one.
*/
class NonSyntheticPostUpdateNode extends PostUpdateNodeImpl, CfgNode {
SyntheticPreUpdateNode pre;

View File

@@ -71,6 +71,9 @@ newtype TNode =
def.getDefiningNode() = node and
def.getParameter() = func.getArg(0)
)
or
// the iterable argument to the implicit comprehension function
node.getNode() = any(Comp c).getIterable()
} or
/** A node representing a global (module-level) variable in a specific module. */
TModuleVariableNode(Module m, GlobalVariable v) {
@@ -129,6 +132,9 @@ newtype TNode =
TSynthCompCapturedVariablesArgumentNode(Comp comp) {
comp.getFunction() = any(VariableCapture::CapturedVariable v).getACapturingScope()
} or
TSynthCompCapturedVariablesArgumentPostUpdateNode(Comp comp) {
comp.getFunction() = any(VariableCapture::CapturedVariable v).getACapturingScope()
} or
/** An empty, unused node type that exists to prevent unwanted dependencies on data flow nodes. */
TForbiddenRecursionGuard() {
none() and