Data flow: Add aliases for removing DataFlow prefixes

This commit is contained in:
Tom Hvitved
2025-02-05 10:11:46 +01:00
parent bcec7ee234
commit 0f52fe92cf
5 changed files with 487 additions and 592 deletions

View File

@@ -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)
}

View File

@@ -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()
)
}

View File

@@ -17,6 +17,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
private import MakeImplStage1<Location, Lang>
private import DataFlowImplCommon::MakeImplCommon<Location, Lang>
private import DataFlowImplCommonPublic
private import Aliases
/**
* An input configuration for data flow using flow state. This signature equals
@@ -236,7 +237,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<StageSig PrevStage> {
@@ -292,7 +288,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> Lang> {
private module FwdFlowIn<flowThroughSig/0 flowThrough> {
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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> Lang> {
private module FwdTypeFlow = TypeFlow<FwdTypeFlowInput>;
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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> Lang> {
private module RevTypeFlow = TypeFlow<RevTypeFlowInput>;
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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<localStep1/6>::localFlowBigStep(node1, node2, preservesValue, t,
lcc, label)
@@ -2708,10 +2667,10 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
private module Stage3 = MkStage<Stage2>::Stage<Stage3Param>;
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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> Lang> {
private module Stage5Param implements MkStage<Stage4>::StageParam {
private module PrevStage = Stage4;
class Typ = DataFlowType;
class Typ = Type;
class Ap = AccessPathApprox;
@@ -3003,7 +2962,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> Lang> {
private module Stage6Param implements MkStage<Stage5>::StageParam {
private module PrevStage = Stage5;
class Typ = DataFlowType;
class Typ = Type;
class Ap = AccessPath;
@@ -3193,7 +3152,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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.

View File

@@ -16,6 +16,7 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> Lang> {
private import MakeImpl<Location, Lang> as Impl
private import DataFlowImplCommon::MakeImplCommon<Location, Lang>
private import DataFlowImplCommonPublic
private import Aliases
bindingset[this]
signature class FlowStateSig;
@@ -33,9 +34,9 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> Lang> {
Location getLocation();
DataFlowType getDataFlowType();
Type getType();
DataFlowCallable getEnclosingCallable();
Callable getEnclosingCallable();
}
class ArgNd extends Nd;
@@ -68,7 +69,7 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> Lang> {
private newtype TSummaryCtx3 =
TSummaryCtx3None() or
TSummaryCtx3Some(DataFlowType t)
TSummaryCtx3Some(Type t)
private newtype TSummaryCtx4 =
TSummaryCtx4None() or
@@ -1688,7 +1669,7 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> Lang> {
TSummaryCtx2 sc2;
TSummaryCtx3 sc3;
TSummaryCtx4 sc4;
DataFlowType t;
Type t;
PartialAccessPath ap;
PartialPathNodeFwd() {
@@ -1906,7 +1884,7 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> Lang> {
TSummaryCtx4 getSummaryCtx4() { result = sc4 }
DataFlowType getType() { result = t }
Type getType() { result = t }
PartialAccessPath getAp() { result = ap }
@@ -1968,7 +1946,7 @@ module MakeImplStage1<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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<LocationSig Location, InputSig<Location> 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)
)