@@ -37,6 +37,7 @@ private import DataFlowPublic
3737private import DataFlowPrivate
3838private import FlowSummaryImpl as FlowSummaryImpl
3939private import FlowSummaryImplSpecific as FlowSummaryImplSpecific
40+ private import semmle.python.internal.CachedStages
4041
4142newtype TParameterPosition =
4243 /** Used for `self` in methods, and `cls` in classmethods. */
@@ -1041,20 +1042,23 @@ predicate resolveClassInstanceCall(CallNode call, Function target, Node self) {
10411042 */
10421043cached
10431044predicate resolveCall ( ControlFlowNode call , Function target , CallType type ) {
1044- type instanceof CallTypePlainFunction and
1045- call .( CallNode ) .getFunction ( ) = functionTracker ( target ) .asCfgNode ( ) and
1046- not exists ( Class cls | cls .getAMethod ( ) = target )
1047- or
1048- resolveMethodCall ( call , target , type , _)
1049- or
1050- type instanceof CallTypeClass and
1051- exists ( Class cls |
1052- resolveClassCall ( call , cls ) and
1053- target = invokedFunctionFromClassConstruction ( cls , _)
1045+ Stages:: DataFlow:: ref ( ) and
1046+ (
1047+ type instanceof CallTypePlainFunction and
1048+ call .( CallNode ) .getFunction ( ) = functionTracker ( target ) .asCfgNode ( ) and
1049+ not exists ( Class cls | cls .getAMethod ( ) = target )
1050+ or
1051+ resolveMethodCall ( call , target , type , _)
1052+ or
1053+ type instanceof CallTypeClass and
1054+ exists ( Class cls |
1055+ resolveClassCall ( call , cls ) and
1056+ target = invokedFunctionFromClassConstruction ( cls , _)
1057+ )
1058+ or
1059+ type instanceof CallTypeClassInstanceCall and
1060+ resolveClassInstanceCall ( call , target , _)
10541061 )
1055- or
1056- type instanceof CallTypeClassInstanceCall and
1057- resolveClassInstanceCall ( call , target , _)
10581062}
10591063
10601064// =============================================================================
@@ -1119,77 +1123,80 @@ cached
11191123predicate getCallArg (
11201124 ControlFlowNode call , Function target , CallType type , Node arg , ArgumentPosition apos
11211125) {
1122- // normal calls with a real call node
1123- resolveCall ( call , target , type ) and
1124- call instanceof CallNode and
1126+ Stages:: DataFlow:: ref ( ) and
11251127 (
1126- type instanceof CallTypePlainFunction and
1127- normalCallArg ( call , arg , apos )
1128- or
1129- // self argument for normal method calls
1130- type instanceof CallTypeNormalMethod and
1131- apos .isSelf ( ) and
1132- resolveMethodCall ( call , target , type , arg ) and
1133- // dataflow lib has requirement that arguments and calls are in same enclosing callable.
1134- exists ( CfgNode cfgNode | cfgNode .getNode ( ) = call |
1135- cfgNode .getEnclosingCallable ( ) = arg .getEnclosingCallable ( )
1136- )
1137- or
1138- // cls argument for classmethod calls
1139- type instanceof CallTypeClassMethod and
1140- apos .isSelf ( ) and
1141- resolveMethodCall ( call , target , type , arg ) and
1142- ( arg = classTracker ( _) or arg = clsTracker ( _) ) and
1143- // dataflow lib has requirement that arguments and calls are in same enclosing callable.
1144- exists ( CfgNode cfgNode | cfgNode .getNode ( ) = call |
1145- cfgNode .getEnclosingCallable ( ) = arg .getEnclosingCallable ( )
1146- )
1147- or
1148- // normal arguments for method calls
1149- (
1150- type instanceof CallTypeNormalMethod or
1151- type instanceof CallTypeStaticMethod or
1152- type instanceof CallTypeClassMethod
1153- ) and
1154- normalCallArg ( call , arg , apos )
1155- or
1156- // method as plain function call.
1157- //
1158- // argument index 0 of call has position self (and MUST be given as positional
1159- // argument in call). This also means that call-arguments are shifted by 1, such
1160- // that argument index 1 of call has argument position 0
1161- type instanceof CallTypeMethodAsPlainFunction and
1128+ // normal calls with a real call node
1129+ resolveCall ( call , target , type ) and
1130+ call instanceof CallNode and
11621131 (
1163- apos .isSelf ( ) and arg .asCfgNode ( ) = call .( CallNode ) .getArg ( 0 )
1164- or
1165- not apos .isPositional ( _) and normalCallArg ( call , arg , apos )
1132+ type instanceof CallTypePlainFunction and
1133+ normalCallArg ( call , arg , apos )
11661134 or
1167- exists ( ArgumentPosition normalPos , int index |
1168- apos .isPositional ( index - 1 ) and
1169- normalPos .isPositional ( index ) and
1170- normalCallArg ( call , arg , normalPos )
1171- )
1172- )
1173- or
1174- // class call
1175- type instanceof CallTypeClass and
1176- (
1177- // only pass synthetic node for created object to __init__, and not __new__ since
1178- // __new__ is a classmethod.
1179- target = invokedFunctionFromClassConstruction ( _, "__init__" ) and
1135+ // self argument for normal method calls
1136+ type instanceof CallTypeNormalMethod and
11801137 apos .isSelf ( ) and
1181- arg = TSyntheticPreUpdateNode ( call )
1138+ resolveMethodCall ( call , target , type , arg ) and
1139+ // dataflow lib has requirement that arguments and calls are in same enclosing callable.
1140+ exists ( CfgNode cfgNode | cfgNode .getNode ( ) = call |
1141+ cfgNode .getEnclosingCallable ( ) = arg .getEnclosingCallable ( )
1142+ )
11821143 or
1183- normalCallArg ( call , arg , apos )
1184- )
1185- or
1186- // call on class instance, which goes to `__call__` method
1187- type instanceof CallTypeClassInstanceCall and
1188- (
1144+ // cls argument for classmethod calls
1145+ type instanceof CallTypeClassMethod and
11891146 apos .isSelf ( ) and
1190- resolveClassInstanceCall ( call , target , arg )
1147+ resolveMethodCall ( call , target , type , arg ) and
1148+ ( arg = classTracker ( _) or arg = clsTracker ( _) ) and
1149+ // dataflow lib has requirement that arguments and calls are in same enclosing callable.
1150+ exists ( CfgNode cfgNode | cfgNode .getNode ( ) = call |
1151+ cfgNode .getEnclosingCallable ( ) = arg .getEnclosingCallable ( )
1152+ )
11911153 or
1154+ // normal arguments for method calls
1155+ (
1156+ type instanceof CallTypeNormalMethod or
1157+ type instanceof CallTypeStaticMethod or
1158+ type instanceof CallTypeClassMethod
1159+ ) and
11921160 normalCallArg ( call , arg , apos )
1161+ or
1162+ // method as plain function call.
1163+ //
1164+ // argument index 0 of call has position self (and MUST be given as positional
1165+ // argument in call). This also means that call-arguments are shifted by 1, such
1166+ // that argument index 1 of call has argument position 0
1167+ type instanceof CallTypeMethodAsPlainFunction and
1168+ (
1169+ apos .isSelf ( ) and arg .asCfgNode ( ) = call .( CallNode ) .getArg ( 0 )
1170+ or
1171+ not apos .isPositional ( _) and normalCallArg ( call , arg , apos )
1172+ or
1173+ exists ( ArgumentPosition normalPos , int index |
1174+ apos .isPositional ( index - 1 ) and
1175+ normalPos .isPositional ( index ) and
1176+ normalCallArg ( call , arg , normalPos )
1177+ )
1178+ )
1179+ or
1180+ // class call
1181+ type instanceof CallTypeClass and
1182+ (
1183+ // only pass synthetic node for created object to __init__, and not __new__ since
1184+ // __new__ is a classmethod.
1185+ target = invokedFunctionFromClassConstruction ( _, "__init__" ) and
1186+ apos .isSelf ( ) and
1187+ arg = TSyntheticPreUpdateNode ( call )
1188+ or
1189+ normalCallArg ( call , arg , apos )
1190+ )
1191+ or
1192+ // call on class instance, which goes to `__call__` method
1193+ type instanceof CallTypeClassInstanceCall and
1194+ (
1195+ apos .isSelf ( ) and
1196+ resolveClassInstanceCall ( call , target , arg )
1197+ or
1198+ normalCallArg ( call , arg , apos )
1199+ )
11931200 )
11941201 )
11951202}
0 commit comments