From 0f52fe92cf41f5a8d0e8ffb3193a1cef38e3a290 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 5 Feb 2025 10:11:46 +0100 Subject: [PATCH] Data flow: Add aliases for removing `DataFlow` prefixes --- .../dataflow/delegates/DelegateFlow.ql | 10 +- .../functionpointers/FunctionPointerFlow.ql | 6 +- .../codeql/dataflow/internal/DataFlowImpl.qll | 277 ++++----- .../dataflow/internal/DataFlowImplCommon.qll | 531 ++++++++---------- .../dataflow/internal/DataFlowImplStage1.qll | 255 ++++----- 5 files changed, 487 insertions(+), 592 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.ql b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.ql index 6ec7637bf6c..d97cf44f6c9 100644 --- a/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/delegates/DelegateFlow.ql @@ -4,19 +4,19 @@ import semmle.code.csharp.dataflow.internal.DataFlowDispatch query predicate delegateCall(DelegateLikeCall dc, Callable c) { c = dc.getARuntimeTarget() } -private class LocatableDataFlowCallOption extends DataFlowCallOption { +private class LocatableCallOption extends CallOption { Location getLocation() { - this = TDataFlowCallNone() and + this = TCallNone() and result instanceof EmptyLocation or exists(DataFlowCall call | - this = TDataFlowCallSome(call) and + this = TCallSome(call) and result = call.getLocation() ) } } -private class LocatableDataFlowCall extends TDataFlowCall { +private class LocatableCall extends TDataFlowCall { string toString() { result = this.(DataFlowCall).toString() } Location getLocation() { @@ -28,7 +28,7 @@ private class LocatableDataFlowCall extends TDataFlowCall { } query predicate viableLambda( - LocatableDataFlowCall call, LocatableDataFlowCallOption lastCall, DataFlowCallable target + LocatableCall call, LocatableCallOption lastCall, DataFlowCallable target ) { target = viableCallableLambda(call, lastCall) } diff --git a/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql index fced49bc9c6..21101cf94c9 100644 --- a/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql +++ b/csharp/ql/test/library-tests/dataflow/functionpointers/FunctionPointerFlow.ql @@ -4,13 +4,13 @@ import semmle.code.csharp.dataflow.internal.DataFlowDispatch query predicate fptrCall(FunctionPointerCall dc, Callable c) { c = dc.getARuntimeTarget() } -private class LocatableDataFlowCallOption extends DataFlowCallOption { +private class LocatableDataFlowCallOption extends CallOption { Location getLocation() { - this = TDataFlowCallNone() and + this = TCallNone() and result instanceof EmptyLocation or exists(DataFlowCall call | - this = TDataFlowCallSome(call) and + this = TCallSome(call) and result = call.getLocation() ) } diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index 6883b385284..a13c71f554c 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -17,6 +17,7 @@ module MakeImpl Lang> { private import MakeImplStage1 private import DataFlowImplCommon::MakeImplCommon private import DataFlowImplCommonPublic + private import Aliases /** * An input configuration for data flow using flow state. This signature equals @@ -236,7 +237,7 @@ module MakeImpl Lang> { } pragma[nomagic] - private predicate allowsFieldFlowThrough(DataFlowCall call, DataFlowCallable c) { + private predicate allowsFieldFlowThrough(Call call, Callable c) { Stage1::callEdgeReturn(call, c, _, _, _, true) } @@ -249,30 +250,25 @@ module MakeImpl Lang> { predicate revFlow(Nd node, Ap ap); - predicate callMayFlowThroughRev(DataFlowCall call); + predicate callMayFlowThroughRev(Call call); predicate parameterMayFlowThrough(ParamNd p, boolean emptyAp); predicate returnMayFlowThrough(RetNd ret, ReturnKindExt kind); - predicate storeStepCand( - Nd node1, Content c, Nd node2, DataFlowType contentType, DataFlowType containerType - ); + predicate storeStepCand(Nd node1, Content c, Nd node2, Type contentType, Type containerType); predicate readStepCand(Nd n1, Content c, Nd n2); - predicate callEdgeArgParam( - DataFlowCall call, DataFlowCallable c, ArgNd arg, ParamNd p, boolean emptyAp - ); + predicate callEdgeArgParam(Call call, Callable c, ArgNd arg, ParamNd p, boolean emptyAp); predicate callEdgeReturn( - DataFlowCall call, DataFlowCallable c, RetNd ret, ReturnKindExt kind, Nd out, - boolean allowsFieldFlow + Call call, Callable c, RetNd ret, ReturnKindExt kind, Nd out, boolean allowsFieldFlow ); - predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c); + predicate relevantCallEdgeIn(Call call, Callable c); - predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c); + predicate relevantCallEdgeOut(Call call, Callable c); } private module MkStage { @@ -292,7 +288,7 @@ module MakeImpl Lang> { bindingset[result, ap] ApApprox getApprox(Ap ap); - Typ getTyp(DataFlowType t); + Typ getTyp(Type t); bindingset[c, tail] Ap apCons(Content c, Ap tail); @@ -321,7 +317,7 @@ module MakeImpl Lang> { class CcCall extends Cc; // TODO: member predicate on CcCall - predicate matchesCall(CcCall cc, DataFlowCall call); + predicate matchesCall(CcCall cc, Call call); class CcNoCall extends Cc; @@ -343,20 +339,20 @@ module MakeImpl Lang> { class LocalCc; - DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CcCall ctx); + Callable viableImplCallContextReduced(Call call, CcCall ctx); bindingset[call, ctx] - predicate viableImplNotCallContextReduced(DataFlowCall call, Cc ctx); + predicate viableImplNotCallContextReduced(Call call, Cc ctx); bindingset[call, c] - CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c); + CcCall getCallContextCall(Call call, Callable c); - DataFlowCall viableImplCallContextReducedReverse(DataFlowCallable c, CcNoCall ctx); + Call viableImplCallContextReducedReverse(Callable c, CcNoCall ctx); predicate viableImplNotCallContextReducedReverse(CcNoCall ctx); bindingset[call, c] - CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call); + CcNoCall getCallContextReturn(Callable c, Call call); bindingset[cc] LocalCc getLocalCc(Cc cc); @@ -398,13 +394,11 @@ module MakeImpl Lang> { /* Begin: Stage logic. */ pragma[nomagic] private Typ getNodeTyp(Nd node) { - PrevStage::revFlow(node) and result = getTyp(node.getDataFlowType()) + PrevStage::revFlow(node) and result = getTyp(node.getType()) } pragma[nomagic] - private predicate flowThroughOutOfCall( - DataFlowCall call, RetNd ret, Nd out, boolean allowsFieldFlow - ) { + private predicate flowThroughOutOfCall(Call call, RetNd ret, Nd out, boolean allowsFieldFlow) { exists(ReturnKindExt kind | PrevStage::callEdgeReturn(call, _, ret, kind, out, allowsFieldFlow) and PrevStage::callMayFlowThroughRev(call) and @@ -413,8 +407,8 @@ module MakeImpl Lang> { } pragma[nomagic] - private predicate compatibleContainer0(ApHeadContent apc, DataFlowType containerType) { - exists(DataFlowType containerType0, Content c | + private predicate compatibleContainer0(ApHeadContent apc, Type containerType) { + exists(Type containerType0, Content c | PrevStage::storeStepCand(_, c, _, _, containerType0) and not topTypeContent(apc) and compatibleTypesCached(containerType0, containerType) and @@ -424,7 +418,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate topTypeContent(ApHeadContent apc) { - exists(DataFlowType containerType0, Content c | + exists(Type containerType0, Content c | PrevStage::storeStepCand(_, c, _, _, containerType0) and isTopType(containerType0) and apc = projectToHeadContent(c) @@ -433,7 +427,7 @@ module MakeImpl Lang> { bindingset[apc, containerType] pragma[inline_late] - private predicate compatibleContainer(ApHeadContent apc, DataFlowType containerType) { + private predicate compatibleContainer(ApHeadContent apc, Type containerType) { compatibleContainer0(apc, containerType) } @@ -462,7 +456,7 @@ module MakeImpl Lang> { if node instanceof CastingNd then ap instanceof ApNil or - compatibleContainer(getHeadContent(ap), node.getDataFlowType()) or + compatibleContainer(getHeadContent(ap), node.getType()) or topTypeContent(getHeadContent(ap)) else any() ) @@ -528,7 +522,7 @@ module MakeImpl Lang> { apa = getApprox(ap) or // flow through a callable - exists(DataFlowCall call, RetNd ret, boolean allowsFieldFlow | + exists(Call call, RetNd ret, boolean allowsFieldFlow | fwdFlowThrough(call, cc, summaryCtx, t, ap, stored, ret) and flowThroughOutOfCall(call, ret, node, allowsFieldFlow) and apa = getApprox(ap) and @@ -600,7 +594,7 @@ module MakeImpl Lang> { Nd node1, Typ t1, Ap ap1, TypOption stored1, Content c, Typ t2, TypOption stored2, Nd node2, Cc cc, SummaryCtx summaryCtx ) { - exists(DataFlowType contentType, DataFlowType containerType | + exists(Type contentType, Type containerType | fwdFlow(node1, cc, summaryCtx, t1, ap1, stored1) and PrevStage::storeStepCand(node1, c, node2, contentType, containerType) and t2 = getTyp(containerType) and @@ -690,7 +684,7 @@ module MakeImpl Lang> { private module FwdFlowIn { pragma[nomagic] private predicate callEdgeArgParamRestricted( - DataFlowCall call, DataFlowCallable c, ArgNd arg, ParamNd p, boolean emptyAp + Call call, Callable c, ArgNd arg, ParamNd p, boolean emptyAp ) { PrevStage::callEdgeArgParam(call, c, arg, p, emptyAp) and if @@ -706,26 +700,20 @@ module MakeImpl Lang> { } pragma[nomagic] - private DataFlowCallable viableImplCallContextReducedRestricted( - DataFlowCall call, CcCall ctx - ) { + private Callable viableImplCallContextReducedRestricted(Call call, CcCall ctx) { result = viableImplCallContextReduced(call, ctx) and callEdgeArgParamRestricted(call, result, _, _, _) } bindingset[call, ctx] pragma[inline_late] - private DataFlowCallable viableImplCallContextReducedInlineLate( - DataFlowCall call, CcCall ctx - ) { + private Callable viableImplCallContextReducedInlineLate(Call call, CcCall ctx) { result = viableImplCallContextReducedRestricted(call, ctx) } bindingset[arg, ctx] pragma[inline_late] - private DataFlowCallable viableImplCallContextReducedInlineLate( - DataFlowCall call, ArgNd arg, CcCall ctx - ) { + private Callable viableImplCallContextReducedInlineLate(Call call, ArgNd arg, CcCall ctx) { callEdgeArgParamRestricted(call, _, arg, _, _) and instanceofCcCall(ctx) and result = viableImplCallContextReducedInlineLate(call, ctx) @@ -734,23 +722,21 @@ module MakeImpl Lang> { bindingset[call] pragma[inline_late] private predicate callEdgeArgParamRestrictedInlineLate( - DataFlowCall call, DataFlowCallable c, ArgNd arg, ParamNd p, boolean emptyAp + Call call, Callable c, ArgNd arg, ParamNd p, boolean emptyAp ) { callEdgeArgParamRestricted(call, c, arg, p, emptyAp) } bindingset[call, ctx] pragma[inline_late] - private predicate viableImplNotCallContextReducedInlineLate(DataFlowCall call, Cc ctx) { + private predicate viableImplNotCallContextReducedInlineLate(Call call, Cc ctx) { instanceofCc(ctx) and viableImplNotCallContextReduced(call, ctx) } bindingset[arg, outercc] pragma[inline_late] - private predicate viableImplArgNotCallContextReduced( - DataFlowCall call, ArgNd arg, Cc outercc - ) { + private predicate viableImplArgNotCallContextReduced(Call call, ArgNd arg, Cc outercc) { callEdgeArgParamRestricted(call, _, arg, _, _) and instanceofCc(outercc) and viableImplNotCallContextReducedInlineLate(call, outercc) @@ -758,8 +744,8 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowInCand( - DataFlowCall call, ArgNd arg, Cc outercc, DataFlowCallable inner, ParamNd p, - SummaryCtx summaryCtx, Typ t, Ap ap, boolean emptyAp, TypOption stored, boolean cc + Call call, ArgNd arg, Cc outercc, Callable inner, ParamNd p, SummaryCtx summaryCtx, + Typ t, Ap ap, boolean emptyAp, TypOption stored, boolean cc ) { fwdFlowIntoArg(arg, outercc, summaryCtx, t, ap, emptyAp, stored, cc) and ( @@ -772,8 +758,8 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowInCandTypeFlowDisabled( - DataFlowCall call, ArgNd arg, Cc outercc, DataFlowCallable inner, ParamNd p, - SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, boolean cc + Call call, ArgNd arg, Cc outercc, Callable inner, ParamNd p, SummaryCtx summaryCtx, + Typ t, Ap ap, TypOption stored, boolean cc ) { not enableTypeFlow() and fwdFlowInCand(call, arg, outercc, inner, p, summaryCtx, t, ap, _, stored, cc) @@ -781,8 +767,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInCandTypeFlowEnabled( - DataFlowCall call, ArgNd arg, Cc outercc, DataFlowCallable inner, ParamNd p, - boolean emptyAp, boolean cc + Call call, ArgNd arg, Cc outercc, Callable inner, ParamNd p, boolean emptyAp, boolean cc ) { enableTypeFlow() and fwdFlowInCand(call, arg, outercc, inner, p, _, _, _, emptyAp, _, cc) @@ -790,7 +775,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInValidEdgeTypeFlowDisabled( - DataFlowCall call, DataFlowCallable inner, CcCall innercc, boolean cc + Call call, Callable inner, CcCall innercc, boolean cc ) { not enableTypeFlow() and FwdTypeFlow::typeFlowValidEdgeIn(call, inner, cc) and @@ -799,8 +784,8 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInValidEdgeTypeFlowEnabled( - DataFlowCall call, ArgNd arg, Cc outercc, DataFlowCallable inner, ParamNd p, - CcCall innercc, boolean emptyAp, boolean cc + Call call, ArgNd arg, Cc outercc, Callable inner, ParamNd p, CcCall innercc, + boolean emptyAp, boolean cc ) { fwdFlowInCandTypeFlowEnabled(call, arg, outercc, inner, p, emptyAp, cc) and FwdTypeFlow::typeFlowValidEdgeIn(call, inner, cc) and @@ -809,8 +794,8 @@ module MakeImpl Lang> { pragma[inline] predicate fwdFlowIn( - DataFlowCall call, ArgNd arg, DataFlowCallable inner, ParamNd p, Cc outercc, - CcCall innercc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, boolean cc + Call call, ArgNd arg, Callable inner, ParamNd p, Cc outercc, CcCall innercc, + SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, boolean cc ) { // type flow disabled: linear recursion fwdFlowInCandTypeFlowDisabled(call, arg, outercc, inner, p, summaryCtx, t, ap, stored, @@ -848,25 +833,21 @@ module MakeImpl Lang> { } pragma[nomagic] - private DataFlowCall viableImplCallContextReducedReverseRestricted( - DataFlowCallable c, CcNoCall ctx - ) { + private Call viableImplCallContextReducedReverseRestricted(Callable c, CcNoCall ctx) { result = viableImplCallContextReducedReverse(c, ctx) and PrevStage::callEdgeReturn(result, c, _, _, _, _) } bindingset[c, ctx] pragma[inline_late] - private DataFlowCall viableImplCallContextReducedReverseInlineLate( - DataFlowCallable c, CcNoCall ctx - ) { + private Call viableImplCallContextReducedReverseInlineLate(Callable c, CcNoCall ctx) { result = viableImplCallContextReducedReverseRestricted(c, ctx) } bindingset[call] pragma[inline_late] private predicate flowOutOfCallInlineLate( - DataFlowCall call, DataFlowCallable c, RetNd ret, Nd out, boolean allowsFieldFlow + Call call, Callable c, RetNd ret, Nd out, boolean allowsFieldFlow ) { PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) } @@ -875,8 +856,7 @@ module MakeImpl Lang> { pragma[inline_late] pragma[noopt] private predicate flowOutOfCallNotCallContextReduced( - DataFlowCall call, DataFlowCallable c, RetNd ret, Nd out, boolean allowsFieldFlow, - CcNoCall innercc + Call call, Callable c, RetNd ret, Nd out, boolean allowsFieldFlow, CcNoCall innercc ) { viableImplNotCallContextReducedReverse(innercc) and PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) @@ -892,8 +872,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowOutCand( - DataFlowCall call, RetNd ret, CcNoCall innercc, DataFlowCallable inner, Nd out, - boolean allowsFieldFlow + Call call, RetNd ret, CcNoCall innercc, Callable inner, Nd out, boolean allowsFieldFlow ) { fwdFlowIntoRet(ret, innercc, _, _, _, _) and inner = ret.getEnclosingCallable() and @@ -907,8 +886,8 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowOutValidEdge( - DataFlowCall call, RetNd ret, CcNoCall innercc, DataFlowCallable inner, Nd out, - CcNoCall outercc, boolean allowsFieldFlow + Call call, RetNd ret, CcNoCall innercc, Callable inner, Nd out, CcNoCall outercc, + boolean allowsFieldFlow ) { fwdFlowOutCand(call, ret, innercc, inner, out, allowsFieldFlow) and FwdTypeFlow::typeFlowValidEdgeOut(call, inner) and @@ -917,8 +896,8 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowOut( - DataFlowCall call, DataFlowCallable inner, Nd out, CcNoCall outercc, - SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored + Call call, Callable inner, Nd out, CcNoCall outercc, SummaryCtx summaryCtx, Typ t, Ap ap, + TypOption stored ) { exists(RetNd ret, CcNoCall innercc, boolean allowsFieldFlow | fwdFlowIntoRet(ret, innercc, summaryCtx, t, ap, stored) and @@ -936,8 +915,8 @@ module MakeImpl Lang> { pragma[nomagic] private predicate dataFlowTakenCallEdgeIn0( - DataFlowCall call, DataFlowCallable c, ParamNd p, CcCall innercc, Typ t, Ap ap, - TypOption stored, boolean cc + Call call, Callable c, ParamNd p, CcCall innercc, Typ t, Ap ap, TypOption stored, + boolean cc ) { FwdFlowInNoThrough::fwdFlowIn(call, _, c, p, _, innercc, _, t, ap, stored, cc) or @@ -951,7 +930,7 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate dataFlowTakenCallEdgeIn(DataFlowCall call, DataFlowCallable c, boolean cc) { + predicate dataFlowTakenCallEdgeIn(Call call, Callable c, boolean cc) { exists(ParamNd p, CcCall innercc, Typ t, Ap ap, TypOption stored | dataFlowTakenCallEdgeIn0(call, c, p, innercc, t, ap, stored, cc) and fwdFlow1Param(p, innercc, t, ap, stored) @@ -960,7 +939,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate dataFlowTakenCallEdgeOut0( - DataFlowCall call, DataFlowCallable c, Nd node, Cc cc, Typ t, Ap ap, TypOption stored + Call call, Callable c, Nd node, Cc cc, Typ t, Ap ap, TypOption stored ) { fwdFlowOut(call, c, node, cc, _, t, ap, stored) } @@ -972,14 +951,14 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate dataFlowTakenCallEdgeOut(DataFlowCall call, DataFlowCallable c) { + predicate dataFlowTakenCallEdgeOut(Call call, Callable c) { exists(Nd node, Cc cc, Typ t, Ap ap, TypOption stored | dataFlowTakenCallEdgeOut0(call, c, node, cc, t, ap, stored) and fwdFlow1Out(node, cc, t, ap, stored) ) } - predicate dataFlowNonCallEntry(DataFlowCallable c, boolean cc) { + predicate dataFlowNonCallEntry(Callable c, boolean cc) { exists(Nd node | sourceNode(node) and (if hasSourceCallCtx() then cc = true else cc = false) and @@ -998,7 +977,7 @@ module MakeImpl Lang> { private module FwdTypeFlow = TypeFlow; private predicate flowIntoCallTaken( - DataFlowCall call, DataFlowCallable c, ArgNd arg, ParamNd p, boolean emptyAp + Call call, Callable c, ArgNd arg, ParamNd p, boolean emptyAp ) { PrevStage::callEdgeArgParam(call, c, arg, p, emptyAp) and FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) @@ -1021,7 +1000,7 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowThrough0( - DataFlowCall call, ArgNd arg, Cc cc, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, + Call call, ArgNd arg, Cc cc, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNd ret, SummaryCtxSome innerSummaryCtx ) { fwdFlowRetFromArg(ret, ccc, innerSummaryCtx, t, ap, stored) and @@ -1030,15 +1009,15 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThrough( - DataFlowCall call, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNd ret + Call call, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNd ret ) { fwdFlowThrough0(call, _, cc, _, summaryCtx, t, ap, stored, ret, _) } pragma[nomagic] private predicate fwdFlowIsEntered0( - DataFlowCall call, ArgNd arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, ParamNd p, - Typ t, Ap ap, TypOption stored + Call call, ArgNd arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, ParamNd p, Typ t, + Ap ap, TypOption stored ) { FwdFlowInThrough::fwdFlowIn(call, arg, _, p, cc, innerCc, summaryCtx, t, ap, stored, _) } @@ -1049,7 +1028,7 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCall call, ArgNd arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, + Call call, ArgNd arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, SummaryCtxSome innerSummaryCtx ) { exists(ParamNd p, Typ t, Ap ap, TypOption stored | @@ -1071,7 +1050,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate returnFlowsThrough0( - DataFlowCall call, CcCall ccc, Ap ap, RetNd ret, SummaryCtxSome innerSummaryCtx + Call call, CcCall ccc, Ap ap, RetNd ret, SummaryCtxSome innerSummaryCtx ) { fwdFlowThrough0(call, _, _, ccc, _, _, ap, _, ret, innerSummaryCtx) } @@ -1081,7 +1060,7 @@ module MakeImpl Lang> { RetNd ret, ReturnPosition pos, CcCall ccc, ParamNd p, Typ argT, Ap argAp, TypOption argStored, Ap ap ) { - exists(DataFlowCall call, boolean allowsFieldFlow | + exists(Call call, boolean allowsFieldFlow | returnFlowsThrough0(call, ccc, ap, ret, TSummaryCtxSome(p, argT, argAp, argStored)) and flowThroughOutOfCall(call, ret, _, allowsFieldFlow) and pos = ret.getReturnPosition() and @@ -1090,7 +1069,7 @@ module MakeImpl Lang> { } pragma[nomagic] - private predicate flowThroughIntoCall(DataFlowCall call, ArgNd arg, ParamNd p, Ap argAp) { + private predicate flowThroughIntoCall(Call call, ArgNd arg, ParamNd p, Ap argAp) { exists(Typ argT, TypOption argStored | returnFlowsThrough(_, _, _, pragma[only_bind_into](p), pragma[only_bind_into](argT), pragma[only_bind_into](argAp), pragma[only_bind_into](argStored), _) and @@ -1101,16 +1080,14 @@ module MakeImpl Lang> { } pragma[nomagic] - private predicate flowIntoCallAp( - DataFlowCall call, DataFlowCallable c, ArgNd arg, ParamNd p, Ap ap - ) { + private predicate flowIntoCallAp(Call call, Callable c, ArgNd arg, ParamNd p, Ap ap) { flowIntoCallTaken(call, c, arg, p, isNil(ap)) and fwdFlow(arg, _, _, _, ap, _) } pragma[nomagic] private predicate flowOutOfCallAp( - DataFlowCall call, DataFlowCallable c, RetNd ret, ReturnPosition pos, Nd out, Ap ap, + Call call, Callable c, RetNd ret, ReturnPosition pos, Nd out, Ap ap, boolean allowsFieldFlow ) { PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) and @@ -1183,7 +1160,7 @@ module MakeImpl Lang> { returnAp = apNone() or // flow through a callable - exists(DataFlowCall call, ParamNd p | + exists(Call call, ParamNd p | revFlowThrough(call, returnCtx, p, returnAp, ap) and flowThroughIntoCall(call, node, p, ap) ) @@ -1238,16 +1215,14 @@ module MakeImpl Lang> { private module RevTypeFlowInput implements TypeFlowInput { predicate enableTypeFlow = Param::enableTypeFlow/0; - predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { + predicate relevantCallEdgeIn(Call call, Callable c) { flowOutOfCallAp(call, c, _, _, _, _, _) } - predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - flowIntoCallAp(call, c, _, _, _) - } + predicate relevantCallEdgeOut(Call call, Callable c) { flowIntoCallAp(call, c, _, _, _) } pragma[nomagic] - predicate dataFlowTakenCallEdgeIn(DataFlowCall call, DataFlowCallable c, boolean cc) { + predicate dataFlowTakenCallEdgeIn(Call call, Callable c, boolean cc) { exists(RetNd ret | revFlowOut(call, ret, _, _, cc, _, _) and c = ret.getEnclosingCallable() @@ -1255,11 +1230,9 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate dataFlowTakenCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - revFlowIn(call, c, _, _) - } + predicate dataFlowTakenCallEdgeOut(Call call, Callable c) { revFlowIn(call, c, _, _) } - predicate dataFlowNonCallEntry(DataFlowCallable c, boolean cc) { + predicate dataFlowNonCallEntry(Callable c, boolean cc) { exists(Nd node, ApNil nil | fwdFlow(node, _, _, _, nil, _) and sinkNode(node) and @@ -1278,24 +1251,22 @@ module MakeImpl Lang> { private module RevTypeFlow = TypeFlow; pragma[nomagic] - private predicate flowIntoCallApValid( - DataFlowCall call, DataFlowCallable c, ArgNd arg, ParamNd p, Ap ap - ) { + private predicate flowIntoCallApValid(Call call, Callable c, ArgNd arg, ParamNd p, Ap ap) { flowIntoCallAp(call, c, arg, p, ap) and RevTypeFlow::typeFlowValidEdgeOut(call, c) } pragma[nomagic] private predicate flowOutOfCallApValid( - DataFlowCall call, RetNd ret, ReturnPosition pos, Nd out, Ap ap, boolean cc + Call call, RetNd ret, ReturnPosition pos, Nd out, Ap ap, boolean cc ) { - exists(DataFlowCallable c | + exists(Callable c | flowOutOfCallAp(call, c, ret, pos, out, ap, _) and RevTypeFlow::typeFlowValidEdgeIn(call, c, cc) ) } - private predicate revFlowIn(DataFlowCall call, DataFlowCallable c, ArgNd arg, Ap ap) { + private predicate revFlowIn(Call call, Callable c, ArgNd arg, Ap ap) { exists(ParamNd p | revFlow(p, TReturnCtxNone(), _, ap) and flowIntoCallApValid(call, c, arg, p, ap) @@ -1304,7 +1275,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate revFlowOut( - DataFlowCall call, RetNd ret, ReturnPosition pos, ReturnCtx returnCtx, boolean cc, + Call call, RetNd ret, ReturnPosition pos, ReturnCtx returnCtx, boolean cc, ApOption returnAp, Ap ap ) { exists(Nd out | @@ -1324,7 +1295,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate revFlowThrough( - DataFlowCall call, ReturnCtx returnCtx, ParamNd p, ApOption returnAp, Ap ap + Call call, ReturnCtx returnCtx, ParamNd p, ApOption returnAp, Ap ap ) { exists(ReturnPosition pos, Ap innerReturnAp | revFlowParamToReturn(p, pos, innerReturnAp, ap) and @@ -1339,7 +1310,7 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap + Call call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap ) { exists(RetNd ret, CcCall ccc | revFlowOut(call, ret, pos, returnCtx, _, returnAp, ap) and @@ -1349,9 +1320,7 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate storeStepCand( - Nd node1, Content c, Nd node2, DataFlowType contentType, DataFlowType containerType - ) { + predicate storeStepCand(Nd node1, Content c, Nd node2, Type contentType, Type containerType) { exists(Ap ap2, Ap ap1 | PrevStage::storeStepCand(node1, c, node2, contentType, containerType) and revFlowStore(ap2, c, ap1, node1, node2, _, _) and @@ -1449,7 +1418,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate revFlowThroughArg( - DataFlowCall call, ArgNd arg, ReturnCtx returnCtx, ApOption returnAp, Ap ap + Call call, ArgNd arg, ReturnCtx returnCtx, ApOption returnAp, Ap ap ) { exists(ParamNd p | revFlowThrough(call, returnCtx, p, returnAp, ap) and @@ -1458,16 +1427,14 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call) { + predicate callMayFlowThroughRev(Call call) { exists(ArgNd arg, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, returnCtx, returnAp, ap) and revFlowThroughArg(call, arg, returnCtx, returnAp, ap) ) } - predicate callEdgeArgParam( - DataFlowCall call, DataFlowCallable c, ArgNd arg, ParamNd p, boolean emptyAp - ) { + predicate callEdgeArgParam(Call call, Callable c, ArgNd arg, ParamNd p, boolean emptyAp) { exists(Ap ap | flowIntoCallAp(call, c, arg, p, ap) and revFlow(arg, pragma[only_bind_into](ap)) and @@ -1481,8 +1448,7 @@ module MakeImpl Lang> { } predicate callEdgeReturn( - DataFlowCall call, DataFlowCallable c, RetNd ret, ReturnKindExt kind, Nd out, - boolean allowsFieldFlow + Call call, Callable c, RetNd ret, ReturnKindExt kind, Nd out, boolean allowsFieldFlow ) { exists(ReturnPosition pos, Ap ap | flowOutOfCallAp(call, c, ret, pos, out, ap, allowsFieldFlow) and @@ -1493,18 +1459,13 @@ module MakeImpl Lang> { ) } - predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - callEdgeArgParam(call, c, _, _, _) - } + predicate relevantCallEdgeIn(Call call, Callable c) { callEdgeArgParam(call, c, _, _, _) } - predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - callEdgeReturn(call, c, _, _, _, _) - } + predicate relevantCallEdgeOut(Call call, Callable c) { callEdgeReturn(call, c, _, _, _, _) } /** Holds if `node1` can step to `node2` in one or more local steps. */ signature predicate localStepSig( - Nd node1, Nd node2, boolean preservesValue, DataFlowType t, LocalCallContext lcc, - string label + Nd node1, Nd node2, boolean preservesValue, Type t, LocalCallContext lcc, string label ); /** @@ -1532,7 +1493,7 @@ module MakeImpl Lang> { } private predicate additionalLocalStateStep( - Nd node1, Nd node2, DataFlowType t, LocalCallContext lcc, string label + Nd node1, Nd node2, Type t, LocalCallContext lcc, string label ) { exists(ApNil nil | revFlow(node1, pragma[only_bind_into](nil)) and @@ -1615,10 +1576,9 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate localFlowStepPlus( - Nd node1, Nd node2, boolean preservesValue, DataFlowType t, LocalCallContext cc, - string label + Nd node1, Nd node2, boolean preservesValue, Type t, LocalCallContext cc, string label ) { - exists(Nd mid, boolean preservesValue2, DataFlowType t2, string label2, Ap ap | + exists(Nd mid, boolean preservesValue2, Type t2, string label2, Ap ap | localStepInput(mid, node2, preservesValue2, t2, cc, label2) and not isStateStep(mid, node2) and revFlow(node2, pragma[only_bind_into](ap)) and @@ -1631,7 +1591,7 @@ module MakeImpl Lang> { t = t2 and node1 != node2 or - exists(boolean preservesValue1, DataFlowType t1, string label1 | + exists(boolean preservesValue1, Type t1, string label1 | localFlowStepPlus(node1, mid, preservesValue1, t1, cc, label1) and not mid instanceof FlowCheckNode and preservesValue = preservesValue2.booleanAnd(preservesValue1) and @@ -1647,8 +1607,8 @@ module MakeImpl Lang> { */ pragma[nomagic] predicate localFlowBigStep( - Nd node1, Nd node2, boolean preservesValue, DataFlowType t, - LocalCallContext callContext, string label + Nd node1, Nd node2, boolean preservesValue, Type t, LocalCallContext callContext, + string label ) { exists(Ap ap | localFlowStepPlus(node1, node2, preservesValue, t, callContext, label) and @@ -1672,8 +1632,8 @@ module MakeImpl Lang> { */ pragma[nomagic] predicate localFlowBigStepTc( - Nd node1, Nd node2, boolean preservesValue, DataFlowType t, - LocalCallContext callContext, string label + Nd node1, Nd node2, boolean preservesValue, Type t, LocalCallContext callContext, + string label ) { exists(Ap ap | localFlowEntry(node1, pragma[only_bind_into](ap)) and @@ -2005,7 +1965,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThroughStep0( - DataFlowCall call, ArgNd arg, Cc cc, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, + Call call, ArgNd arg, Cc cc, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNd ret, SummaryCtxSome innerSummaryCtx ) { fwdFlowThrough0(call, arg, cc, ccc, summaryCtx, t, ap, stored, ret, innerSummaryCtx) @@ -2030,7 +1990,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThroughStep1( - PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, DataFlowCall call, Cc cc, + PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, Call call, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNd ret ) { exists( @@ -2053,7 +2013,7 @@ module MakeImpl Lang> { PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, Nd node, Cc cc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored ) { - exists(DataFlowCall call, RetNd ret, boolean allowsFieldFlow | + exists(Call call, RetNd ret, boolean allowsFieldFlow | fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, summaryCtx, t, ap, stored, ret) and flowThroughOutOfCall(call, ret, node, allowsFieldFlow) and if allowsFieldFlow = false then ap instanceof ApNil else any() @@ -2464,7 +2424,7 @@ module MakeImpl Lang> { fwdFlow(n, cc, summaryCtx, t, ap, stored) ) and calledges = - count(DataFlowCall call, DataFlowCallable c | + count(Call call, Callable c | FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) or FwdTypeFlowInput::dataFlowTakenCallEdgeOut(call, c) ) and @@ -2480,7 +2440,7 @@ module MakeImpl Lang> { revFlow(n, returnCtx, retAp, ap) ) and calledges = - count(DataFlowCall call, DataFlowCallable c | + count(Call call, Callable c | RevTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) or RevTypeFlowInput::dataFlowTakenCallEdgeOut(call, c) ) and @@ -2498,7 +2458,7 @@ module MakeImpl Lang> { } /** Holds if the call context may be `call`. */ - predicate matchesCall(CcCall cc, DataFlowCall call) { any() } + predicate matchesCall(CcCall cc, Call call) { any() } class CcNoCall extends Cc { CcNoCall() { this = false } @@ -2519,20 +2479,20 @@ module MakeImpl Lang> { bindingset[cc] LocalCc getLocalCc(Cc cc) { any() } - DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CcCall ctx) { none() } + Callable viableImplCallContextReduced(Call call, CcCall ctx) { none() } bindingset[call, ctx] - predicate viableImplNotCallContextReduced(DataFlowCall call, Cc ctx) { any() } + predicate viableImplNotCallContextReduced(Call call, Cc ctx) { any() } bindingset[call, c] - CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { any() } + CcCall getCallContextCall(Call call, Callable c) { any() } - DataFlowCall viableImplCallContextReducedReverse(DataFlowCallable c, CcNoCall ctx) { none() } + Call viableImplCallContextReducedReverse(Callable c, CcNoCall ctx) { none() } predicate viableImplNotCallContextReducedReverse(CcNoCall ctx) { any() } bindingset[call, c] - CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() } + CcNoCall getCallContextReturn(Callable c, Call call) { any() } } private module S1 implements StageSig { @@ -2553,7 +2513,7 @@ module MakeImpl Lang> { bindingset[result, ap] PrevStage::Ap getApprox(Ap ap) { any() } - Typ getTyp(DataFlowType t) { any() } + Typ getTyp(Type t) { any() } bindingset[c, tail] Ap apCons(Content c, Ap tail) { @@ -2629,7 +2589,7 @@ module MakeImpl Lang> { PrevStage::Ap getApprox(Ap ap) { result = ap.toBoolNonEmpty() } - Typ getTyp(DataFlowType t) { any() } + Typ getTyp(Type t) { any() } bindingset[c, tail] Ap apCons(Content c, Ap tail) { result.getAHead() = c and exists(tail) } @@ -2663,8 +2623,7 @@ module MakeImpl Lang> { import NoLocalCallContext additional predicate localFlowBigStep( - Nd node1, Nd node2, boolean preservesValue, DataFlowType t, LocalCallContext lcc, - string label + Nd node1, Nd node2, boolean preservesValue, Type t, LocalCallContext lcc, string label ) { PrevStage::LocalFlowBigStep::localFlowBigStep(node1, node2, preservesValue, t, lcc, label) @@ -2708,10 +2667,10 @@ module MakeImpl Lang> { private module Stage3 = MkStage::Stage; bindingset[node, t0] - private predicate strengthenType(Nd node, DataFlowType t0, DataFlowType t) { + private predicate strengthenType(Nd node, Type t0, Type t) { if node instanceof CastingNd then - exists(DataFlowType nt | nt = node.getDataFlowType() | + exists(Type nt | nt = node.getType() | if typeStrongerThanFilter(nt, t0) then t = nt else ( @@ -2732,7 +2691,7 @@ module MakeImpl Lang> { PrevStage::Ap getApprox(Ap ap) { result = ap.toApprox() } - Typ getTyp(DataFlowType t) { any() } + Typ getTyp(Type t) { any() } bindingset[c, tail] Ap apCons(Content c, Ap tail) { result.getHead() = c and exists(tail) } @@ -2994,7 +2953,7 @@ module MakeImpl Lang> { private module Stage5Param implements MkStage::StageParam { private module PrevStage = Stage4; - class Typ = DataFlowType; + class Typ = Type; class Ap = AccessPathApprox; @@ -3003,7 +2962,7 @@ module MakeImpl Lang> { pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getFront() } - Typ getTyp(DataFlowType t) { result = t } + Typ getTyp(Type t) { result = t } bindingset[c, tail] Ap apCons(Content c, Ap tail) { result.isCons(c, tail) } @@ -3184,7 +3143,7 @@ module MakeImpl Lang> { private module Stage6Param implements MkStage::StageParam { private module PrevStage = Stage5; - class Typ = DataFlowType; + class Typ = Type; class Ap = AccessPath; @@ -3193,7 +3152,7 @@ module MakeImpl Lang> { pragma[nomagic] PrevStage::Ap getApprox(Ap ap) { result = ap.getApprox() } - Typ getTyp(DataFlowType t) { result = t } + Typ getTyp(Type t) { result = t } bindingset[c, tail] pragma[inline_late] @@ -3428,7 +3387,7 @@ module MakeImpl Lang> { /** * Holds if data can flow from some source to `sink`. */ - predicate flowToExpr(DataFlowExpr sink) { flowTo(exprNode(sink)) } + predicate flowToExpr(Expr sink) { flowTo(exprNode(sink)) } /** * INTERNAL: Only for debugging. diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index 2fbabf1e9ef..845da27aae7 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -9,6 +9,19 @@ module MakeImplCommon Lang> { private import Lang import Cached + /** Provides short-hand aliases for making the code less verbose. */ + module Aliases { + class Call = Lang::DataFlowCall; + + class Callable = Lang::DataFlowCallable; + + class Type = Lang::DataFlowType; + + class Expr = Lang::DataFlowExpr; + } + + private import Aliases + module DataFlowImplCommonPublic { /** * DEPRECATED: Generally, a custom `FlowState` type should be used instead, @@ -176,7 +189,7 @@ module MakeImplCommon Lang> { * parameter position `ppos`. */ pragma[noinline] - predicate argumentPositionMatch(DataFlowCall call, ArgNode arg, ParameterPosition ppos) { + predicate argumentPositionMatch(Call call, ArgNode arg, ParameterPosition ppos) { exists(ArgumentPosition apos | arg.argumentOf(call, apos) and parameterMatch(ppos, apos) @@ -193,23 +206,23 @@ module MakeImplCommon Lang> { */ private module LambdaFlow { pragma[noinline] - private predicate viableParamNonLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) { + private predicate viableParamNonLambda(Call call, ParameterPosition ppos, ParamNode p) { p.isParameterOf(viableCallable(call), ppos) } pragma[noinline] - private predicate viableParamLambda(DataFlowCall call, ParameterPosition ppos, ParamNode p) { + private predicate viableParamLambda(Call call, ParameterPosition ppos, ParamNode p) { p.isParameterOf(viableCallableLambda(call, _), ppos) } - private predicate viableParamArgNonLambda(DataFlowCall call, ParamNode p, ArgNode arg) { + private predicate viableParamArgNonLambda(Call call, ParamNode p, ArgNode arg) { exists(ParameterPosition ppos | viableParamNonLambda(call, ppos, p) and argumentPositionMatch(call, arg, ppos) ) } - private predicate viableParamArgLambda(DataFlowCall call, ParamNode p, ArgNode arg) { + private predicate viableParamArgLambda(Call call, ParamNode p, ArgNode arg) { exists(ParameterPosition ppos | viableParamLambda(call, ppos, p) and argumentPositionMatch(call, arg, ppos) @@ -217,7 +230,7 @@ module MakeImplCommon Lang> { } private newtype TReturnPositionSimple = - TReturnPositionSimple0(DataFlowCallable c, ReturnKind kind) { + TReturnPositionSimple0(Callable c, ReturnKind kind) { exists(ReturnNode ret | c = getNodeEnclosingCallable(ret) and kind = ret.getKind() @@ -225,32 +238,30 @@ module MakeImplCommon Lang> { } pragma[nomagic] - private predicate hasSimpleReturnKindIn(ReturnNode ret, ReturnKind kind, DataFlowCallable c) { + private predicate hasSimpleReturnKindIn(ReturnNode ret, ReturnKind kind, Callable c) { c = getNodeEnclosingCallable(ret) and kind = ret.getKind() } pragma[nomagic] private TReturnPositionSimple getReturnPositionSimple(ReturnNode ret) { - exists(ReturnKind kind, DataFlowCallable c | + exists(ReturnKind kind, Callable c | hasSimpleReturnKindIn(ret, kind, c) and result = TReturnPositionSimple0(c, kind) ) } pragma[nomagic] - private TReturnPositionSimple viableReturnPosNonLambda(DataFlowCall call, ReturnKind kind) { + private TReturnPositionSimple viableReturnPosNonLambda(Call call, ReturnKind kind) { result = TReturnPositionSimple0(viableCallable(call), kind) } pragma[nomagic] - private TReturnPositionSimple viableReturnPosLambda(DataFlowCall call, ReturnKind kind) { + private TReturnPositionSimple viableReturnPosLambda(Call call, ReturnKind kind) { result = TReturnPositionSimple0(viableCallableLambda(call, _), kind) } - private predicate viableReturnPosOutNonLambda( - DataFlowCall call, TReturnPositionSimple pos, OutNode out - ) { + private predicate viableReturnPosOutNonLambda(Call call, TReturnPositionSimple pos, OutNode out) { exists(ReturnKind kind | pos = viableReturnPosNonLambda(call, kind) and out = getAnOutNode(call, kind) @@ -258,9 +269,7 @@ module MakeImplCommon Lang> { } pragma[nomagic] - private predicate viableReturnPosOutLambda( - DataFlowCall call, TReturnPositionSimple pos, OutNode out - ) { + private predicate viableReturnPosOutLambda(Call call, TReturnPositionSimple pos, OutNode out) { exists(ReturnKind kind | pos = viableReturnPosLambda(call, kind) and out = getAnOutNode(call, kind) @@ -281,8 +290,8 @@ module MakeImplCommon Lang> { */ pragma[nomagic] predicate revLambdaFlow( - DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, - boolean toJump, DataFlowCallOption lastCall + Call lambdaCall, LambdaCallKind kind, Node node, Type t, boolean toReturn, boolean toJump, + CallOption lastCall ) { revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and not expectsContent(node, _) and @@ -293,17 +302,17 @@ module MakeImplCommon Lang> { pragma[nomagic] predicate revLambdaFlow0( - DataFlowCall lambdaCall, LambdaCallKind kind, Node node, DataFlowType t, boolean toReturn, - boolean toJump, DataFlowCallOption lastCall + Call lambdaCall, LambdaCallKind kind, Node node, Type t, boolean toReturn, boolean toJump, + CallOption lastCall ) { lambdaCall(lambdaCall, kind, node) and t = getNodeDataFlowType(node) and toReturn = false and toJump = false and - lastCall = TDataFlowCallNone() + lastCall = TCallNone() or // local flow - exists(Node mid, DataFlowType t0 | + exists(Node mid, Type t0 | revLambdaFlow(lambdaCall, kind, mid, t0, toReturn, toJump, lastCall) | simpleLocalFlowStep(node, mid, _) and @@ -322,7 +331,7 @@ module MakeImplCommon Lang> { ) or // jump step - exists(Node mid, DataFlowType t0 | + exists(Node mid, Type t0 | revLambdaFlow(lambdaCall, kind, mid, t0, _, _, lastCall) and toReturn = false and toJump = true @@ -343,11 +352,11 @@ module MakeImplCommon Lang> { ) or // flow into a callable - exists(ParamNode p, DataFlowCallOption lastCall0, DataFlowCall call | + exists(ParamNode p, CallOption lastCall0, Call call | revLambdaFlowIn(lambdaCall, kind, p, t, toJump, lastCall0) and ( - if lastCall0 = TDataFlowCallNone() and toJump = false - then lastCall = TDataFlowCallSome(call) + if lastCall0 = TCallNone() and toJump = false + then lastCall = TCallSome(call) else lastCall = lastCall0 ) and toReturn = false @@ -367,8 +376,8 @@ module MakeImplCommon Lang> { pragma[nomagic] predicate revLambdaFlowOutLambdaCall( - DataFlowCall lambdaCall, LambdaCallKind kind, OutNode out, DataFlowType t, boolean toJump, - DataFlowCall call, DataFlowCallOption lastCall + Call lambdaCall, LambdaCallKind kind, OutNode out, Type t, boolean toJump, Call call, + CallOption lastCall ) { revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and exists(ReturnKindExt rk | @@ -379,10 +388,10 @@ module MakeImplCommon Lang> { pragma[nomagic] predicate revLambdaFlowOut( - DataFlowCall lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, DataFlowType t, - boolean toJump, DataFlowCallOption lastCall + Call lambdaCall, LambdaCallKind kind, TReturnPositionSimple pos, Type t, boolean toJump, + CallOption lastCall ) { - exists(DataFlowCall call, OutNode out | + exists(Call call, OutNode out | revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and viableReturnPosOutNonLambda(call, pos, out) or @@ -394,14 +403,13 @@ module MakeImplCommon Lang> { pragma[nomagic] predicate revLambdaFlowIn( - DataFlowCall lambdaCall, LambdaCallKind kind, ParamNode p, DataFlowType t, boolean toJump, - DataFlowCallOption lastCall + Call lambdaCall, LambdaCallKind kind, ParamNode p, Type t, boolean toJump, CallOption lastCall ) { revLambdaFlow(lambdaCall, kind, p, t, false, toJump, lastCall) } } - private DataFlowCallable viableCallableExt(DataFlowCall call) { + private Callable viableCallableExt(Call call) { result = viableCallableCached(call) or result = viableCallableLambda(call, _) @@ -409,18 +417,16 @@ module MakeImplCommon Lang> { signature module CallContextSensitivityInputSig { /** Holds if the edge is possibly needed in the direction `call` to `c`. */ - predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c); + predicate relevantCallEdgeIn(Call call, Callable c); /** Holds if the edge is possibly needed in the direction `c` to `call`. */ - predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c); + predicate relevantCallEdgeOut(Call call, Callable c); /** * Holds if the call context `ctx` may reduce the set of viable run-time * dispatch targets of call `call` in `c`. */ - default predicate reducedViableImplInCallContextCand( - DataFlowCall call, DataFlowCallable c, DataFlowCall ctx - ) { + default predicate reducedViableImplInCallContextCand(Call call, Callable c, Call ctx) { relevantCallEdgeIn(ctx, c) and mayBenefitFromCallContextExt(call, c) } @@ -430,7 +436,7 @@ module MakeImplCommon Lang> { * further and if this path may restrict the set of call sites that can be * returned to. */ - default predicate reducedViableImplInReturnCand(DataFlowCallable c, DataFlowCall call) { + default predicate reducedViableImplInReturnCand(Callable c, Call call) { relevantCallEdgeOut(call, c) and mayBenefitFromCallContextExt(call, _) } @@ -441,7 +447,7 @@ module MakeImplCommon Lang> { private import Input pragma[nomagic] - private DataFlowCallable viableImplInCallContextExtIn(DataFlowCall call, DataFlowCall ctx) { + private Callable viableImplInCallContextExtIn(Call call, Call ctx) { reducedViableImplInCallContextCand(call, _, ctx) and result = viableImplInCallContextExt(call, ctx) and relevantCallEdgeIn(call, result) @@ -452,11 +458,11 @@ module MakeImplCommon Lang> { * dispatch targets of call `call` in `c`. */ pragma[nomagic] - predicate reducedViableImplInCallContext(DataFlowCall call, DataFlowCallable c, DataFlowCall ctx) { + predicate reducedViableImplInCallContext(Call call, Callable c, Call ctx) { exists(int tgts, int ctxtgts | reducedViableImplInCallContextCand(call, c, ctx) and ctxtgts = count(viableImplInCallContextExtIn(call, ctx)) and - tgts = strictcount(DataFlowCallable tgt | relevantCallEdgeIn(call, tgt)) and + tgts = strictcount(Callable tgt | relevantCallEdgeIn(call, tgt)) and ctxtgts < tgts ) } @@ -465,7 +471,7 @@ module MakeImplCommon Lang> { * Holds if the call context `call` allows us to prune unreachable nodes in `callable`. */ pragma[nomagic] - predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable callable) { + predicate recordCallSiteUnreachable(Call call, Callable callable) { exists(NodeRegion nr | relevantCallEdgeIn(call, callable) and getNodeRegionEnclosingCallable(nr) = callable and @@ -474,8 +480,8 @@ module MakeImplCommon Lang> { } pragma[nomagic] - private DataFlowCallable viableImplInCallContextExtOut(DataFlowCall call, DataFlowCall ctx) { - exists(DataFlowCallable c | + private Callable viableImplInCallContextExtOut(Call call, Call ctx) { + exists(Callable c | reducedViableImplInReturnCand(result, call) and result = viableImplInCallContextExt(call, ctx) and mayBenefitFromCallContextExt(call, c) and @@ -489,27 +495,27 @@ module MakeImplCommon Lang> { * returned to. */ pragma[nomagic] - predicate reducedViableImplInReturn(DataFlowCallable c, DataFlowCall call) { + predicate reducedViableImplInReturn(Callable c, Call call) { exists(int tgts, int ctxtgts | reducedViableImplInReturnCand(c, call) and - ctxtgts = count(DataFlowCall ctx | c = viableImplInCallContextExtOut(call, ctx)) and + ctxtgts = count(Call ctx | c = viableImplInCallContextExtOut(call, ctx)) and tgts = - strictcount(DataFlowCall ctx | - callEnclosingCallable(call, any(DataFlowCallable encl | relevantCallEdgeOut(ctx, encl))) + strictcount(Call ctx | + callEnclosingCallable(call, any(Callable encl | relevantCallEdgeOut(ctx, encl))) ) and ctxtgts < tgts ) } - private DataFlowCall getACallWithReducedViableImpl(TCallEdge ctxEdge) { - exists(DataFlowCall ctx, DataFlowCallable c | + private Call getACallWithReducedViableImpl(TCallEdge ctxEdge) { + exists(Call ctx, Callable c | ctxEdge = TMkCallEdge(ctx, c) and reducedViableImplInCallContext(result, c, ctx) ) } private module CallSets = - QlBuiltins::InternSets; + QlBuiltins::InternSets; private class CallSet0 extends CallSets::Set { string toString() { result = "CallSet" } @@ -525,7 +531,7 @@ module MakeImplCommon Lang> { private class CallSet = CallSetOption::Option; private TCallEdge getAReducedViableEdge(TCallEdge ctxEdge) { - exists(DataFlowCall ctx, DataFlowCallable c, DataFlowCall call, DataFlowCallable tgt | + exists(Call ctx, Callable c, Call call, Callable tgt | ctxEdge = mkCallEdge(ctx, c) and result = mkCallEdge(call, tgt) and viableImplInCallContextExtIn(call, ctx) = tgt and @@ -585,7 +591,7 @@ module MakeImplCommon Lang> { hasCtx(_, calls, tgts, unreachable) } or TSomeCall() or - TReturn(DataFlowCallable c, DataFlowCall call) { reducedViableImplInReturn(c, call) } + TReturn(Callable c, Call call) { reducedViableImplInReturn(c, call) } /** * A call context to restrict the targets of virtual dispatch and prune local flow. @@ -600,7 +606,7 @@ module MakeImplCommon Lang> { * - `TSomeCall()` : Flow entered through a parameter. The * originating call does not improve the set of dispatch targets for any * method call in the current callable and was therefore not recorded. - * - `TReturn(Callable c, DataFlowCall call)` : Flow reached `call` from `c` and + * - `TReturn(Callable c, Call call)` : Flow reached `call` from `c` and * this dispatch target of `call` implies a reduced set of dispatch origins * to which data may flow if it should reach a `return` statement. */ @@ -626,12 +632,12 @@ module MakeImplCommon Lang> { private class CallContextReturn extends CallContextNoCall, TReturn { override string toString() { - exists(DataFlowCall call | this = TReturn(_, call) | result = "CcReturn(" + call + ")") + exists(Call call | this = TReturn(_, call) | result = "CcReturn(" + call + ")") } } pragma[nomagic] - CallContextCall getSpecificCallContextCall(DataFlowCall call, DataFlowCallable c) { + CallContextCall getSpecificCallContextCall(Call call, Callable c) { exists(CallSet calls, DispatchSet tgts, UnreachableSetOption unreachable | hasCtx(TMkCallEdge(call, c), calls, tgts, unreachable) and result = TSpecificCall(calls, tgts, unreachable) @@ -639,26 +645,24 @@ module MakeImplCommon Lang> { } pragma[nomagic] - predicate callContextAffectsDispatch(DataFlowCall call, CallContext ctx) { + predicate callContextAffectsDispatch(Call call, CallContext ctx) { exists(CallSet calls | ctx = TSpecificCall(calls, _, _) | calls.asSome().contains(call)) } - CallContextNoCall getSpecificCallContextReturn(DataFlowCallable c, DataFlowCall call) { + CallContextNoCall getSpecificCallContextReturn(Callable c, Call call) { result = TReturn(c, call) } signature module PrunedViableImplInputSig { - predicate reducedViableImplInCallContext( - DataFlowCall call, DataFlowCallable c, DataFlowCall ctx - ); + predicate reducedViableImplInCallContext(Call call, Callable c, Call ctx); - predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable c); + predicate recordCallSiteUnreachable(Call call, Callable c); - CallContextCall getSpecificCallContextCall(DataFlowCall call, DataFlowCallable c); + CallContextCall getSpecificCallContextCall(Call call, Callable c); - predicate callContextAffectsDispatch(DataFlowCall call, CallContext ctx); + predicate callContextAffectsDispatch(Call call, CallContext ctx); - CallContextNoCall getSpecificCallContextReturn(DataFlowCallable c, DataFlowCall call); + CallContextNoCall getSpecificCallContextReturn(Callable c, Call call); } /** @@ -671,7 +675,7 @@ module MakeImplCommon Lang> { class CcCall = CallContextCall; pragma[inline] - predicate matchesCall(CcCall cc, DataFlowCall call) { + predicate matchesCall(CcCall cc, Call call) { cc = Input2::getSpecificCallContextCall(call, _) or cc = ccSomeCall() } @@ -696,7 +700,7 @@ module MakeImplCommon Lang> { * makes a difference. */ pragma[nomagic] - DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CallContextCall ctx) { + Callable viableImplCallContextReduced(Call call, CallContextCall ctx) { exists(DispatchSet tgts | ctx = TSpecificCall(_, tgts, _) | tgts.asSome().contains(TMkCallEdge(call, result)) ) @@ -704,7 +708,7 @@ module MakeImplCommon Lang> { /** Holds if `call` does not have a reduced set of dispatch targets in call context `ctx`. */ bindingset[call, ctx] - predicate viableImplNotCallContextReduced(DataFlowCall call, CallContext ctx) { + predicate viableImplNotCallContextReduced(Call call, CallContext ctx) { not Input2::callContextAffectsDispatch(call, ctx) } @@ -713,7 +717,7 @@ module MakeImplCommon Lang> { * restricted by `relevantResolveTarget`. */ bindingset[call, cc] - DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) { + Callable resolveCall(Call call, CallContext cc) { result = viableImplCallContextReduced(call, cc) or viableImplNotCallContextReduced(call, cc) and @@ -726,10 +730,8 @@ module MakeImplCommon Lang> { * the possible call sites are restricted. */ pragma[nomagic] - DataFlowCall viableImplCallContextReducedReverse( - DataFlowCallable callable, CallContextNoCall ctx - ) { - exists(DataFlowCallable c0, DataFlowCall call0 | + Call viableImplCallContextReducedReverse(Callable callable, CallContextNoCall ctx) { + exists(Callable c0, Call call0 | callEnclosingCallable(call0, callable) and ctx = TReturn(c0, call0) and c0 = viableImplInCallContextExtOut(call0, result) and @@ -749,7 +751,7 @@ module MakeImplCommon Lang> { * Resolves a return from `callable` in `cc` to `call`. */ bindingset[cc, callable] - predicate resolveReturn(CallContextNoCall cc, DataFlowCallable callable, DataFlowCall call) { + predicate resolveReturn(CallContextNoCall cc, Callable callable, Call call) { cc instanceof CallContextAny and relevantCallEdgeOut(call, callable) or call = viableImplCallContextReducedReverse(callable, cc) @@ -757,7 +759,7 @@ module MakeImplCommon Lang> { /** Gets the call context when returning from `c` to `call`. */ bindingset[call, c] - CallContextNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { + CallContextNoCall getCallContextReturn(Callable c, Call call) { result = Input2::getSpecificCallContextReturn(c, call) or not exists(Input2::getSpecificCallContextReturn(c, call)) and result = TAnyCallContext() @@ -767,7 +769,7 @@ module MakeImplCommon Lang> { * Holds if the call context `call` improves virtual dispatch in `callable`. */ pragma[nomagic] - private predicate recordDataFlowCallSiteDispatch(DataFlowCall call, DataFlowCallable callable) { + private predicate recordCallSiteDispatch(Call call, Callable callable) { Input2::reducedViableImplInCallContext(_, callable, call) } @@ -775,9 +777,9 @@ module MakeImplCommon Lang> { * Holds if the call context `call` either improves virtual dispatch in * `callable` or if it allows us to prune unreachable nodes in `callable`. */ - predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable c) { - Input2::recordDataFlowCallSiteUnreachable(call, c) or - recordDataFlowCallSiteDispatch(call, c) + predicate recordCallSite(Call call, Callable c) { + Input2::recordCallSiteUnreachable(call, c) or + recordCallSiteDispatch(call, c) } module NoLocalCallContext { @@ -787,8 +789,8 @@ module MakeImplCommon Lang> { LocalCc getLocalCc(CallContext cc) { any() } bindingset[call, c] - CallContextCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { - if recordDataFlowCallSiteDispatch(call, c) + CallContextCall getCallContextCall(Call call, Callable c) { + if recordCallSiteDispatch(call, c) then result = Input2::getSpecificCallContextCall(call, c) else result = TSomeCall() } @@ -815,8 +817,8 @@ module MakeImplCommon Lang> { LocalCc getLocalCc(CallContext cc) { result = getLocalCallContext(cc) } bindingset[call, c] - CallContextCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { - if recordDataFlowCallSite(call, c) + CallContextCall getCallContextCall(Call call, Callable c) { + if recordCallSite(call, c) then result = Input2::getSpecificCallContextCall(call, c) else result = TSomeCall() } @@ -825,7 +827,7 @@ module MakeImplCommon Lang> { private predicate reducedViableImplInCallContextAlias = reducedViableImplInCallContext/3; - private predicate recordDataFlowCallSiteUnreachableAlias = recordDataFlowCallSiteUnreachable/2; + private predicate recordCallSiteUnreachableAlias = recordCallSiteUnreachable/2; private predicate getSpecificCallContextCallAlias = getSpecificCallContextCall/2; @@ -836,7 +838,7 @@ module MakeImplCommon Lang> { private module DefaultPrunedViableImplInput implements PrunedViableImplInputSig { predicate reducedViableImplInCallContext = reducedViableImplInCallContextAlias/3; - predicate recordDataFlowCallSiteUnreachable = recordDataFlowCallSiteUnreachableAlias/2; + predicate recordCallSiteUnreachable = recordCallSiteUnreachableAlias/2; predicate getSpecificCallContextCall = getSpecificCallContextCallAlias/2; @@ -881,28 +883,24 @@ module MakeImplCommon Lang> { } pragma[nomagic] - private DataFlowCallable getEnclosingCallable0() { - nodeEnclosingCallable(this.projectToNode(), result) - } + private Callable getEnclosingCallable0() { nodeEnclosingCallable(this.projectToNode(), result) } pragma[inline] - DataFlowCallable getEnclosingCallable() { + Callable getEnclosingCallable() { pragma[only_bind_out](this).getEnclosingCallable0() = pragma[only_bind_into](result) } pragma[nomagic] - private DataFlowType getDataFlowType0() { - nodeDataFlowType(this.asNode(), result) + private Type getType0() { + nodeType(this.asNode(), result) or - nodeDataFlowType(this.asParamReturnNode(), result) + nodeType(this.asParamReturnNode(), result) or isTopType(result) and this.isImplicitReadNode(_) } pragma[inline] - DataFlowType getDataFlowType() { - pragma[only_bind_out](this).getDataFlowType0() = pragma[only_bind_into](result) - } + Type getType() { pragma[only_bind_out](this).getType0() = pragma[only_bind_into](result) } Location getLocation() { result = this.projectToNode().getLocation() } } @@ -915,26 +913,26 @@ module MakeImplCommon Lang> { } final class ArgNodeEx extends NodeEx { - private DataFlowCall call_; + private Call call_; private ArgumentPosition pos_; ArgNodeEx() { this.asNode().(ArgNode).argumentOf(call_, pos_) } - predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { + predicate argumentOf(Call call, ArgumentPosition pos) { call = call_ and pos = pos_ } - DataFlowCall getCall() { result = call_ } + Call getCall() { result = call_ } } final class ParamNodeEx extends NodeEx { - private DataFlowCallable c_; + private Callable c_; private ParameterPosition pos_; ParamNodeEx() { this.asNode().(ParamNode).isParameterOf(c_, pos_) } - predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { c = c_ and pos = pos_ } + predicate isParameterOf(Callable c, ParameterPosition pos) { c = c_ and pos = pos_ } ParameterPosition getPosition() { result = pos_ } } @@ -981,29 +979,27 @@ module MakeImplCommon Lang> { } cached - predicate nodeEnclosingCallable(Node n, DataFlowCallable c) { c = nodeGetEnclosingCallable(n) } + predicate nodeEnclosingCallable(Node n, Callable c) { c = nodeGetEnclosingCallable(n) } cached - predicate callEnclosingCallable(DataFlowCall call, DataFlowCallable c) { - c = call.getEnclosingCallable() + predicate callEnclosingCallable(Call call, Callable c) { c = call.getEnclosingCallable() } + + cached + predicate nodeType(Node n, Type t) { t = getNodeType(n) } + + cached + predicate compatibleTypesCached(Type t1, Type t2) { compatibleTypes(t1, t2) } + + private predicate relevantType(Type t) { t = getNodeType(_) } + + cached + predicate isTopType(Type t) { + strictcount(Type t0 | relevantType(t0)) = + strictcount(Type t0 | relevantType(t0) and compatibleTypesCached(t, t0)) } cached - predicate nodeDataFlowType(Node n, DataFlowType t) { t = getNodeType(n) } - - cached - predicate compatibleTypesCached(DataFlowType t1, DataFlowType t2) { compatibleTypes(t1, t2) } - - private predicate relevantType(DataFlowType t) { t = getNodeType(_) } - - cached - predicate isTopType(DataFlowType t) { - strictcount(DataFlowType t0 | relevantType(t0)) = - strictcount(DataFlowType t0 | relevantType(t0) and compatibleTypesCached(t, t0)) - } - - cached - predicate typeStrongerThanCached(DataFlowType t1, DataFlowType t2) { typeStrongerThan(t1, t2) } + predicate typeStrongerThanCached(Type t1, Type t2) { typeStrongerThan(t1, t2) } cached predicate jumpStepCached(Node node1, Node node2) { jumpStep(node1, node2) } @@ -1018,9 +1014,7 @@ module MakeImplCommon Lang> { predicate expectsContentSet(NodeEx n, ContentSet c) { expectsContent(n.asNode(), c) } cached - predicate isUnreachableInCallCached(NodeRegion nr, DataFlowCall call) { - isUnreachableInCall(nr, call) - } + predicate isUnreachableInCallCached(NodeRegion nr, Call call) { isUnreachableInCall(nr, call) } cached predicate outNodeExt(Node n) { @@ -1037,7 +1031,7 @@ module MakeImplCommon Lang> { } cached - OutNodeEx getAnOutNodeEx(DataFlowCall call, ReturnKindExt k) { + OutNodeEx getAnOutNodeEx(Call call, ReturnKindExt k) { result.asNode() = getAnOutNodeExt(call, k) } @@ -1074,17 +1068,15 @@ module MakeImplCommon Lang> { string getSinkModel(NodeEx node) { knownSinkModel(node.asNodeOrImplicitRead(), result) } cached - predicate parameterNode(Node p, DataFlowCallable c, ParameterPosition pos) { + predicate parameterNode(Node p, Callable c, ParameterPosition pos) { isParameterNode(p, c, pos) } cached - predicate argumentNode(Node n, DataFlowCall call, ArgumentPosition pos) { - isArgumentNode(n, call, pos) - } + predicate argumentNode(Node n, Call call, ArgumentPosition pos) { isArgumentNode(n, call, pos) } cached - DataFlowCallable viableCallableCached(DataFlowCall call) { result = viableCallable(call) } + Callable viableCallableCached(Call call) { result = viableCallable(call) } /** * Gets a viable target for the lambda call `call`. @@ -1093,7 +1085,7 @@ module MakeImplCommon Lang> { * to be a viable target, if any. */ cached - DataFlowCallable viableCallableLambda(DataFlowCall call, DataFlowCallOption lastCall) { + Callable viableCallableLambda(Call call, CallOption lastCall) { exists(Node creation, LambdaCallKind kind | LambdaFlow::revLambdaFlow(call, kind, creation, _, _, _, lastCall) and lambdaCreation(creation, kind, result) @@ -1105,11 +1097,11 @@ module MakeImplCommon Lang> { * might be improved by knowing the call context. */ cached - predicate mayBenefitFromCallContextExt(DataFlowCall call, DataFlowCallable callable) { + predicate mayBenefitFromCallContextExt(Call call, Callable callable) { ( mayBenefitFromCallContext(call) or - exists(viableCallableLambda(call, TDataFlowCallSome(_))) + exists(viableCallableLambda(call, TCallSome(_))) ) and callEnclosingCallable(call, callable) } @@ -1119,16 +1111,16 @@ module MakeImplCommon Lang> { * restricted to those `call`s for which a context might make a difference. */ cached - DataFlowCallable viableImplInCallContextExt(DataFlowCall call, DataFlowCall ctx) { + Callable viableImplInCallContextExt(Call call, Call ctx) { result = viableImplInCallContext(call, ctx) and result = viableCallable(call) or - result = viableCallableLambda(call, TDataFlowCallSome(ctx)) + result = viableCallableLambda(call, TCallSome(ctx)) or - exists(DataFlowCallable enclosing | + exists(Callable enclosing | mayBenefitFromCallContextExt(call, enclosing) and enclosing = viableCallableExt(ctx) and - result = viableCallableLambda(call, TDataFlowCallNone()) + result = viableCallableLambda(call, TCallNone()) ) } @@ -1140,46 +1132,40 @@ module MakeImplCommon Lang> { cached module CachedCallContextSensitivity { private module CallContextSensitivityInput implements CallContextSensitivityInputSig { - predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - c = viableCallableExt(call) - } + predicate relevantCallEdgeIn(Call call, Callable c) { c = viableCallableExt(call) } - predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - c = viableCallableExt(call) - } + predicate relevantCallEdgeOut(Call call, Callable c) { c = viableCallableExt(call) } } private module Impl1 = CallContextSensitivity; cached - predicate reducedViableImplInCallContext( - DataFlowCall call, DataFlowCallable c, DataFlowCall ctx - ) { + predicate reducedViableImplInCallContext(Call call, Callable c, Call ctx) { Impl1::reducedViableImplInCallContext(call, c, ctx) } cached - predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable c) { - Impl1::recordDataFlowCallSiteUnreachable(call, c) + predicate recordCallSiteUnreachable(Call call, Callable c) { + Impl1::recordCallSiteUnreachable(call, c) } cached - predicate reducedViableImplInReturn(DataFlowCallable c, DataFlowCall call) { + predicate reducedViableImplInReturn(Callable c, Call call) { Impl1::reducedViableImplInReturn(c, call) } cached - CcCall getSpecificCallContextCall(DataFlowCall call, DataFlowCallable c) { + CcCall getSpecificCallContextCall(Call call, Callable c) { result = Impl1::getSpecificCallContextCall(call, c) } cached - predicate callContextAffectsDispatch(DataFlowCall call, Cc ctx) { + predicate callContextAffectsDispatch(Call call, Cc ctx) { Impl1::callContextAffectsDispatch(call, ctx) } cached - CcNoCall getSpecificCallContextReturn(DataFlowCallable c, DataFlowCall call) { + CcNoCall getSpecificCallContextReturn(Callable c, Call call) { result = Impl1::getSpecificCallContextReturn(c, call) } @@ -1187,8 +1173,8 @@ module MakeImplCommon Lang> { predicate reducedViableImplInCallContext = CachedCallContextSensitivity::reducedViableImplInCallContext/3; - predicate recordDataFlowCallSiteUnreachable = - CachedCallContextSensitivity::recordDataFlowCallSiteUnreachable/2; + predicate recordCallSiteUnreachable = + CachedCallContextSensitivity::recordCallSiteUnreachable/2; predicate getSpecificCallContextCall = CachedCallContextSensitivity::getSpecificCallContextCall/2; @@ -1214,12 +1200,12 @@ module MakeImplCommon Lang> { predicate instanceofCcNoCall(CcNoCall cc) { any() } cached - DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CcCall ctx) { + Callable viableImplCallContextReduced(Call call, CcCall ctx) { result = Impl2::viableImplCallContextReduced(call, ctx) } cached - DataFlowCall viableImplCallContextReducedReverse(DataFlowCallable callable, CcNoCall ctx) { + Call viableImplCallContextReducedReverse(Callable callable, CcNoCall ctx) { result = Impl2::viableImplCallContextReducedReverse(callable, ctx) } } @@ -1229,7 +1215,7 @@ module MakeImplCommon Lang> { * and `p` has position `ppos`. */ pragma[nomagic] - private predicate viableParam(DataFlowCall call, ParameterPosition ppos, ParamNode p) { + private predicate viableParam(Call call, ParameterPosition ppos, ParamNode p) { p.isParameterOf(viableCallableExt(call), ppos) } @@ -1238,7 +1224,7 @@ module MakeImplCommon Lang> { * dispatch into account. */ cached - predicate viableParamArg(DataFlowCall call, ParamNode p, ArgNode arg) { + predicate viableParamArg(Call call, ParamNode p, ArgNode arg) { exists(ParameterPosition ppos | viableParam(call, ppos, p) and argumentPositionMatch(call, arg, ppos) and @@ -1252,12 +1238,12 @@ module MakeImplCommon Lang> { * dispatch into account. */ cached - predicate viableParamArgEx(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) { + predicate viableParamArgEx(Call call, ParamNodeEx p, ArgNodeEx arg) { viableParamArg(call, p.asNode(), arg.asNode()) } pragma[nomagic] - private ReturnPosition viableReturnPos(DataFlowCall call, ReturnKindExt kind) { + private ReturnPosition viableReturnPos(Call call, ReturnKindExt kind) { viableCallableExt(call) = result.getCallable() and kind = result.getKind() } @@ -1267,7 +1253,7 @@ module MakeImplCommon Lang> { * taking virtual dispatch into account. */ cached - predicate viableReturnPosOut(DataFlowCall call, ReturnPosition pos, OutNodeExt out) { + predicate viableReturnPosOut(Call call, ReturnPosition pos, OutNodeExt out) { exists(ReturnKindExt kind | pos = viableReturnPos(call, kind) and out = getAnOutNodeExt(call, kind) @@ -1279,7 +1265,7 @@ module MakeImplCommon Lang> { * taking virtual dispatch into account. */ cached - predicate viableReturnPosOutEx(DataFlowCall call, ReturnPosition pos, OutNodeEx out) { + predicate viableReturnPosOutEx(Call call, ReturnPosition pos, OutNodeEx out) { viableReturnPosOut(call, pos, out.asNode()) } @@ -1360,7 +1346,7 @@ module MakeImplCommon Lang> { pragma[nomagic] private predicate argumentValueFlowsThroughCand0( - DataFlowCall call, ArgNode arg, ReturnKind kind, boolean read + Call call, ArgNode arg, ReturnKind kind, boolean read ) { exists(ParamNode param | viableParamArg(call, param, arg) | parameterValueFlowReturnCand(param, kind, read) @@ -1374,7 +1360,7 @@ module MakeImplCommon Lang> { * `read` indicates whether it is contents of `arg` that can flow to `out`. */ predicate argumentValueFlowsThroughCand(ArgNode arg, Node out, boolean read) { - exists(DataFlowCall call, ReturnKind kind | + exists(Call call, ReturnKind kind | argumentValueFlowsThroughCand0(call, arg, kind, read) and out = getAnOutNode(call, kind) ) @@ -1475,7 +1461,7 @@ module MakeImplCommon Lang> { else // check that `ctx1` is compatible with `ctx2` for at least _some_ outer call, // and then (arbitrarily) continue with `ctx2` - exists(DataFlowCall someOuterCall, DataFlowCallable callable | + exists(Call someOuterCall, Callable callable | someOuterCall = CachedCallContextSensitivity::viableImplCallContextReducedReverse(callable, ctx1) and someOuterCall = @@ -1517,12 +1503,11 @@ module MakeImplCommon Lang> { pragma[nomagic] private predicate argumentValueFlowsThrough0( - DataFlowCall call, ArgNode arg, ReturnKind kind, ReadStepTypesOption read, string model, + Call call, ArgNode arg, ReturnKind kind, ReadStepTypesOption read, string model, CachedCallContextSensitivity::CcNoCall outerCtx ) { exists( - ParamNode param, DataFlowCallable callable, - CachedCallContextSensitivity::CcNoCall innerCtx + ParamNode param, Callable callable, CachedCallContextSensitivity::CcNoCall innerCtx | viableParamArg(call, param, arg) and parameterValueFlowReturn(param, kind, read, model, innerCtx) and @@ -1541,7 +1526,7 @@ module MakeImplCommon Lang> { ArgNode arg, ReadStepTypesOption read, Node out, string model, CachedCallContextSensitivity::CcNoCall ctx ) { - exists(DataFlowCall call, ReturnKind kind | + exists(Call call, ReturnKind kind | argumentValueFlowsThrough0(call, arg, kind, read, model, ctx) and out = getAnOutNode(call, kind) | @@ -1622,9 +1607,7 @@ module MakeImplCommon Lang> { } cached - predicate storeSet( - Node node1, ContentSet c, Node node2, DataFlowType contentType, DataFlowType containerType - ) { + predicate storeSet(Node node1, ContentSet c, Node node2, Type contentType, Type containerType) { storeStep(node1, c, node2) and contentType = getNodeDataFlowType(node1) and containerType = getNodeDataFlowType(node2) @@ -1649,9 +1632,7 @@ module MakeImplCommon Lang> { * been stored into, in order to handle cases like `x.f1.f2 = y`. */ cached - predicate storeEx( - NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType - ) { + predicate storeEx(NodeEx node1, Content c, NodeEx node2, Type contentType, Type containerType) { exists(ContentSet cs | c = cs.getAStoreContent() and storeSet(pragma[only_bind_into](node1.asNode()), cs, pragma[only_bind_into](node2.asNode()), @@ -1672,7 +1653,7 @@ module MakeImplCommon Lang> { fromPre = fromNode.getPreUpdateNode() and toPre = toNode.getPreUpdateNode() | - exists(DataFlowCall c | + exists(Call c | // Does the language-specific simpleLocalFlowStep already model flow // from function input to output? fromPre = getAnOutNode(c, _) and @@ -1700,11 +1681,10 @@ module MakeImplCommon Lang> { ContentApprox getContentApproxCached(Content c) { result = getContentApprox(c) } cached - newtype TCallEdge = - TMkCallEdge(DataFlowCall call, DataFlowCallable tgt) { viableCallableExt(call) = tgt } + newtype TCallEdge = TMkCallEdge(Call call, Callable tgt) { viableCallableExt(call) = tgt } private NodeRegion getAnUnreachableRegion(TCallEdge edge) { - exists(DataFlowCall call, DataFlowCallable tgt | + exists(Call call, Callable tgt | edge = mkCallEdge(call, tgt) and getNodeRegionEnclosingCallable(result) = tgt and isUnreachableInCallCached(result, call) @@ -1726,7 +1706,7 @@ module MakeImplCommon Lang> { } cached - DataFlowCallable getEnclosingCallable() { + Callable getEnclosingCallable() { exists(NodeRegion nr | super.contains(nr) and result = getNodeRegionEnclosingCallable(nr)) } } @@ -1739,14 +1719,14 @@ module MakeImplCommon Lang> { class UnreachableSetOption = UnreachableSetOption::Option; pragma[nomagic] - private predicate hasValueReturnKindIn(ReturnNode ret, ReturnKindExt kind, DataFlowCallable c) { + private predicate hasValueReturnKindIn(ReturnNode ret, ReturnKindExt kind, Callable c) { c = getNodeEnclosingCallable(ret) and kind = TValueReturn(ret.getKind()) } pragma[nomagic] private predicate hasParamReturnKindIn( - PostUpdateNode n, ParamNode p, ReturnKindExt kind, DataFlowCallable c + PostUpdateNode n, ParamNode p, ReturnKindExt kind, Callable c ) { c = getNodeEnclosingCallable(n) and paramReturnNode(n, p, _, kind) @@ -1754,7 +1734,7 @@ module MakeImplCommon Lang> { cached newtype TReturnPosition = - TReturnPosition0(DataFlowCallable c, ReturnKindExt kind) { + TReturnPosition0(Callable c, ReturnKindExt kind) { hasValueReturnKindIn(_, kind, c) or hasParamReturnKindIn(_, _, kind, c) @@ -1762,7 +1742,7 @@ module MakeImplCommon Lang> { cached ReturnPosition getValueReturnPosition(ReturnNode ret) { - exists(ReturnKindExt kind, DataFlowCallable c | + exists(ReturnKindExt kind, Callable c | hasValueReturnKindIn(ret, kind, c) and result = TReturnPosition0(c, kind) ) @@ -1770,7 +1750,7 @@ module MakeImplCommon Lang> { cached ReturnPosition getParamReturnPosition(PostUpdateNode n, ParamNode p) { - exists(ReturnKindExt kind, DataFlowCallable c | + exists(ReturnKindExt kind, Callable c | hasParamReturnKindIn(n, p, kind, c) and result = TReturnPosition0(c, kind) ) @@ -1792,9 +1772,9 @@ module MakeImplCommon Lang> { TBooleanSome(boolean b) { b = true or b = false } cached - newtype TDataFlowCallOption = - TDataFlowCallNone() or - TDataFlowCallSome(DataFlowCall call) + newtype TCallOption = + TCallNone() or + TCallSome(Call call) cached newtype TReturnCtx = @@ -1863,23 +1843,17 @@ module MakeImplCommon Lang> { bindingset[call, tgt] pragma[inline_late] - private TCallEdge mkCallEdge(DataFlowCall call, DataFlowCallable tgt) { - result = TMkCallEdge(call, tgt) - } + private TCallEdge mkCallEdge(Call call, Callable tgt) { result = TMkCallEdge(call, tgt) } bindingset[t1, t2] pragma[inline_late] - predicate compatibleTypesFilter(DataFlowType t1, DataFlowType t2) { - compatibleTypesCached(t1, t2) - } + predicate compatibleTypesFilter(Type t1, Type t2) { compatibleTypesCached(t1, t2) } bindingset[t1, t2] pragma[inline_late] - predicate typeStrongerThanFilter(DataFlowType t1, DataFlowType t2) { - typeStrongerThanCached(t1, t2) - } + predicate typeStrongerThanFilter(Type t1, Type t2) { typeStrongerThanCached(t1, t2) } - private predicate callEdge(DataFlowCall call, DataFlowCallable c, ArgNode arg, ParamNode p) { + private predicate callEdge(Call call, Callable c, ArgNode arg, ParamNode p) { viableParamArg(call, p, arg) and c = getNodeEnclosingCallable(p) } @@ -1888,27 +1862,27 @@ module MakeImplCommon Lang> { predicate enableTypeFlow(); /** Holds if the edge is possibly needed in the direction `call` to `c`. */ - predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c); + predicate relevantCallEdgeIn(Call call, Callable c); /** Holds if the edge is possibly needed in the direction `c` to `call`. */ - predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c); + predicate relevantCallEdgeOut(Call call, Callable c); /** * Holds if the edge is followed in data flow in the direction `call` to `c` * and the call context `cc`. */ - predicate dataFlowTakenCallEdgeIn(DataFlowCall call, DataFlowCallable c, boolean cc); + predicate dataFlowTakenCallEdgeIn(Call call, Callable c, boolean cc); /** * Holds if the edge is followed in data flow in the direction `c` to `call`. */ - predicate dataFlowTakenCallEdgeOut(DataFlowCall call, DataFlowCallable c); + predicate dataFlowTakenCallEdgeOut(Call call, Callable c); /** * Holds if data flow enters `c` with call context `cc` without using a call * edge. */ - predicate dataFlowNonCallEntry(DataFlowCallable c, boolean cc); + predicate dataFlowNonCallEntry(Callable c, boolean cc); } /** @@ -1924,9 +1898,7 @@ module MakeImplCommon Lang> { * given in `typeFlowValidEdgeIn` and `typeFlowValidEdgeOut`. */ module TypeFlow { - private predicate relevantCallEdge( - DataFlowCall call, DataFlowCallable c, ArgNode arg, ParamNode p - ) { + private predicate relevantCallEdge(Call call, Callable c, ArgNode arg, ParamNode p) { callEdge(call, c, arg, p) and ( Input::relevantCallEdgeIn(call, c) or @@ -1954,19 +1926,19 @@ module MakeImplCommon Lang> { private predicate trackedArgTypeCand(ArgNode arg) { Input::enableTypeFlow() and ( - exists(ParamNode p, DataFlowType at, DataFlowType pt | - nodeDataFlowType(arg, at) and - nodeDataFlowType(p, pt) and + exists(ParamNode p, Type at, Type pt | + nodeType(arg, at) and + nodeType(p, pt) and relevantCallEdge(_, _, arg, p) and typeStrongerThanFilter(pt, at) ) or - exists(ParamNode p, DataFlowType at, DataFlowType pt | + exists(ParamNode p, Type at, Type pt | // A call edge may implicitly strengthen a type by ensuring that a // specific argument node was reached if the type of that argument was // strengthened via a cast. - nodeDataFlowType(arg, at) and - nodeDataFlowType(p, pt) and + nodeType(arg, at) and + nodeType(p, pt) and paramMustFlow(p, arg) and relevantCallEdge(_, _, arg, _) and typeStrongerThanFilter(at, pt) @@ -1985,10 +1957,7 @@ module MakeImplCommon Lang> { * argument nodes. */ private predicate trackedParamType(ParamNode p) { - exists( - DataFlowCall call1, DataFlowCallable c1, ArgNode argOut, DataFlowCall call2, - DataFlowCallable c2, ArgNode argIn - | + exists(Call call1, Callable c1, ArgNode argOut, Call call2, Callable c2, ArgNode argIn | // Data flow may exit `call1` and enter `call2`. If a stronger type is // known for `argOut`, `argIn` may reach a strengthening, and both are // determined by the same parameter `p` so we know they're equal, then @@ -2004,10 +1973,10 @@ module MakeImplCommon Lang> { paramMustFlow(p, argIn) ) or - exists(ArgNode arg, DataFlowType at, DataFlowType pt | + exists(ArgNode arg, Type at, Type pt | trackedParamTypeCand(p) and - nodeDataFlowType(arg, at) and - nodeDataFlowType(p, pt) and + nodeType(arg, at) and + nodeType(p, pt) and relevantCallEdge(_, _, arg, p) and typeStrongerThanFilter(at, pt) ) @@ -2033,7 +2002,7 @@ module MakeImplCommon Lang> { } pragma[nomagic] - private predicate returnCallDeterminesParam(DataFlowCall call, ParamNode p) { + private predicate returnCallDeterminesParam(Call call, ParamNode p) { exists(ArgNode arg | trackedArgType(arg) and arg.argumentOf(call, _) and @@ -2041,22 +2010,22 @@ module MakeImplCommon Lang> { ) } - private predicate returnCallLeavesParamUndetermined(DataFlowCall call, ParamNode p) { + private predicate returnCallLeavesParamUndetermined(Call call, ParamNode p) { trackedParamType(p) and call.getEnclosingCallable() = getNodeEnclosingCallable(p) and not returnCallDeterminesParam(call, p) } pragma[nomagic] - private predicate trackedParamWithType(ParamNode p, DataFlowType t, DataFlowCallable c) { + private predicate trackedParamWithType(ParamNode p, Type t, Callable c) { trackedParamType(p) and c = getNodeEnclosingCallable(p) and - nodeDataFlowType(p, t) + nodeType(p, t) } pragma[nomagic] private predicate dataFlowTakenCallEdgeIn( - DataFlowCall call, DataFlowCallable c, ArgNode arg, ParamNode p, boolean cc + Call call, Callable c, ArgNode arg, ParamNode p, boolean cc ) { Input::dataFlowTakenCallEdgeIn(call, c, cc) and callEdge(call, c, arg, p) and @@ -2064,9 +2033,7 @@ module MakeImplCommon Lang> { } pragma[nomagic] - private predicate dataFlowTakenCallEdgeOut( - DataFlowCall call, DataFlowCallable c, ArgNode arg, ParamNode p - ) { + private predicate dataFlowTakenCallEdgeOut(Call call, Callable c, ArgNode arg, ParamNode p) { Input::dataFlowTakenCallEdgeOut(call, c) and callEdge(call, c, arg, p) and trackedArgType(arg) and @@ -2079,7 +2046,7 @@ module MakeImplCommon Lang> { */ bindingset[t1, t2] pragma[inline_late] - DataFlowType getStrongestType(DataFlowType t1, DataFlowType t2) { + Type getStrongestType(Type t1, Type t2) { if typeStrongerThanCached(t2, t1) then result = t2 else ( @@ -2092,10 +2059,10 @@ module MakeImplCommon Lang> { * parameter `p` through an in-going edge in the current data flow stage. */ pragma[nomagic] - private predicate typeFlowParamTypeCand(ParamNode p, DataFlowType t) { + private predicate typeFlowParamTypeCand(ParamNode p, Type t) { exists(ArgNode arg, boolean outercc | dataFlowTakenCallEdgeIn(_, _, arg, p, outercc) and - if trackedArgType(arg) then typeFlowArgType(arg, t, outercc) else nodeDataFlowType(arg, t) + if trackedArgType(arg) then typeFlowArgType(arg, t, outercc) else nodeType(arg, t) ) } @@ -2104,32 +2071,32 @@ module MakeImplCommon Lang> { * context `cc` and that the current data flow stage has reached this * context. */ - private predicate typeFlowParamType(ParamNode p, DataFlowType t, boolean cc) { - exists(DataFlowCallable c | + private predicate typeFlowParamType(ParamNode p, Type t, boolean cc) { + exists(Callable c | Input::dataFlowNonCallEntry(c, cc) and trackedParamWithType(p, t, c) ) or - exists(DataFlowType t1, DataFlowType t2 | + exists(Type t1, Type t2 | cc = true and typeFlowParamTypeCand(p, t1) and - nodeDataFlowType(p, t2) and + nodeType(p, t2) and t = getStrongestType(t1, t2) ) or - exists(ArgNode arg, DataFlowType t1, DataFlowType t2 | + exists(ArgNode arg, Type t1, Type t2 | cc = false and typeFlowArgTypeFromReturn(arg, t1) and paramMustFlow(p, arg) and - nodeDataFlowType(p, t2) and + nodeType(p, t2) and t = getStrongestType(t1, t2) ) or - exists(DataFlowCall call | + exists(Call call | cc = false and Input::dataFlowTakenCallEdgeOut(call, _) and returnCallLeavesParamUndetermined(call, p) and - nodeDataFlowType(p, t) + nodeType(p, t) ) } @@ -2138,11 +2105,11 @@ module MakeImplCommon Lang> { * the current data flow stage has reached the call of `arg` from one of its * call targets. */ - private predicate typeFlowArgTypeFromReturn(ArgNode arg, DataFlowType t) { - exists(ParamNode p, DataFlowType t1, DataFlowType t2 | + private predicate typeFlowArgTypeFromReturn(ArgNode arg, Type t) { + exists(ParamNode p, Type t1, Type t2 | dataFlowTakenCallEdgeOut(_, _, arg, p) and - (if trackedParamType(p) then typeFlowParamType(p, t1, false) else nodeDataFlowType(p, t1)) and - nodeDataFlowType(arg, t2) and + (if trackedParamType(p) then typeFlowParamType(p, t1, false) else nodeType(p, t1)) and + nodeType(arg, t2) and t = getStrongestType(t1, t2) ) } @@ -2152,19 +2119,19 @@ module MakeImplCommon Lang> { * context `cc` and that the current data flow stage has reached this * context. */ - private predicate typeFlowArgType(ArgNode arg, DataFlowType t, boolean cc) { + private predicate typeFlowArgType(ArgNode arg, Type t, boolean cc) { trackedArgType(arg) and ( - exists(ParamNode p, DataFlowType t1, DataFlowType t2 | + exists(ParamNode p, Type t1, Type t2 | paramMustFlow(p, arg) and typeFlowParamType(p, t1, cc) and - nodeDataFlowType(arg, t2) and + nodeType(arg, t2) and t = getStrongestType(t1, t2) ) or cc = [true, false] and not paramMustFlow(_, arg) and - nodeDataFlowType(arg, t) + nodeType(arg, t) ) } @@ -2174,7 +2141,7 @@ module MakeImplCommon Lang> { typeFlowParamType(n, _, _) or typeFlowArgTypeFromReturn(n, _) or typeFlowArgType(n, _, _) ) and tuples = - count(Node n, DataFlowType t, boolean cc | + count(Node n, Type t, boolean cc | typeFlowParamType(n, t, cc) or typeFlowArgTypeFromReturn(n, t) and cc = false @@ -2187,13 +2154,13 @@ module MakeImplCommon Lang> { * Holds if the `arg`-to-`p` edge should be considered for validation of the * corresponding call edge in the in-going direction. */ - private predicate relevantArgParamIn(ArgNode arg, ParamNode p, DataFlowType pt) { - exists(DataFlowCall call, DataFlowCallable c | + private predicate relevantArgParamIn(ArgNode arg, ParamNode p, Type pt) { + exists(Call call, Callable c | Input::relevantCallEdgeIn(call, c) and callEdge(call, c, arg, p) and paramMustFlow(_, arg) and trackedArgType(arg) and - nodeDataFlowType(p, pt) + nodeType(p, pt) ) } @@ -2202,7 +2169,7 @@ module MakeImplCommon Lang> { * is consistent with the static type of `p`. */ private predicate validArgParamIn(ArgNode arg, ParamNode p, boolean cc) { - exists(DataFlowType t1, DataFlowType t2 | + exists(Type t1, Type t2 | typeFlowArgType(arg, t1, cc) and relevantArgParamIn(arg, p, t2) and compatibleTypesFilter(t1, t2) @@ -2214,7 +2181,7 @@ module MakeImplCommon Lang> { * call context `cc`. */ pragma[nomagic] - predicate typeFlowValidEdgeIn(DataFlowCall call, DataFlowCallable c, boolean cc) { + predicate typeFlowValidEdgeIn(Call call, Callable c, boolean cc) { Input::relevantCallEdgeIn(call, c) and cc = [true, false] and ( @@ -2232,12 +2199,12 @@ module MakeImplCommon Lang> { * Holds if the `arg`-to-`p` edge should be considered for validation of the * corresponding call edge in the out-going direction. */ - private predicate relevantArgParamOut(ArgNode arg, ParamNode p, DataFlowType argt) { - exists(DataFlowCall call, DataFlowCallable c | + private predicate relevantArgParamOut(ArgNode arg, ParamNode p, Type argt) { + exists(Call call, Callable c | Input::relevantCallEdgeOut(call, c) and callEdge(call, c, arg, p) and trackedParamType(p) and - nodeDataFlowType(arg, argt) + nodeType(arg, argt) ) } @@ -2246,7 +2213,7 @@ module MakeImplCommon Lang> { * that is consistent with the static type of `arg`. */ private predicate validArgParamOut(ArgNode arg, ParamNode p) { - exists(DataFlowType t1, DataFlowType t2 | + exists(Type t1, Type t2 | typeFlowParamType(p, t1, false) and relevantArgParamOut(arg, p, t2) and compatibleTypesFilter(t1, t2) @@ -2257,7 +2224,7 @@ module MakeImplCommon Lang> { * Holds if the edge `call`-to-`c` is valid in the out-going direction. */ pragma[nomagic] - predicate typeFlowValidEdgeOut(DataFlowCall call, DataFlowCallable c) { + predicate typeFlowValidEdgeOut(Call call, Callable c) { Input::relevantCallEdgeOut(call, c) and ( not Input::enableTypeFlow() @@ -2286,9 +2253,7 @@ module MakeImplCommon Lang> { } } - private predicate readStepWithTypes( - Node n1, DataFlowType container, ContentSet c, Node n2, DataFlowType content - ) { + private predicate readStepWithTypes(Node n1, Type container, ContentSet c, Node n2, Type content) { readSet(n1, c, n2) and container = getNodeDataFlowType(n1) and content = getNodeDataFlowType(n2) @@ -2296,18 +2261,18 @@ module MakeImplCommon Lang> { private newtype TReadStepTypesOption = TReadStepTypesNone() or - TReadStepTypesSome(DataFlowType container, ContentSet c, DataFlowType content) { + TReadStepTypesSome(Type container, ContentSet c, Type content) { readStepWithTypes(_, container, c, _, content) } private class ReadStepTypesOption extends TReadStepTypesOption { predicate isSome() { this instanceof TReadStepTypesSome } - DataFlowType getContainerType() { this = TReadStepTypesSome(result, _, _) } + Type getContainerType() { this = TReadStepTypesSome(result, _, _) } ContentSet getContent() { this = TReadStepTypesSome(_, result, _) } - DataFlowType getContentType() { this = TReadStepTypesSome(_, _, result) } + Type getContentType() { this = TReadStepTypesSome(_, _, result) } string toString() { if this.isSome() then result = "Some(..)" else result = "None()" } } @@ -2319,13 +2284,13 @@ module MakeImplCommon Lang> { abstract string toString(); /** Holds if this call context is relevant for `callable`. */ - abstract predicate relevantFor(DataFlowCallable callable); + abstract predicate relevantFor(Callable callable); } class LocalCallContextAny extends LocalCallContext, TAnyLocalCall { override string toString() { result = "LocalCcAny" } - override predicate relevantFor(DataFlowCallable callable) { any() } + override predicate relevantFor(Callable callable) { any() } } class LocalCallContextSpecificCall extends LocalCallContext, TSpecificLocalCall { @@ -2335,15 +2300,13 @@ module MakeImplCommon Lang> { override string toString() { result = "LocalCcCall" } - override predicate relevantFor(DataFlowCallable callable) { - ns.getEnclosingCallable() = callable - } + override predicate relevantFor(Callable callable) { ns.getEnclosingCallable() = callable } /** Holds if this call context makes `n` unreachable. */ predicate unreachable(NodeEx n) { ns.contains(n) } } - private DataFlowCallable getNodeRegionEnclosingCallable(NodeRegion nr) { + private Callable getNodeRegionEnclosingCallable(NodeRegion nr) { exists(Node n | nr.contains(n) | getNodeEnclosingCallable(n) = result) } @@ -2358,9 +2321,7 @@ module MakeImplCommon Lang> { * Holds if this node is the parameter of callable `c` at the specified * position. */ - predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { - parameterNode(this, c, pos) - } + predicate isParameterOf(Callable c, ParameterPosition pos) { parameterNode(this, c, pos) } } /** A data-flow node that represents a call argument. */ @@ -2368,9 +2329,7 @@ module MakeImplCommon Lang> { ArgNode() { argumentNode(this, _, _) } /** Holds if this argument occurs at the given position in the given call. */ - final predicate argumentOf(DataFlowCall call, ArgumentPosition pos) { - argumentNode(this, call, pos) - } + final predicate argumentOf(Call call, ArgumentPosition pos) { argumentNode(this, call, pos) } } /** @@ -2382,7 +2341,7 @@ module MakeImplCommon Lang> { } pragma[nomagic] - OutNodeExt getAnOutNodeExt(DataFlowCall call, ReturnKindExt k) { + OutNodeExt getAnOutNodeExt(Call call, ReturnKindExt k) { result = getAnOutNode(call, k.(ValueReturnKind).getKind()) or exists(ArgNode arg | @@ -2401,7 +2360,7 @@ module MakeImplCommon Lang> { abstract string toString(); /** Gets a node corresponding to data flow out of `call`. */ - final OutNodeEx getAnOutNodeEx(DataFlowCall call) { result = getAnOutNodeEx(call, this) } + final OutNodeEx getAnOutNodeEx(Call call) { result = getAnOutNodeEx(call, this) } } class ValueReturnKind extends ReturnKindExt, TValueReturn { @@ -2431,13 +2390,13 @@ module MakeImplCommon Lang> { /** A callable tagged with a relevant return kind. */ class ReturnPosition extends TReturnPosition0 { - private DataFlowCallable c; + private Callable c; private ReturnKindExt kind; ReturnPosition() { this = TReturnPosition0(c, kind) } /** Gets the callable. */ - DataFlowCallable getCallable() { result = c } + Callable getCallable() { result = c } /** Gets the return kind. */ ReturnKindExt getKind() { result = kind } @@ -2452,14 +2411,14 @@ module MakeImplCommon Lang> { * way around. */ pragma[inline] - DataFlowCallable getNodeEnclosingCallable(Node n) { + Callable getNodeEnclosingCallable(Node n) { nodeEnclosingCallable(pragma[only_bind_out](n), pragma[only_bind_into](result)) } /** Gets the type of `n` used for type pruning. */ pragma[inline] - DataFlowType getNodeDataFlowType(Node n) { - nodeDataFlowType(pragma[only_bind_out](n), pragma[only_bind_into](result)) + Type getNodeDataFlowType(Node n) { + nodeType(pragma[only_bind_out](n), pragma[only_bind_into](result)) } /** An optional Boolean value. */ @@ -2471,14 +2430,14 @@ module MakeImplCommon Lang> { } } - /** An optional `DataFlowCall`. */ - class DataFlowCallOption extends TDataFlowCallOption { + /** An optional `Call`. */ + class CallOption extends TCallOption { string toString() { - this = TDataFlowCallNone() and + this = TCallNone() and result = "(none)" or - exists(DataFlowCall call | - this = TDataFlowCallSome(call) and + exists(Call call | + this = TCallSome(call) and result = call.toString() ) } diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll index d709571fad0..f9eaea566cd 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplStage1.qll @@ -16,6 +16,7 @@ module MakeImplStage1 Lang> { private import MakeImpl as Impl private import DataFlowImplCommon::MakeImplCommon private import DataFlowImplCommonPublic + private import Aliases bindingset[this] signature class FlowStateSig; @@ -33,9 +34,9 @@ module MakeImplStage1 Lang> { Location getLocation(); - DataFlowType getDataFlowType(); + Type getType(); - DataFlowCallable getEnclosingCallable(); + Callable getEnclosingCallable(); } class ArgNd extends Nd; @@ -68,7 +69,7 @@ module MakeImplStage1 Lang> { predicate additionalJumpStep(Nd node1, Nd node2, string model); predicate localStep1( - Nd node1, Nd node2, boolean preservesValue, DataFlowType t, LocalCallContext lcc, string label + Nd node1, Nd node2, boolean preservesValue, Type t, LocalCallContext lcc, string label ); predicate isStateStep(Nd node1, Nd node2); @@ -90,30 +91,25 @@ module MakeImplStage1 Lang> { predicate revFlow(Nd node, Ap ap); - predicate callMayFlowThroughRev(DataFlowCall call); + predicate callMayFlowThroughRev(Call call); predicate parameterMayFlowThrough(ParamNd p, boolean emptyAp); predicate returnMayFlowThrough(RetNd ret, ReturnKindExt kind); - predicate storeStepCand( - Nd node1, Content c, Nd node2, DataFlowType contentType, DataFlowType containerType - ); + predicate storeStepCand(Nd node1, Content c, Nd node2, Type contentType, Type containerType); predicate readStepCand(Nd n1, Content c, Nd n2); - predicate callEdgeArgParam( - DataFlowCall call, DataFlowCallable c, ArgNd arg, ParamNd p, boolean emptyAp - ); + predicate callEdgeArgParam(Call call, Callable c, ArgNd arg, ParamNd p, boolean emptyAp); predicate callEdgeReturn( - DataFlowCall call, DataFlowCallable c, RetNd ret, ReturnKindExt kind, Nd out, - boolean allowsFieldFlow + Call call, Callable c, RetNd ret, ReturnKindExt kind, Nd out, boolean allowsFieldFlow ); - predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c); + predicate relevantCallEdgeIn(Call call, Callable c); - predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c); + predicate relevantCallEdgeOut(Call call, Callable c); // end StageSig predicate revFlowIsReadAndStored(Content c); @@ -416,7 +412,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate storeUnrestricted( - NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType + NodeEx node1, Content c, NodeEx node2, Type contentType, Type containerType ) { storeEx(node1, c, node2, contentType, containerType) and stepFilter(node1, node2) @@ -427,7 +423,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate store( - NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType + NodeEx node1, Content c, NodeEx node2, Type contentType, Type containerType ) { storeUnrestricted(node1, c, node2, contentType, containerType) and hasReadStep(c) @@ -504,7 +500,7 @@ module MakeImplStage1 Lang> { cc = false or // flow through a callable - exists(DataFlowCall call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind | + exists(Call call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind | fwdFlowOutFromArg(call, kind, node) and fwdFlowIsEntered(call, disallowReturnKind, cc) and kind != disallowReturnKind @@ -513,7 +509,7 @@ module MakeImplStage1 Lang> { // inline to reduce the number of iterations pragma[inline] - private predicate fwdFlowIn(DataFlowCall call, NodeEx arg, Cc cc, ParamNodeEx p) { + private predicate fwdFlowIn(Call call, NodeEx arg, Cc cc, ParamNodeEx p) { // call context cannot help reduce virtual dispatch fwdFlow(arg, cc) and viableParamArgEx(call, p, arg) and @@ -526,7 +522,7 @@ module MakeImplStage1 Lang> { ) or // call context may help reduce virtual dispatch - exists(DataFlowCallable target | + exists(Callable target | fwdFlowInReducedViableImplInSomeCallContext(call, arg, p, target) and target = viableImplInSomeFwdFlowCallContextExt(call) and cc = true @@ -550,9 +546,7 @@ module MakeImplStage1 Lang> { * Holds if an argument to `call` is reached in the flow covered by `fwdFlow`. */ pragma[nomagic] - private predicate fwdFlowIsEntered( - DataFlowCall call, ReturnKindExtOption disallowReturnKind, Cc cc - ) { + private predicate fwdFlowIsEntered(Call call, ReturnKindExtOption disallowReturnKind, Cc cc) { exists(ParamNodeEx p | fwdFlowIn(call, _, cc, p) and disallowReturnKind = getDisallowedReturnKind(p) @@ -561,7 +555,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate fwdFlowInReducedViableImplInSomeCallContext( - DataFlowCall call, NodeEx arg, ParamNodeEx p, DataFlowCallable target + Call call, NodeEx arg, ParamNodeEx p, Callable target ) { fwdFlow(arg, true) and viableParamArgEx(call, p, arg) and @@ -576,8 +570,8 @@ module MakeImplStage1 Lang> { * and to `ctx`s that are reachable in `fwdFlow`. */ pragma[nomagic] - private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(DataFlowCall call) { - exists(DataFlowCall ctx | + private Callable viableImplInSomeFwdFlowCallContextExt(Call call) { + exists(Call ctx | fwdFlowIsEntered(ctx, _, _) and result = viableImplInCallContextExt(call, ctx) ) @@ -626,7 +620,7 @@ module MakeImplStage1 Lang> { // inline to reduce the number of iterations pragma[inline] - private predicate fwdFlowOut(DataFlowCall call, ReturnKindExt kind, NodeEx out, Cc cc) { + private predicate fwdFlowOut(Call call, ReturnKindExt kind, NodeEx out, Cc cc) { exists(ReturnPosition pos | fwdFlowReturnPosition(pos, cc) and viableReturnPosOutEx(call, pos, out) and @@ -636,7 +630,7 @@ module MakeImplStage1 Lang> { } pragma[nomagic] - private predicate fwdFlowOutFromArg(DataFlowCall call, ReturnKindExtOption kind, NodeEx out) { + private predicate fwdFlowOutFromArg(Call call, ReturnKindExtOption kind, NodeEx out) { fwdFlowOut(call, kind.asSome(), out, true) } @@ -722,7 +716,7 @@ module MakeImplStage1 Lang> { ) or // flow through a callable - exists(DataFlowCall call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind | + exists(Call call, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind | revFlowIsReturned(call, kind, toReturn) and revFlowInToReturn(call, disallowReturnKind, node) and kind != disallowReturnKind @@ -762,7 +756,7 @@ module MakeImplStage1 Lang> { } pragma[nomagic] - predicate viableReturnPosOutNodeCandFwd1(DataFlowCall call, ReturnPosition pos, NodeEx out) { + predicate viableReturnPosOutNodeCandFwd1(Call call, ReturnPosition pos, NodeEx out) { fwdFlowReturnPosition(pos, _) and viableReturnPosOutEx(call, pos, out) } @@ -776,20 +770,20 @@ module MakeImplStage1 Lang> { } pragma[nomagic] - predicate viableParamArgNodeCandFwd1(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) { + predicate viableParamArgNodeCandFwd1(Call call, ParamNodeEx p, ArgNodeEx arg) { fwdFlowIn(call, arg, _, p) } // inline to reduce the number of iterations pragma[inline] - private predicate revFlowIn(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, boolean toReturn) { + private predicate revFlowIn(Call call, ParamNodeEx p, ArgNodeEx arg, boolean toReturn) { revFlow(p, toReturn) and viableParamArgNodeCandFwd1(call, p, arg) } pragma[nomagic] private predicate revFlowInToReturn( - DataFlowCall call, ReturnKindExtOption disallowReturnKind, ArgNodeEx arg + Call call, ReturnKindExtOption disallowReturnKind, ArgNodeEx arg ) { exists(ParamNodeEx p | revFlowIn(call, p, arg, true) and @@ -803,9 +797,7 @@ module MakeImplStage1 Lang> { * reaching an argument of `call`. */ pragma[nomagic] - private predicate revFlowIsReturned( - DataFlowCall call, ReturnKindExtOption kind, boolean toReturn - ) { + private predicate revFlowIsReturned(Call call, ReturnKindExtOption kind, boolean toReturn) { exists(NodeEx out | revFlow(out, toReturn) and fwdFlowOutFromArg(call, kind, out) @@ -840,7 +832,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] predicate storeStepCand( - NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType + NodeEx node1, Content c, NodeEx node2, Type contentType, Type containerType ) { revFlowIsReadAndStored(c) and revFlow(node2) and @@ -866,7 +858,7 @@ module MakeImplStage1 Lang> { /** Holds if flow may return from `callable`. */ pragma[nomagic] - private predicate returnFlowCallableNodeCand(DataFlowCallable callable, ReturnKindExt kind) { + private predicate returnFlowCallableNodeCand(Callable callable, ReturnKindExt kind) { exists(RetNodeEx ret | throughFlowNodeCand(ret) and callable = ret.getEnclosingCallable() and @@ -880,7 +872,7 @@ module MakeImplStage1 Lang> { */ pragma[nomagic] predicate parameterMayFlowThrough(ParamNodeEx p, boolean emptyAp) { - exists(DataFlowCallable c, ReturnKindExt kind | + exists(Callable c, ReturnKindExt kind | throughFlowNodeCand(p) and returnFlowCallableNodeCand(c, kind) and p.getEnclosingCallable() = c and @@ -896,7 +888,7 @@ module MakeImplStage1 Lang> { } pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCall call) { + predicate callMayFlowThroughRev(Call call) { exists( ArgNodeEx arg, ReturnKindExtOption kind, ReturnKindExtOption disallowReturnKind, boolean toReturn @@ -909,7 +901,7 @@ module MakeImplStage1 Lang> { } predicate callEdgeArgParam( - DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp + Call call, Callable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { exists(boolean allowsFieldFlow | flowIntoCallNodeCand1(call, arg, p, allowsFieldFlow) and @@ -923,7 +915,7 @@ module MakeImplStage1 Lang> { } predicate callEdgeReturn( - DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + Call call, Callable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow ) { flowOutOfCallNodeCand1(call, ret, kind, out, allowsFieldFlow) and @@ -948,7 +940,7 @@ module MakeImplStage1 Lang> { states = count(FlowState state | revFlowState(state)) and tuples = count(NodeEx n, boolean b | revFlow(n, b)) and calledges = - count(DataFlowCall call, DataFlowCallable c | + count(Call call, Callable c | callEdgeArgParam(call, c, _, _, _) or callEdgeReturn(call, c, _, _, _, _) ) @@ -980,11 +972,11 @@ module MakeImplStage1 Lang> { predicate callMayFlowThroughRev = Stage1::callMayFlowThroughRev/1; - predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { + predicate relevantCallEdgeIn(Call call, Callable c) { Stage1::callEdgeArgParam(call, c, _, _, _) } - predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { + predicate relevantCallEdgeOut(Call call, Callable c) { Stage1::callEdgeReturn(call, c, _, _, _, _) } @@ -993,19 +985,18 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate localStepNodeCand1( - NodeEx node1, NodeEx node2, boolean preservesValue, DataFlowType t, LocalCallContext lcc, - string label + NodeEx node1, NodeEx node2, boolean preservesValue, Type t, LocalCallContext lcc, string label ) { Stage1::revFlow(node1) and Stage1::revFlow(node2) and ( preservesValue = true and localFlowStepEx(node1, node2, label) and - t = node1.getDataFlowType() + t = node1.getType() or preservesValue = false and additionalLocalFlowStep(node1, node2, label) and - t = node2.getDataFlowType() + t = node2.getType() ) and lcc.relevantFor(node1.getEnclosingCallable()) and not isUnreachableInCall1(node1, lcc) and @@ -1014,20 +1005,20 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate localStateStepNodeCand1( - NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, DataFlowType t, - LocalCallContext lcc, string label + NodeEx node1, FlowState state1, NodeEx node2, FlowState state2, Type t, LocalCallContext lcc, + string label ) { Stage1::revFlow(node1) and Stage1::revFlow(node2) and additionalLocalStateStep(node1, state1, node2, state2, label) and - t = node2.getDataFlowType() and + t = node2.getType() and lcc.relevantFor(node1.getEnclosingCallable()) and not isUnreachableInCall1(node1, lcc) and not isUnreachableInCall1(node2, lcc) } pragma[nomagic] - private predicate viableReturnPosOutNodeCand1(DataFlowCall call, ReturnPosition pos, NodeEx out) { + private predicate viableReturnPosOutNodeCand1(Call call, ReturnPosition pos, NodeEx out) { Stage1::revFlow(out) and Stage1::viableReturnPosOutNodeCandFwd1(call, pos, out) } @@ -1039,7 +1030,7 @@ module MakeImplStage1 Lang> { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out + Call call, RetNodeEx ret, ReturnKindExt kind, NodeEx out ) { exists(ReturnPosition pos | viableReturnPosOutNodeCand1(call, pos, out) and @@ -1052,7 +1043,7 @@ module MakeImplStage1 Lang> { } pragma[nomagic] - private predicate viableParamArgNodeCand1(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) { + private predicate viableParamArgNodeCand1(Call call, ParamNodeEx p, ArgNodeEx arg) { Stage1::viableParamArgNodeCandFwd1(call, p, arg) and Stage1::revFlow(arg) } @@ -1062,7 +1053,7 @@ module MakeImplStage1 Lang> { * path from a source to a sink. */ pragma[nomagic] - private predicate flowIntoCallNodeCand1(DataFlowCall call, ArgNodeEx arg, ParamNodeEx p) { + private predicate flowIntoCallNodeCand1(Call call, ArgNodeEx arg, ParamNodeEx p) { viableParamArgNodeCand1(call, p, arg) and Stage1::revFlow(p) and not outBarrier(arg) and @@ -1081,9 +1072,7 @@ module MakeImplStage1 Lang> { } pragma[nomagic] - private predicate returnCallEdge1( - DataFlowCallable c, SndLevelScopeOption scope, DataFlowCall call, NodeEx out - ) { + private predicate returnCallEdge1(Callable c, SndLevelScopeOption scope, Call call, NodeEx out) { exists(RetNodeEx ret | flowOutOfCallNodeCand1(call, ret, _, out) and c = ret.getEnclosingCallable() @@ -1094,37 +1083,35 @@ module MakeImplStage1 Lang> { ) } - private int simpleDispatchFanoutOnReturn(DataFlowCall call, NodeEx out) { + private int simpleDispatchFanoutOnReturn(Call call, NodeEx out) { result = - strictcount(DataFlowCallable c, SndLevelScopeOption scope | - returnCallEdge1(c, scope, call, out) - ) + strictcount(Callable c, SndLevelScopeOption scope | returnCallEdge1(c, scope, call, out)) } pragma[nomagic] private predicate returnCallEdgeInCtx1( - DataFlowCallable c, SndLevelScopeOption scope, DataFlowCall call, NodeEx out, DataFlowCall ctx + Callable c, SndLevelScopeOption scope, Call call, NodeEx out, Call ctx ) { returnCallEdge1(c, scope, call, out) and c = viableImplInCallContextExt(call, ctx) } - private int ctxDispatchFanoutOnReturn(NodeEx out, DataFlowCall ctx) { - exists(DataFlowCall call, DataFlowCallable c | + private int ctxDispatchFanoutOnReturn(NodeEx out, Call ctx) { + exists(Call call, Callable c | simpleDispatchFanoutOnReturn(call, out) > 1 and not Stage1::revFlow(out, false) and call.getEnclosingCallable() = c and returnCallEdge1(c, _, ctx, _) and mayBenefitFromCallContextExt(call, _) and result = - count(DataFlowCallable tgt, SndLevelScopeOption scope | + count(Callable tgt, SndLevelScopeOption scope | returnCallEdgeInCtx1(tgt, scope, call, out, ctx) ) ) } private int ctxDispatchFanoutOnReturn(NodeEx out) { - result = max(DataFlowCall ctx | | ctxDispatchFanoutOnReturn(out, ctx)) + result = max(Call ctx | | ctxDispatchFanoutOnReturn(out, ctx)) } private int dispatchFanoutOnReturn(NodeEx out) { @@ -1142,7 +1129,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private int branch(ArgNodeEx n1) { result = - strictcount(DataFlowCallable c | + strictcount(Callable c | exists(NodeEx n | flowIntoCallNodeCand1(_, n1, n) and c = n.getEnclosingCallable() @@ -1158,7 +1145,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private int join(ParamNodeEx n2) { result = - strictcount(DataFlowCallable c | + strictcount(Callable c | exists(NodeEx n | flowIntoCallNodeCand1(_, n, n2) and c = n.getEnclosingCallable() @@ -1175,7 +1162,7 @@ module MakeImplStage1 Lang> { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow + Call call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow ) { flowOutOfCallNodeCand1(call, ret, kind, out) and exists(int j | @@ -1196,7 +1183,7 @@ module MakeImplStage1 Lang> { */ pragma[nomagic] private predicate flowIntoCallNodeCand1( - DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow + Call call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ) { flowIntoCallNodeCand1(call, arg, p) and exists(int b, int j | @@ -1298,9 +1285,9 @@ module MakeImplStage1 Lang> { Location getLocation() { result = node.getLocation() } - DataFlowType getDataFlowType() { result = node.getDataFlowType() } + Type getType() { result = node.getType() } - DataFlowCallable getEnclosingCallable() { result = node.getEnclosingCallable() } + Callable getEnclosingCallable() { result = node.getEnclosingCallable() } } class ArgNd extends Nd { @@ -1361,9 +1348,7 @@ module MakeImplStage1 Lang> { private Nd mkNodeState(NodeEx node, FlowState state) { result = TNodeState(node, state) } pragma[nomagic] - predicate storeStepCand( - Nd node1, Content c, Nd node2, DataFlowType contentType, DataFlowType containerType - ) { + predicate storeStepCand(Nd node1, Content c, Nd node2, Type contentType, Type containerType) { exists(NodeEx n1, NodeEx n2, FlowState s | Stage1::storeStepCand(n1, c, n2, contentType, containerType) and node1 = mkNodeState(n1, s) and @@ -1384,9 +1369,7 @@ module MakeImplStage1 Lang> { ) } - predicate callEdgeArgParam( - DataFlowCall call, DataFlowCallable c, ArgNd arg, ParamNd p, boolean emptyAp - ) { + predicate callEdgeArgParam(Call call, Callable c, ArgNd arg, ParamNd p, boolean emptyAp) { exists(ArgNodeEx arg0, ParamNodeEx p0, FlowState s | Stage1::callEdgeArgParam(call, c, arg0, p0, emptyAp) and arg = mkNodeState(arg0, s) and @@ -1397,8 +1380,7 @@ module MakeImplStage1 Lang> { } predicate callEdgeReturn( - DataFlowCall call, DataFlowCallable c, RetNd ret, ReturnKindExt kind, Nd out, - boolean allowsFieldFlow + Call call, Callable c, RetNd ret, ReturnKindExt kind, Nd out, boolean allowsFieldFlow ) { exists(RetNodeEx ret0, NodeEx out0, FlowState s | Stage1::callEdgeReturn(call, c, ret0, kind, out0, allowsFieldFlow) and @@ -1460,8 +1442,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] predicate localStep1( - Nd node1, Nd node2, boolean preservesValue, DataFlowType t, LocalCallContext lcc, - string label + Nd node1, Nd node2, boolean preservesValue, Type t, LocalCallContext lcc, string label ) { exists(NodeEx n1, NodeEx n2, FlowState s | localStepNodeCand1(n1, n2, preservesValue, t, lcc, label) and @@ -1522,7 +1503,7 @@ module MakeImplStage1 Lang> { predicate callContextNone = CachedCallContextSensitivity::ccNone/0; - private predicate callableStep(DataFlowCallable c1, DataFlowCallable c2) { + private predicate callableStep(Callable c1, Callable c2) { exists(NodeEx node1, NodeEx node2 | jumpStepEx1(node1, node2) or @@ -1542,23 +1523,23 @@ module MakeImplStage1 Lang> { ) } - private predicate interestingCallableSrc(DataFlowCallable c) { + private predicate interestingCallableSrc(Callable c) { exists(Node n | isRelevantSource(n, _) and c = getNodeEnclosingCallable(n)) or - exists(DataFlowCallable mid | interestingCallableSrc(mid) and callableStep(mid, c)) + exists(Callable mid | interestingCallableSrc(mid) and callableStep(mid, c)) } - private predicate interestingCallableSink(DataFlowCallable c) { + private predicate interestingCallableSink(Callable c) { exists(Node n | c = getNodeEnclosingCallable(n) | isRelevantSink(n, _) or isRelevantSink(n) ) or - exists(DataFlowCallable mid | interestingCallableSink(mid) and callableStep(c, mid)) + exists(Callable mid | interestingCallableSink(mid) and callableStep(c, mid)) } private newtype TCallableExt = - TCallable(DataFlowCallable c) { + TCallable(Callable c) { interestingCallableSrc(c) or interestingCallableSink(c) } or @@ -1570,7 +1551,7 @@ module MakeImplStage1 Lang> { private predicate callableExtSink(TCallableSink sink) { any() } private predicate callableExtStepFwd(TCallableExt ce1, TCallableExt ce2) { - exists(DataFlowCallable c1, DataFlowCallable c2 | + exists(Callable c1, Callable c2 | callableStep(c1, c2) and ce1 = TCallable(c1) and ce2 = TCallable(c2) @@ -1601,9 +1582,9 @@ module MakeImplStage1 Lang> { private int distSinkExt(TCallableExt c) = shortestDistances(callableExtSink/1, callableExtStepRev/2)(_, c, result) - private int distSrc(DataFlowCallable c) { result = distSrcExt(TCallable(c)) - 1 } + private int distSrc(Callable c) { result = distSrcExt(TCallable(c)) - 1 } - private int distSink(DataFlowCallable c) { result = distSinkExt(TCallable(c)) - 1 } + private int distSink(Callable c) { result = distSinkExt(TCallable(c)) - 1 } private newtype TPartialAccessPath = TPartialNil() or @@ -1667,7 +1648,7 @@ module MakeImplStage1 Lang> { private newtype TSummaryCtx3 = TSummaryCtx3None() or - TSummaryCtx3Some(DataFlowType t) + TSummaryCtx3Some(Type t) private newtype TSummaryCtx4 = TSummaryCtx4None() or @@ -1688,7 +1669,7 @@ module MakeImplStage1 Lang> { private newtype TPartialPathNode = TPartialPathNodeFwd( NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + TSummaryCtx3 sc3, TSummaryCtx4 sc4, Type t, PartialAccessPath ap ) { flagFwd() and sourceNode(node, state) and @@ -1697,7 +1678,7 @@ module MakeImplStage1 Lang> { sc2 = TSummaryCtx2None() and sc3 = TSummaryCtx3None() and sc4 = TSummaryCtx4None() and - t = node.getDataFlowType() and + t = node.getType() and ap = TPartialNil() and exists(explorationLimit()) or @@ -1732,16 +1713,16 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate partialPathStep( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, - TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, Type t, PartialAccessPath ap ) { partialPathStep1(mid, node, state, cc, sc1, sc2, sc3, sc4, _, t, ap) } bindingset[node, t0] - private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) { + private predicate strengthenType(NodeEx node, Type t0, Type t) { if node instanceof CastingNodeEx then - exists(DataFlowType nt | nt = node.getDataFlowType() | + exists(Type nt | nt = node.getType() | if typeStrongerThanFilter(nt, t0) then t = nt else ( @@ -1754,8 +1735,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate partialPathStep1( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, - TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t0, DataFlowType t, - PartialAccessPath ap + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, Type t0, Type t, PartialAccessPath ap ) { exists(boolean isStoreStep | partialPathStep0(mid, node, state, cc, sc1, sc2, sc3, sc4, t0, ap, isStoreStep) and @@ -1774,9 +1754,7 @@ module MakeImplStage1 Lang> { } pragma[nomagic] - private predicate partialPathTypeStrengthen( - DataFlowType t0, PartialAccessPath ap, DataFlowType t - ) { + private predicate partialPathTypeStrengthen(Type t0, PartialAccessPath ap, Type t) { partialPathStep1(_, _, _, _, _, _, _, _, t0, t, ap) and t0 != t } @@ -1885,7 +1863,7 @@ module MakeImplStage1 Lang> { TSummaryCtx2 sc2; TSummaryCtx3 sc3; TSummaryCtx4 sc4; - DataFlowType t; + Type t; PartialAccessPath ap; PartialPathNodeFwd() { @@ -1906,7 +1884,7 @@ module MakeImplStage1 Lang> { TSummaryCtx4 getSummaryCtx4() { result = sc4 } - DataFlowType getType() { result = t } + Type getType() { result = t } PartialAccessPath getAp() { result = ap } @@ -1968,7 +1946,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate partialPathStep0( PartialPathNodeFwd mid, NodeEx node, FlowState state, CallContext cc, TSummaryCtx1 sc1, - TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap, + TSummaryCtx2 sc2, TSummaryCtx3 sc3, TSummaryCtx4 sc4, Type t, PartialAccessPath ap, boolean isStoreStep ) { not isUnreachableInCall1(node, @@ -1992,7 +1970,7 @@ module MakeImplStage1 Lang> { sc3 = mid.getSummaryCtx3() and sc4 = mid.getSummaryCtx4() and mid.getAp() instanceof PartialAccessPathNil and - t = node.getDataFlowType() and + t = node.getType() and ap = TPartialNil() or additionalLocalStateStep(mid.getNodeEx(), mid.getState(), node, state, _) and @@ -2002,7 +1980,7 @@ module MakeImplStage1 Lang> { sc3 = mid.getSummaryCtx3() and sc4 = mid.getSummaryCtx4() and mid.getAp() instanceof PartialAccessPathNil and - t = node.getDataFlowType() and + t = node.getType() and ap = TPartialNil() ) and isStoreStep = false @@ -2026,7 +2004,7 @@ module MakeImplStage1 Lang> { sc3 = TSummaryCtx3None() and sc4 = TSummaryCtx4None() and mid.getAp() instanceof PartialAccessPathNil and - t = node.getDataFlowType() and + t = node.getType() and ap = TPartialNil() and isStoreStep = false or @@ -2037,7 +2015,7 @@ module MakeImplStage1 Lang> { sc3 = TSummaryCtx3None() and sc4 = TSummaryCtx4None() and mid.getAp() instanceof PartialAccessPathNil and - t = node.getDataFlowType() and + t = node.getType() and ap = TPartialNil() and isStoreStep = false or @@ -2050,7 +2028,7 @@ module MakeImplStage1 Lang> { sc4 = mid.getSummaryCtx4() and isStoreStep = true or - exists(DataFlowType t0, PartialAccessPath ap0, Content c | + exists(Type t0, PartialAccessPath ap0, Content c | partialPathReadStep(mid, t0, ap0, c, node, cc) and state = mid.getState() and sc1 = mid.getSummaryCtx1() and @@ -2084,10 +2062,10 @@ module MakeImplStage1 Lang> { pragma[inline] private predicate partialPathStoreStep( - PartialPathNodeFwd mid, DataFlowType t1, PartialAccessPath ap1, Content c, NodeEx node, - DataFlowType t2, PartialAccessPath ap2 + PartialPathNodeFwd mid, Type t1, PartialAccessPath ap1, Content c, NodeEx node, Type t2, + PartialAccessPath ap2 ) { - exists(NodeEx midNode, DataFlowType contentType | + exists(NodeEx midNode, Type contentType | midNode = mid.getNodeEx() and t1 = mid.getType() and ap1 = mid.getAp() and @@ -2100,11 +2078,11 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate apConsFwd( - DataFlowType t1, PartialAccessPath ap1, Content c, DataFlowType t2, PartialAccessPath ap2 + Type t1, PartialAccessPath ap1, Content c, Type t2, PartialAccessPath ap2 ) { partialPathStoreStep(_, t1, ap1, c, _, t2, ap2) or - exists(DataFlowType t0 | + exists(Type t0 | partialPathTypeStrengthen(t0, ap2, t2) and apConsFwd(t1, ap1, c, t0, ap2) ) @@ -2112,8 +2090,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate partialPathReadStep( - PartialPathNodeFwd mid, DataFlowType t, PartialAccessPath ap, Content c, NodeEx node, - CallContext cc + PartialPathNodeFwd mid, Type t, PartialAccessPath ap, Content c, NodeEx node, CallContext cc ) { exists(NodeEx midNode | midNode = mid.getNodeEx() and @@ -2126,8 +2103,8 @@ module MakeImplStage1 Lang> { } private predicate partialPathOutOfCallable0( - PartialPathNodeFwd mid, ReturnPosition pos, FlowState state, CallContext innercc, - DataFlowType t, PartialAccessPath ap + PartialPathNodeFwd mid, ReturnPosition pos, FlowState state, CallContext innercc, Type t, + PartialAccessPath ap ) { pos = mid.getNodeEx().(RetNodeEx).getReturnPosition() and state = mid.getState() and @@ -2139,10 +2116,10 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate partialPathOutOfCallable1( - PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, FlowState state, - CallContext cc, DataFlowType t, PartialAccessPath ap + PartialPathNodeFwd mid, Call call, ReturnKindExt kind, FlowState state, CallContext cc, + Type t, PartialAccessPath ap ) { - exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | + exists(ReturnPosition pos, Callable c, CallContext innercc | partialPathOutOfCallable0(mid, pos, state, innercc, t, ap) and c = pos.getCallable() and kind = pos.getKind() and @@ -2152,10 +2129,10 @@ module MakeImplStage1 Lang> { } private predicate partialPathOutOfCallable( - PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, DataFlowType t, + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, Type t, PartialAccessPath ap ) { - exists(ReturnKindExt kind, DataFlowCall call | + exists(ReturnKindExt kind, Call call | partialPathOutOfCallable1(mid, call, kind, state, cc, t, ap) and out = kind.getAnOutNodeEx(call) ) @@ -2163,8 +2140,8 @@ module MakeImplStage1 Lang> { pragma[noinline] private predicate partialPathIntoArg( - PartialPathNodeFwd mid, ParameterPosition ppos, FlowState state, CallContext cc, - DataFlowCall call, DataFlowType t, PartialAccessPath ap + PartialPathNodeFwd mid, ParameterPosition ppos, FlowState state, CallContext cc, Call call, + Type t, PartialAccessPath ap ) { exists(ArgNode arg, ArgumentPosition apos | arg = mid.getNodeEx().asNode() and @@ -2179,8 +2156,8 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate partialPathIntoCallable0( - PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, FlowState state, - CallContext outercc, DataFlowCall call, DataFlowType t, PartialAccessPath ap + PartialPathNodeFwd mid, Callable callable, ParameterPosition pos, FlowState state, + CallContext outercc, Call call, Type t, PartialAccessPath ap ) { partialPathIntoArg(mid, pos, state, outercc, call, t, ap) and callable = CachedCallContextSensitivity::resolveCall(call, outercc) @@ -2189,9 +2166,9 @@ module MakeImplStage1 Lang> { private predicate partialPathIntoCallable( PartialPathNodeFwd mid, ParamNodeEx p, FlowState state, CallContext outercc, CallContextCall innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, - TSummaryCtx4 sc4, DataFlowCall call, DataFlowType t, PartialAccessPath ap + TSummaryCtx4 sc4, Call call, Type t, PartialAccessPath ap ) { - exists(ParameterPosition pos, DataFlowCallable callable | + exists(ParameterPosition pos, Callable callable | partialPathIntoCallable0(mid, callable, pos, state, outercc, call, t, ap) and p.isParameterOf(callable, pos) and sc1 = TSummaryCtx1Param(p) and @@ -2206,7 +2183,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate paramFlowsThroughInPartialPath( ReturnKindExt kind, FlowState state, CallContextCall cc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, - TSummaryCtx3 sc3, TSummaryCtx4 sc4, DataFlowType t, PartialAccessPath ap + TSummaryCtx3 sc3, TSummaryCtx4 sc4, Type t, PartialAccessPath ap ) { exists(PartialPathNodeFwd mid, RetNodeEx ret | mid.getNodeEx() = ret and @@ -2224,8 +2201,8 @@ module MakeImplStage1 Lang> { pragma[noinline] private predicate partialPathThroughCallable0( - DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, FlowState state, - CallContext cc, DataFlowType t, PartialAccessPath ap + Call call, PartialPathNodeFwd mid, ReturnKindExt kind, FlowState state, CallContext cc, + Type t, PartialAccessPath ap ) { exists( CallContext innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, @@ -2237,10 +2214,10 @@ module MakeImplStage1 Lang> { } private predicate partialPathThroughCallable( - PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, DataFlowType t, + PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, Type t, PartialAccessPath ap ) { - exists(DataFlowCall call, ReturnKindExt kind | + exists(Call call, ReturnKindExt kind | partialPathThroughCallable0(call, mid, kind, state, cc, t, ap) and out = kind.getAnOutNodeEx(call) ) @@ -2411,7 +2388,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate revPartialPathIntoReturn( PartialPathNodeRev mid, ReturnPosition pos, FlowState state, TRevSummaryCtx1Some sc1, - TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3, DataFlowCall call, PartialAccessPath ap + TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3, Call call, PartialAccessPath ap ) { exists(NodeEx out | mid.getNodeEx() = out and @@ -2443,7 +2420,7 @@ module MakeImplStage1 Lang> { pragma[nomagic] private predicate revPartialPathThroughCallable0( - DataFlowCall call, PartialPathNodeRev mid, ArgumentPosition pos, FlowState state, + Call call, PartialPathNodeRev mid, ArgumentPosition pos, FlowState state, PartialAccessPath ap ) { exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3 | @@ -2456,7 +2433,7 @@ module MakeImplStage1 Lang> { private predicate revPartialPathThroughCallable( PartialPathNodeRev mid, ArgNodeEx node, FlowState state, PartialAccessPath ap ) { - exists(DataFlowCall call, ArgumentPosition pos | + exists(Call call, ArgumentPosition pos | revPartialPathThroughCallable0(call, mid, pos, state, ap) and node.argumentOf(call, pos) )