@@ -1560,7 +1560,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
15601560 argT = TypOption:: some ( t ) and
15611561 argAp = apSome ( ap )
15621562 ) else (
1563- summaryCtx = TParamNodeNone ( ) and argT instanceof TypOption:: None and argAp = apNone ( )
1563+ summaryCtx = TParamNodeNone ( ) and
1564+ argT instanceof TypOption:: None and
1565+ argAp = apNone ( ) and
1566+ // When the call contexts of source and sink needs to match then there's
1567+ // never any reason to enter a callable except to find a summary. See also
1568+ // the comment in `PathNodeMid::isAtSink`.
1569+ not Config:: getAFeature ( ) instanceof FeatureEqualSourceSinkCallContext
15641570 )
15651571 )
15661572 or
@@ -2598,8 +2604,23 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
25982604
25992605 override predicate isSink ( ) {
26002606 sinkNode ( node , state ) and
2601- ( if hasSinkCallCtx ( ) then instanceofCcNoCall ( cc ) else any ( ) ) and
2602- ap instanceof ApNil
2607+ ap instanceof ApNil and
2608+ // For `FeatureHasSinkCallContext` the condition `cc instanceof CallContextNoCall`
2609+ // is exactly what we need to check.
2610+ // For `FeatureEqualSourceSinkCallContext` the initial call
2611+ // context was set to `CallContextSomeCall` and jumps are
2612+ // disallowed, so `cc instanceof CallContextNoCall` never holds.
2613+ // On the other hand, in this case there's never any need to
2614+ // enter a call except to identify a summary, so the condition in
2615+ // conjunction with setting the summary context enforces this,
2616+ // which means that the summary context being empty holds if and
2617+ // only if we are in the call context of the source.
2618+ if Config:: getAFeature ( ) instanceof FeatureEqualSourceSinkCallContext
2619+ then summaryCtx = TParamNodeNone ( )
2620+ else
2621+ if Config:: getAFeature ( ) instanceof FeatureHasSinkCallContext
2622+ then instanceofCcNoCall ( cc )
2623+ else any ( )
26032624 }
26042625 }
26052626
@@ -4320,21 +4341,21 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
43204341 sinkNode ( node , state ) and
43214342 sinkModel ( node , model ) and
43224343 ap instanceof AccessPathNil and
4323- if hasSinkCallCtx ( )
4324- then
4325- // For `FeatureHasSinkCallContext ` the condition `cc instanceof CallContextNoCall`
4326- // is exactly what we need to check. This also implies
4327- // `sc instanceof SummaryCtxNone`.
4328- // For `FeatureEqualSourceSinkCallContext` the initial call context was
4329- // set to `CallContextSomeCall` and jumps are disallowed, so
4330- // `cc instanceof CallContextNoCall` never holds. On the other hand,
4331- // in this case there's never any need to enter a call except to identify
4332- // a summary, so the condition in `pathIntoCallable` enforces this, which
4333- // means that ` sc instanceof SummaryCtxNone` holds if and only if we are
4334- // in the call context of the source.
4335- sc instanceof SummaryCtxNone or
4336- cc instanceof CallContextNoCall
4337- else any ( )
4344+ // For `FeatureHasSinkCallContext` the condition `cc instanceof CallContextNoCall`
4345+ // is exactly what we need to check.
4346+ // For `FeatureEqualSourceSinkCallContext ` the initial call context was
4347+ // set to `CallContextSomeCall` and jumps are disallowed, so
4348+ // `cc instanceof CallContextNoCall` never holds. On the other hand,
4349+ // in this case there's never any need to enter a call except to identify
4350+ // a summary, so the condition in `pathIntoCallable` enforces this, which
4351+ // means that `sc instanceof SummaryCtxNone` holds if and only if we are
4352+ // in the call context of the source.
4353+ if Config :: getAFeature ( ) instanceof FeatureEqualSourceSinkCallContext
4354+ then sc instanceof SummaryCtxNone
4355+ else
4356+ if Config :: getAFeature ( ) instanceof FeatureHasSinkCallContext
4357+ then cc instanceof CallContextNoCall
4358+ else any ( )
43384359 }
43394360
43404361 PathNodeSink projectToSink ( string model ) {
0 commit comments