@@ -187,6 +187,18 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
187187 )
188188 }
189189
190+ /**
191+ * Holds if `arg` is an argument of `call` with an argument position that matches
192+ * parameter position `ppos`.
193+ */
194+ pragma [ noinline]
195+ private predicate argumentPositionMatchEx ( DataFlowCall call , ArgNodeEx arg , ParameterPosition ppos ) {
196+ exists ( ArgumentPosition apos |
197+ arg .argumentOf ( call , apos ) and
198+ parameterMatch ( ppos , apos )
199+ )
200+ }
201+
190202 pragma [ nomagic]
191203 private predicate hasSimpleReturnKindIn ( ReturnNode ret , ReturnKind kind , DataFlowCallable c ) {
192204 c = getNodeEnclosingCallable ( ret ) and
@@ -219,7 +231,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
219231
220232 pragma [ noinline]
221233 private predicate viableParamNonLambda ( DataFlowCall call , ParameterPosition ppos , ParamNode p ) {
222- p .isParameterOf ( viableCallable ( call ) , ppos )
234+ p .isParameterOf ( viableCallableCached ( call ) , ppos )
223235 }
224236
225237 pragma [ noinline]
@@ -259,7 +271,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
259271
260272 pragma [ nomagic]
261273 private TReturnPositionSimple viableReturnPosNonLambda ( DataFlowCall call , ReturnKind kind ) {
262- result = TReturnPositionSimple0 ( viableCallable ( call ) , kind )
274+ result = TReturnPositionSimple0 ( viableCallableCached ( call ) , kind )
263275 }
264276
265277 pragma [ nomagic]
@@ -881,9 +893,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
881893 or
882894 result = this .asLambdaInstancePostUpdateNode ( ) .toString ( ) + " [LambdaPostUpdate]"
883895 or
884- exists ( DataFlowCall synthcall , ArgumentPosition apos , boolean isPost |
885- this .isLambdaArgNode ( synthcall , apos , isPost ) |
886- result = synthcall .toString ( ) + "-" + apos .toString ( ) + "-" + isPost .toString ( ) + " [LambdaArg]"
896+ exists ( DataFlowCall synthcall , ArgumentPosition apos , boolean isPost |
897+ this .isLambdaArgNode ( synthcall , apos , isPost )
898+ |
899+ result =
900+ synthcall .toString ( ) + "-" + apos .toString ( ) + "-" + isPost .toString ( ) + " [LambdaArg]"
887901 )
888902 }
889903
@@ -962,9 +976,29 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
962976 }
963977
964978 final class ArgNodeEx extends NodeEx {
965- ArgNodeEx ( ) { this .asNode ( ) instanceof ArgNode }
979+ private DataFlowCall call_ ;
980+ private ArgumentPosition pos_ ;
981+
982+ ArgNodeEx ( ) {
983+ this .asNode ( ) .( ArgNode ) .argumentOf ( call_ , pos_ )
984+ or
985+ this .isLambdaArgNode ( call_ , pos_ , false )
986+ or
987+ exists ( Node lambda , DataFlowCallable c , ParameterNode p , ParameterPosition ppos |
988+ lambda = this .asLambdaMallocNode ( ) and
989+ lambdaCreation ( lambda , _, c , call_ ) and
990+ isParameterNode ( p , c , ppos ) and
991+ isLambdaInstanceParameter ( p ) and
992+ parameterMatch ( ppos , pos_ )
993+ )
994+ }
995+
996+ final DataFlowCall getCall ( ) { this .argumentOf ( result , _) }
966997
967- DataFlowCall getCall ( ) { this .asNode ( ) .( ArgNode ) .argumentOf ( result , _) }
998+ final predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
999+ call = call_ and
1000+ pos = pos_
1001+ }
9681002 }
9691003
9701004 final class ParamNodeEx extends NodeEx {
@@ -991,6 +1025,14 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
9911025 ReturnKindExt getKind ( ) { result = pos .getKind ( ) }
9921026 }
9931027
1028+ final class OutNodeEx extends NodeEx {
1029+ OutNodeEx ( ) {
1030+ this .asNode ( ) instanceof OutNodeExt
1031+ or
1032+ this .( PostUpdateNodeEx ) .getPreUpdateNode ( ) instanceof ArgNodeEx
1033+ }
1034+ }
1035+
9941036 class PostUpdateNodeEx extends NodeEx {
9951037 private NodeEx pre ;
9961038
@@ -1075,7 +1117,10 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
10751117 }
10761118
10771119 cached
1078- predicate hiddenNode ( Node n ) { nodeIsHidden ( n ) }
1120+ predicate hiddenNode ( Node n ) {
1121+ // todo: add all lambda nodes here after end debugging
1122+ nodeIsHidden ( n )
1123+ }
10791124
10801125 cached
10811126 OutNodeExt getAnOutNodeExt ( DataFlowCall call , ReturnKindExt k ) {
@@ -1087,6 +1132,16 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
10871132 )
10881133 }
10891134
1135+ cached
1136+ OutNodeEx getAnOutNodeEx ( DataFlowCall call , ReturnKindExt k ) {
1137+ result .asNode ( ) = getAnOutNodeExt ( call , k )
1138+ or
1139+ exists ( ArgNodeEx arg |
1140+ result .( PostUpdateNodeEx ) .getPreUpdateNode ( ) = arg and
1141+ arg .argumentOf ( call , k .( ParamUpdateReturnKind ) .getAMatchingArgumentPosition ( ) )
1142+ )
1143+ }
1144+
10901145 pragma [ nomagic]
10911146 private predicate paramReturnNode (
10921147 PostUpdateNodeEx n , ParamNode p , SndLevelScopeOption scope , ReturnKindExt k
@@ -1145,7 +1200,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
11451200 }
11461201
11471202 cached
1148- DataFlowCallable viableCallableCached ( DataFlowCall call ) { result = viableCallable ( call ) }
1203+ DataFlowCallable viableCallableCached ( DataFlowCall call ) {
1204+ result = viableCallable ( call )
1205+ or
1206+ lambdaCreation ( _, _, result , call )
1207+ }
11491208
11501209 /*
11511210 * foo(x => sink(x), notaint)
@@ -1260,7 +1319,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
12601319 cached
12611320 DataFlowCallable viableImplInCallContextExt ( DataFlowCall call , DataFlowCall ctx ) {
12621321 result = viableImplInCallContext ( call , ctx ) and
1263- result = viableCallable ( call )
1322+ result = viableCallableCached ( call )
12641323 or
12651324 result = viableCallableLambda ( call , TDataFlowCallSome ( ctx ) )
12661325 or
@@ -1407,23 +1466,29 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
14071466 cached
14081467 predicate viableReturnPosOutEx ( DataFlowCall call , ReturnPosition pos , NodeEx out ) {
14091468 viableReturnPosOut ( call , pos , out .asNode ( ) )
1469+ or
1470+ exists ( ReturnKindExt kind |
1471+ pos = viableReturnPos ( call , kind ) and
1472+ out = kind .getAnOutNodeEx ( call )
1473+ )
14101474 }
14111475
1412- cached
1413- predicate viableParamArgEx ( DataFlowCall call , ParamNodeEx p , ArgNodeEx arg ) {
1414- viableParamArg ( call , p .asNode ( ) , arg .asNode ( ) )
1476+ bindingset [ call , p , arg ]
1477+ private predicate golangSpecificParamArgFilterEx ( DataFlowCall call , ParamNodeEx p , ArgNodeEx arg ) {
1478+ golangSpecificParamArgFilter ( call , p .asNode ( ) , arg .asNode ( ) )
14151479 or
1416- exists ( ArgumentPosition apos , DataFlowCallable c , ParameterPosition ppos |
1417- arg .isLambdaArgNode ( call , apos , false ) and
1418- lambdaCreation ( _, _, c , call ) and
1419- p .isParameterOf ( c , ppos ) and
1420- parameterMatch ( ppos , apos )
1421- )
1480+ not p .asNode ( ) instanceof ParamNode
14221481 or
1423- exists ( DataFlowCallable c |
1424- isLambdaInstanceParameter ( p .asNode ( ) ) and
1425- lambdaCreation ( arg .asLambdaMallocNode ( ) , _, c , call ) and
1426- p .isParameterOf ( c , _)
1482+ not arg .asNode ( ) instanceof ArgNode
1483+ }
1484+
1485+ cached
1486+ predicate viableParamArgEx ( DataFlowCall call , ParamNodeEx p , ArgNodeEx arg ) {
1487+ exists ( ParameterPosition ppos |
1488+ viableParam ( call , ppos , p .asNode ( ) ) and
1489+ argumentPositionMatchEx ( call , arg , ppos ) and
1490+ compatibleTypesFilter ( arg .getDataFlowType ( ) , p .getDataFlowType ( ) ) and
1491+ golangSpecificParamArgFilterEx ( call , p , arg )
14271492 )
14281493 }
14291494
@@ -1969,6 +2034,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
19692034 exists ( DataFlowCallable c , ParameterNode p , ParameterPosition ppos |
19702035 lambdaCreation ( _, _, c , synthcall ) and
19712036 isParameterNode ( p , c , ppos ) and
2037+ not isLambdaInstanceParameter ( p ) and
19722038 parameterMatch ( ppos , apos ) and
19732039 exists ( ispost )
19742040 )
@@ -2549,6 +2615,9 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
25492615
25502616 /** Gets a node corresponding to data flow out of `call`. */
25512617 final OutNodeExt getAnOutNode ( DataFlowCall call ) { result = getAnOutNodeExt ( call , this ) }
2618+
2619+ /** Gets a node corresponding to data flow out of `call`. */
2620+ final OutNodeEx getAnOutNodeEx ( DataFlowCall call ) { result = getAnOutNodeEx ( call , this ) }
25522621 }
25532622
25542623 class ValueReturnKind extends ReturnKindExt , TValueReturn {
0 commit comments