@@ -146,13 +146,24 @@ private module Cached {
146146
147147import Cached
148148
149- private DataFlow:: SourceNode forwardedCalleeSource (
150- DataFlow:: CallNode call , DataFlow:: TypeBackTracker t
149+ /** Gets a value referring to a forwarding-wrapper around `func`. */
150+ private DataFlow:: SourceNode trackWrappedFunction (
151+ DataFlow:: FunctionNode func , DataFlow:: TypeTracker t
151152) {
152153 t .start ( ) and
153- result = call .getCalleeNode ( ) .getALocalSource ( )
154+ functionOneWayForwardingStep ( func , result ) and
155+ // Exclude functions since ordinary call edges can handle that case.
156+ // This will typically match calls to a "wrapper factory".
157+ not result instanceof DataFlow:: FunctionNode
154158 or
155- exists ( DataFlow:: TypeBackTracker t2 | result = forwardedCalleeSource ( call , t2 ) .backtrack ( t2 , t ) )
159+ functionOneWayForwardingStep ( trackWrappedFunction ( func , t .continue ( ) ) , result )
160+ or
161+ exists ( DataFlow:: TypeTracker t2 | result = trackWrappedFunction ( func , t2 ) .track ( t2 , t ) )
162+ }
163+
164+ /** Gets a value referring to a forwarding-wrapper around `func`. */
165+ DataFlow:: SourceNode trackWrappedFunction ( DataFlow:: SourceNode func ) {
166+ result = trackWrappedFunction ( func , DataFlow:: TypeTracker:: end ( ) )
156167}
157168
158169/**
@@ -165,10 +176,7 @@ private class FunctionWrapperCallStep extends DataFlow::SharedFlowStep {
165176 DataFlow:: CallNode call ;
166177 DataFlow:: FunctionNode wrapped ;
167178
168- FunctionWrapperCallStep ( ) {
169- DataFlow:: functionOneWayForwardingStep ( wrapped ,
170- forwardedCalleeSource ( call , DataFlow:: TypeBackTracker:: end ( ) ) )
171- }
179+ FunctionWrapperCallStep ( ) { call = trackWrappedFunction ( wrapped ) .getACall ( ) }
172180
173181 override predicate step ( DataFlow:: Node pred , DataFlow:: Node succ ) {
174182 exists ( int index |
0 commit comments