Skip to content

Commit fa2da2f

Browse files
committed
Python: remove NonLibraryNormalCall
it is not necessary to distinguish these calls, so we remove the class from the hierarchy.
1 parent 895f548 commit fa2da2f

File tree

3 files changed

+27
-41
lines changed

3 files changed

+27
-41
lines changed

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

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ module ArgumentPassing {
103103
* Used to limit the size of predicates.
104104
*/
105105
predicate connects(CallNode call, CallableValue callable) {
106-
exists(NonLibraryNormalCall c, NonLibraryDataFlowCallable k |
106+
exists(NormalCall c, NonLibraryDataFlowCallable k |
107107
call = c.getNode() and
108108
callable = k.getCallableValue() and
109-
k = c.getNonLibraryCallable()
109+
k = c.getCallable()
110110
)
111111
}
112112

@@ -511,81 +511,64 @@ class NormalCall extends DataFlowSourceCall, TNormalCall {
511511

512512
abstract override Node getArg(int n);
513513

514-
override ControlFlowNode getNode() { result = call }
514+
override CallNode getNode() { result = call }
515515

516516
abstract override DataFlowCallable getCallable();
517517

518518
override DataFlowCallable getEnclosingCallable() { result.getScope() = call.getNode().getScope() }
519519
}
520520

521-
/** A (non-special) call that does not go to a library callable. */
522-
abstract class NonLibraryNormalCall extends NormalCall {
523-
abstract Node getNonLibraryArg(int n);
524-
525-
final override Node getArg(int n) { result = this.getNonLibraryArg(n) }
526-
527-
abstract DataFlowCallable getNonLibraryCallable();
528-
529-
final override DataFlowCallable getCallable() { result = this.getNonLibraryCallable() }
530-
}
531-
532521
/**
533522
* A call to a function.
534523
* This excludes calls to bound methods, classes, and special methods.
535524
* Bound method calls and class calls insert an argument for the explicit
536525
* `self` parameter, and special method calls have special argument passing.
537526
*/
538-
class FunctionCall extends NonLibraryNormalCall {
527+
class FunctionCall extends NormalCall {
539528
NonLibraryDataFlowCallable callable;
540529

541530
FunctionCall() {
542531
call = any(FunctionValue f).getAFunctionCall() and
543532
call = callable.getACall()
544533
}
545534

546-
override Node getNonLibraryArg(int n) {
547-
result = getArg(call, TNoShift(), callable.getCallableValue(), n)
548-
}
535+
override Node getArg(int n) { result = getArg(call, TNoShift(), callable.getCallableValue(), n) }
549536

550-
override DataFlowCallable getNonLibraryCallable() { result = callable }
537+
override DataFlowCallable getCallable() { result = callable }
551538
}
552539

553540
/** A call to a lambda. */
554-
class LambdaCall extends NonLibraryNormalCall {
541+
class LambdaCall extends NormalCall {
555542
NonLibraryDataFlowCallable callable;
556543

557544
LambdaCall() {
558545
call = callable.getACall() and
559546
callable = TLambda(any(Function f))
560547
}
561548

562-
override Node getNonLibraryArg(int n) {
563-
result = getArg(call, TNoShift(), callable.getCallableValue(), n)
564-
}
549+
override Node getArg(int n) { result = getArg(call, TNoShift(), callable.getCallableValue(), n) }
565550

566-
override DataFlowCallable getNonLibraryCallable() { result = callable }
551+
override DataFlowCallable getCallable() { result = callable }
567552
}
568553

569554
/**
570555
* Represents a call to a bound method call.
571556
* The node representing the instance is inserted as argument to the `self` parameter.
572557
*/
573-
class MethodCall extends NonLibraryNormalCall {
558+
class MethodCall extends NormalCall {
574559
FunctionValue bm;
575560

576561
MethodCall() { call = bm.getAMethodCall() }
577562

578563
private CallableValue getCallableValue() { result = bm }
579564

580-
override Node getNonLibraryArg(int n) {
565+
override Node getArg(int n) {
581566
n > 0 and result = getArg(call, TShiftOneUp(), this.getCallableValue(), n)
582567
or
583568
n = 0 and result = TCfgNode(call.getFunction().(AttrNode).getObject())
584569
}
585570

586-
override DataFlowCallable getNonLibraryCallable() {
587-
result = TCallableValue(this.getCallableValue())
588-
}
571+
override DataFlowCallable getCallable() { result = TCallableValue(this.getCallableValue()) }
589572
}
590573

591574
/**
@@ -594,7 +577,7 @@ class MethodCall extends NonLibraryNormalCall {
594577
* That makes the call node be the post-update node holding the value of the object
595578
* after the constructor has run.
596579
*/
597-
class ClassCall extends NonLibraryNormalCall {
580+
class ClassCall extends NormalCall {
598581
ClassValue c;
599582

600583
ClassCall() {
@@ -604,15 +587,13 @@ class ClassCall extends NonLibraryNormalCall {
604587

605588
private CallableValue getCallableValue() { c.getScope().getInitMethod() = result.getScope() }
606589

607-
override Node getNonLibraryArg(int n) {
590+
override Node getArg(int n) {
608591
n > 0 and result = getArg(call, TShiftOneUp(), this.getCallableValue(), n)
609592
or
610593
n = 0 and result = TSyntheticPreUpdateNode(TCfgNode(call))
611594
}
612595

613-
override DataFlowCallable getNonLibraryCallable() {
614-
result = TCallableValue(this.getCallableValue())
615-
}
596+
override DataFlowCallable getCallable() { result = TCallableValue(this.getCallableValue()) }
616597
}
617598

618599
/** A call to a special method. */

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,15 +137,15 @@ module SyntheticPostUpdateNode {
137137
* and should not have an extra node synthesised.
138138
*/
139139
Node argumentPreUpdateNode() {
140-
result = any(FunctionCall c).getNonLibraryArg(_)
140+
result = any(FunctionCall c).getArg(_)
141141
or
142142
// Avoid argument 0 of method calls as those have read post-update nodes.
143-
exists(MethodCall c, int n | n > 0 | result = c.getNonLibraryArg(n))
143+
exists(MethodCall c, int n | n > 0 | result = c.getArg(n))
144144
or
145145
result = any(SpecialCall c).getArg(_)
146146
or
147147
// Avoid argument 0 of class calls as those have non-synthetic post-update nodes.
148-
exists(ClassCall c, int n | n > 0 | result = c.getNonLibraryArg(n))
148+
exists(ClassCall c, int n | n > 0 | result = c.getArg(n))
149149
or
150150
// any argument of any call that we have not been able to resolve
151151
exists(CallNode call | not resolvedCall(call) |

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,20 @@
1111
* These are identified by strings and has predicates for finding calls to them.
1212
*
1313
* Having both extracted and non-extracted callables means that we now have three types of calls:
14-
* - Extracted calls to extracted callables, either `NonLibraryNormalCall` or `SpecialCall`. These are handled by standard data flow.
15-
* - Extracted calls to non-extracted callables, `LibraryCall`. These are handled by summaries.
14+
* - Extracted calls to extracted callables, either `NormalCall` or `SpecialCall`. These are handled by standard data flow.
15+
* - Extracted calls to non-extracted callables, `LibraryCall`. These are handled by loking up the relevant summary when the
16+
* global data flwo graph is connected up via `getViableCallable`.
1617
* - Non-extracted calls, `SummaryCall`. These are synthesised by the flow summary framework.
1718
*
18-
* The first two can be referred to as `DataFlowSourceCall`. They have been split up for the benefit of call resolutiuon.
19+
* The first two can be referred to as `DataFlowSourceCall`. In fact, `LibraryCall` is a subclass of `NormalCall`, where
20+
* `getCallable` is set to `none()`. The member predicate `DataFlowSourceCall::getCallable` is _not_ the mechanism for
21+
* call resolution in global data flow. That mechanism is `getViableCallable`.
1922
* Resolving a call to a non-extracted callable goes via `LibraryCallable::getACall`, which may involve type tracking.
2023
* To avoid that type tracking becomes mutualy recursive with data flow, type tracking must use a call graph not including summaries.
24+
* Type tracking sees the callgraph given by `DataFlowSourceCall::getACallable`.
2125
*
22-
* We do not support summaries of special methods.
26+
* We do not support summaries of special methods via the special methods framework,
27+
* the summary would have to identify the call.
2328
*/
2429

2530
private import python

0 commit comments

Comments
 (0)