Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d3e0e84

Browse files
committed
Python: Separate callable for lambdas
Since lambdas are split, but their children are not, we use the Function as the callable.
1 parent 4526a1d commit d3e0e84

2 files changed

Lines changed: 25 additions & 6 deletions

File tree

python/ql/src/semmle/python/dataflow/new/internal/DataFlowPrivate.qll

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,13 @@ import ArgumentPassing
498498
*/
499499
newtype TDataFlowCallable =
500500
TCallableValue(CallableValue callable) {
501-
callable instanceof FunctionValue
501+
callable instanceof FunctionValue and
502+
// TODO: push into FunctionValue
503+
not callable.(FunctionValue).getOrigin().getNode() instanceof Lambda
502504
or
503505
callable instanceof ClassValue
504506
} or
507+
TLambda(Function lambda) { lambda.getName() = "lambda" } or
505508
TModule(Module m)
506509

507510
/** Represents a callable. */
@@ -544,6 +547,27 @@ class DataFlowCallableValue extends DataFlowCallable, TCallableValue {
544547
override CallableValue getCallableValue() { result = callable }
545548
}
546549

550+
/** A class representing a callable lambda. */
551+
class DataFlowLambda extends DataFlowCallable, TLambda {
552+
Function lambda;
553+
554+
DataFlowLambda() { this = TLambda(lambda) }
555+
556+
override string toString() { result = lambda.toString() }
557+
558+
override CallNode getACall() { result = getCallableValue().getACall() }
559+
560+
override Scope getScope() { result = lambda.getEvaluatingScope() }
561+
562+
override NameNode getParameter(int n) { result = getParameter(getCallableValue(), n) }
563+
564+
override string getName() { result = "Lambda callable" }
565+
566+
override CallableValue getCallableValue() {
567+
result.(FunctionValue).getOrigin().getNode() = lambda.getDefinition()
568+
}
569+
}
570+
547571
/** A class representing the scope in which a `ModuleVariableNode` appears. */
548572
class DataFlowModuleScope extends DataFlowCallable, TModule {
549573
Module mod;

python/ql/test/experimental/dataflow/consistency/dataflow-consistency.expected

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
uniqueEnclosingCallable
2-
| test.py:256:18:256:18 | ControlFlowNode for x | Node should have one enclosing callable but has 2. |
3-
| test.py:256:18:256:18 | SSA variable x | Node should have one enclosing callable but has 2. |
4-
| test.py:256:21:256:25 | ControlFlowNode for False | Node should have one enclosing callable but has 2. |
52
uniqueType
63
uniqueNodeLocation
74
missingLocation
85
uniqueNodeToString
96
missingToString
107
parameterCallable
11-
| test.py:256:18:256:18 | ControlFlowNode for x | Callable mismatch for parameter. |
128
localFlowIsLocal
13-
| test.py:256:18:256:18 | ControlFlowNode for x | test.py:256:18:256:18 | SSA variable x | Local flow step does not preserve enclosing callable. |
149
compatibleTypesReflexive
1510
unreachableNodeCCtx
1611
localCallNodes

0 commit comments

Comments
 (0)