Skip to content

Commit d5c3426

Browse files
committed
Data flow: Prune call-context sensitivity relations
1 parent 5be75e9 commit d5c3426

File tree

2 files changed

+436
-216
lines changed

2 files changed

+436
-216
lines changed

shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll

Lines changed: 123 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ module MakeImpl<InputSig Lang> {
588588
cc = false
589589
or
590590
cc = true and
591-
not reducedViableImplInCallContext(call, _, _)
591+
not CachedCallContextSensitivity::reducedViableImplInCallContext(call, _, _)
592592
)
593593
or
594594
// call context may help reduce virtual dispatch
@@ -611,7 +611,7 @@ module MakeImpl<InputSig Lang> {
611611
) {
612612
fwdFlow(arg, true) and
613613
viableParamArgEx(call, p, arg) and
614-
reducedViableImplInCallContext(call, _, _) and
614+
CachedCallContextSensitivity::reducedViableImplInCallContext(call, _, _) and
615615
target = p.getEnclosingCallable() and
616616
not fullBarrier(p)
617617
}
@@ -982,6 +982,14 @@ module MakeImpl<InputSig Lang> {
982982
exists(ap)
983983
}
984984

985+
predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) {
986+
callEdgeArgParam(call, c, _, _, _, _)
987+
}
988+
989+
predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) {
990+
callEdgeReturn(call, c, _, _, _, _, _)
991+
}
992+
985993
additional predicate stats(
986994
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, int calledges
987995
) {
@@ -1178,6 +1186,10 @@ module MakeImpl<InputSig Lang> {
11781186
DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out,
11791187
boolean allowsFieldFlow, Ap ap
11801188
);
1189+
1190+
predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c);
1191+
1192+
predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c);
11811193
}
11821194

11831195
private module MkStage<StageSig PrevStage> {
@@ -1219,7 +1231,9 @@ module MakeImpl<InputSig Lang> {
12191231

12201232
ApOption apSome(Ap ap);
12211233

1222-
class Cc;
1234+
class Cc {
1235+
string toString();
1236+
}
12231237

12241238
class CcCall extends Cc;
12251239

@@ -1731,13 +1745,9 @@ module MakeImpl<InputSig Lang> {
17311745
private module FwdTypeFlowInput implements TypeFlowInput {
17321746
predicate enableTypeFlow = Param::enableTypeFlow/0;
17331747

1734-
predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) {
1735-
PrevStage::callEdgeArgParam(call, c, _, _, _, _)
1736-
}
1748+
predicate relevantCallEdgeIn = PrevStage::relevantCallEdgeIn/2;
17371749

1738-
predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) {
1739-
PrevStage::callEdgeReturn(call, c, _, _, _, _, _)
1740-
}
1750+
predicate relevantCallEdgeOut = PrevStage::relevantCallEdgeOut/2;
17411751

17421752
pragma[nomagic]
17431753
private predicate dataFlowTakenCallEdgeIn0(
@@ -2314,6 +2324,14 @@ module MakeImpl<InputSig Lang> {
23142324
)
23152325
}
23162326

2327+
predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) {
2328+
callEdgeArgParam(call, c, _, _, _, _)
2329+
}
2330+
2331+
predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) {
2332+
callEdgeReturn(call, c, _, _, _, _, _)
2333+
}
2334+
23172335
additional predicate stats(
23182336
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, int calledges,
23192337
int tfnodes, int tftuples
@@ -2356,9 +2374,7 @@ module MakeImpl<InputSig Lang> {
23562374
}
23572375

23582376
private module BooleanCallContext {
2359-
class Cc extends boolean {
2360-
Cc() { this in [true, false] }
2361-
}
2377+
class Cc = Boolean;
23622378

23632379
class CcCall extends Cc {
23642380
CcCall() { this = true }
@@ -2398,7 +2414,24 @@ module MakeImpl<InputSig Lang> {
23982414
CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
23992415
}
24002416

2401-
private module Level1CallContext {
2417+
private signature module Level1CallContextInputSig {
2418+
DataFlowCallable prunedViableImplInCallContext(DataFlowCall call, CallContextSpecificCall ctx);
2419+
2420+
bindingset[call, ctx]
2421+
predicate noPrunedViableImplInCallContext(DataFlowCall call, CallContext ctx);
2422+
2423+
predicate recordDataFlowCallSiteDispatch(DataFlowCall call, DataFlowCallable callable);
2424+
2425+
predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable callable);
2426+
2427+
predicate reducedViableImplInReturn(DataFlowCallable c, DataFlowCall call);
2428+
2429+
DataFlowCall prunedViableImplInCallContextReverse(
2430+
DataFlowCallable callable, CallContextReturn ctx
2431+
);
2432+
}
2433+
2434+
private module Level1CallContext<Level1CallContextInputSig Input> {
24022435
class Cc = CallContext;
24032436

24042437
class CcCall = CallContextCall;
@@ -2419,17 +2452,17 @@ module MakeImpl<InputSig Lang> {
24192452
LocalCc getLocalCc(NodeEx node, Cc cc) { any() }
24202453

24212454
DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CcCall ctx) {
2422-
result = prunedViableImplInCallContext(call, ctx)
2455+
result = Input::prunedViableImplInCallContext(call, ctx)
24232456
}
24242457

24252458
bindingset[call, ctx]
24262459
predicate viableImplNotCallContextReduced(DataFlowCall call, Cc ctx) {
2427-
noPrunedViableImplInCallContext(call, ctx)
2460+
Input::noPrunedViableImplInCallContext(call, ctx)
24282461
}
24292462

24302463
bindingset[call, c]
24312464
CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c) {
2432-
if recordDataFlowCallSiteDispatch(call, c)
2465+
if Input::recordDataFlowCallSiteDispatch(call, c)
24332466
then result = TSpecificCall(call)
24342467
else result = TSomeCall()
24352468
}
@@ -2446,24 +2479,26 @@ module MakeImpl<InputSig Lang> {
24462479
}
24472480

24482481
DataFlowCallable viableImplCallContextReduced(DataFlowCall call, CcCall ctx) {
2449-
result = prunedViableImplInCallContext(call, ctx)
2482+
result = Input::prunedViableImplInCallContext(call, ctx)
24502483
}
24512484

24522485
bindingset[call, ctx]
24532486
predicate viableImplNotCallContextReduced(DataFlowCall call, Cc ctx) {
2454-
noPrunedViableImplInCallContext(call, ctx)
2487+
Input::noPrunedViableImplInCallContext(call, ctx)
24552488
}
24562489

24572490
bindingset[call, c]
24582491
CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c) {
2459-
if recordDataFlowCallSite(call, c)
2492+
if
2493+
Input::recordDataFlowCallSiteDispatch(call, c) or
2494+
Input::recordDataFlowCallSiteUnreachable(call, c)
24602495
then result = TSpecificCall(call)
24612496
else result = TSomeCall()
24622497
}
24632498
}
24642499

24652500
DataFlowCallable viableImplCallContextReducedReverse(DataFlowCall call, CcNoCall ctx) {
2466-
call = prunedViableImplInCallContextReverse(result, ctx)
2501+
call = Input::prunedViableImplInCallContextReverse(result, ctx)
24672502
}
24682503

24692504
predicate viableImplNotCallContextReducedReverse(CcNoCall ctx) {
@@ -2472,7 +2507,9 @@ module MakeImpl<InputSig Lang> {
24722507

24732508
bindingset[call, c]
24742509
CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
2475-
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
2510+
if Input::reducedViableImplInReturn(c, call)
2511+
then result = TReturn(c, call)
2512+
else result = ccNone()
24762513
}
24772514
}
24782515

@@ -2510,7 +2547,11 @@ module MakeImpl<InputSig Lang> {
25102547

25112548
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
25122549

2513-
import Level1CallContext
2550+
private module Level1CallContextInput implements Level1CallContextInputSig {
2551+
import CachedCallContextSensitivity
2552+
}
2553+
2554+
import Level1CallContext<Level1CallContextInput>
25142555
import NoLocalCallContext
25152556

25162557
bindingset[node1, state1]
@@ -2780,7 +2821,23 @@ module MakeImpl<InputSig Lang> {
27802821

27812822
ApOption apSome(Ap ap) { result = TApproxAccessPathFrontSome(ap) }
27822823

2783-
import Level1CallContext
2824+
additional module Level1CallContextInput implements Level1CallContextInputSig {
2825+
private module CallContextSensitivityInput implements CallContextSensitivityInputSig {
2826+
predicate relevantCallEdgeIn = PrevStage::relevantCallEdgeIn/2;
2827+
2828+
predicate relevantCallEdgeOut = PrevStage::relevantCallEdgeOut/2;
2829+
2830+
predicate reducedViableImplInCallContextCand =
2831+
CachedCallContextSensitivity::reducedViableImplInCallContext/3;
2832+
2833+
predicate reducedViableImplInReturnCand =
2834+
CachedCallContextSensitivity::reducedViableImplInReturn/2;
2835+
}
2836+
2837+
import CallContextSensitivity<CallContextSensitivityInput>
2838+
}
2839+
2840+
import Level1CallContext<Level1CallContextInput>
27842841
import NoLocalCallContext
27852842

27862843
predicate localStep(
@@ -3148,7 +3205,23 @@ module MakeImpl<InputSig Lang> {
31483205

31493206
ApOption apSome(Ap ap) { result = TAccessPathApproxSome(ap) }
31503207

3151-
import Level1CallContext
3208+
additional module Level1CallContextInput implements Level1CallContextInputSig {
3209+
private module CallContextSensitivityInput implements CallContextSensitivityInputSig {
3210+
predicate relevantCallEdgeIn = PrevStage::relevantCallEdgeIn/2;
3211+
3212+
predicate relevantCallEdgeOut = PrevStage::relevantCallEdgeOut/2;
3213+
3214+
predicate reducedViableImplInCallContextCand =
3215+
Stage3Param::Level1CallContextInput::reducedViableImplInCallContext/3;
3216+
3217+
predicate reducedViableImplInReturnCand =
3218+
Stage3Param::Level1CallContextInput::reducedViableImplInReturn/2;
3219+
}
3220+
3221+
import CallContextSensitivity<CallContextSensitivityInput>
3222+
}
3223+
3224+
import Level1CallContext<Level1CallContextInput>
31523225
import LocalCallContext
31533226

31543227
predicate localStep(
@@ -4026,6 +4099,22 @@ module MakeImpl<InputSig Lang> {
40264099
)
40274100
}
40284101

4102+
private module PrunedCallContextSensitivityStage5 {
4103+
private module CallContextSensitivityInput implements CallContextSensitivityInputSig {
4104+
predicate relevantCallEdgeIn = Stage5::relevantCallEdgeIn/2;
4105+
4106+
predicate relevantCallEdgeOut = Stage5::relevantCallEdgeOut/2;
4107+
4108+
predicate reducedViableImplInCallContextCand =
4109+
Stage5Param::Level1CallContextInput::reducedViableImplInCallContext/3;
4110+
4111+
predicate reducedViableImplInReturnCand =
4112+
Stage5Param::Level1CallContextInput::reducedViableImplInReturn/2;
4113+
}
4114+
4115+
import CallContextSensitivity<CallContextSensitivityInput>
4116+
}
4117+
40294118
pragma[nomagic]
40304119
private predicate pathOutOfCallable1(
40314120
PathNodeMid mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc,
@@ -4035,9 +4124,11 @@ module MakeImpl<InputSig Lang> {
40354124
pathOutOfCallable0(mid, pos, state, innercc, apa) and
40364125
c = pos.getCallable() and
40374126
kind = pos.getKind() and
4038-
resolveReturn(innercc, c, call)
4127+
PrunedCallContextSensitivityStage5::resolveReturn(innercc, c, call)
40394128
|
4040-
if reducedViableImplInReturn(c, call) then cc = TReturn(c, call) else cc = TAnyCallContext()
4129+
if PrunedCallContextSensitivityStage5::reducedViableImplInReturn(c, call)
4130+
then cc = TReturn(c, call)
4131+
else cc = TAnyCallContext()
40414132
)
40424133
}
40434134

@@ -4087,8 +4178,6 @@ module MakeImpl<InputSig Lang> {
40874178
)
40884179
}
40894180

4090-
private predicate parameterCandProj(DataFlowCallable c) { parameterCand(c, _, _) }
4091-
40924181
pragma[nomagic]
40934182
private predicate pathIntoCallable0(
40944183
PathNodeMid mid, DataFlowCallable callable, ParameterPosition pos, FlowState state,
@@ -4097,7 +4186,7 @@ module MakeImpl<InputSig Lang> {
40974186
exists(AccessPathApprox apa |
40984187
pathIntoArg(mid, pragma[only_bind_into](pos), state, outercc, call, t, ap,
40994188
pragma[only_bind_into](apa)) and
4100-
callable = ResolveCall<parameterCandProj/1>::resolveCall(call, outercc) and
4189+
callable = PrunedCallContextSensitivityStage5::resolveCall(call, outercc) and
41014190
parameterCand(callable, pragma[only_bind_into](pos), pragma[only_bind_into](apa))
41024191
)
41034192
}
@@ -4127,7 +4216,7 @@ module MakeImpl<InputSig Lang> {
41274216
not Config::getAFeature() instanceof FeatureEqualSourceSinkCallContext
41284217
)
41294218
|
4130-
if recordDataFlowCallSite(call, callable)
4219+
if PrunedCallContextSensitivityStage5::recordDataFlowCallSite(call, callable)
41314220
then innercc = TSpecificCall(call)
41324221
else innercc = TSomeCall()
41334222
)
@@ -5019,9 +5108,9 @@ module MakeImpl<InputSig Lang> {
50195108
partialPathOutOfCallable0(mid, pos, state, innercc, t, ap) and
50205109
c = pos.getCallable() and
50215110
kind = pos.getKind() and
5022-
resolveReturn(innercc, c, call)
5111+
CachedCallContextSensitivity::resolveReturn(innercc, c, call)
50235112
|
5024-
if reducedViableImplInReturn(c, call)
5113+
if CachedCallContextSensitivity::reducedViableImplInReturn(c, call)
50255114
then cc = TReturn(c, call)
50265115
else cc = TAnyCallContext()
50275116
)
@@ -5054,15 +5143,13 @@ module MakeImpl<InputSig Lang> {
50545143
)
50555144
}
50565145

5057-
private predicate anyCallable(DataFlowCallable c) { any() }
5058-
50595146
pragma[nomagic]
50605147
private predicate partialPathIntoCallable0(
50615148
PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPosition pos, FlowState state,
50625149
CallContext outercc, DataFlowCall call, DataFlowType t, PartialAccessPath ap
50635150
) {
50645151
partialPathIntoArg(mid, pos, state, outercc, call, t, ap) and
5065-
callable = ResolveCall<anyCallable/1>::resolveCall(call, outercc)
5152+
callable = CachedCallContextSensitivity::resolveCall(call, outercc)
50665153
}
50675154

50685155
private predicate partialPathIntoCallable(
@@ -5078,7 +5165,7 @@ module MakeImpl<InputSig Lang> {
50785165
sc3 = TSummaryCtx3Some(t) and
50795166
sc4 = TSummaryCtx4Some(ap)
50805167
|
5081-
if recordDataFlowCallSite(call, callable)
5168+
if CachedCallContextSensitivity::recordDataFlowCallSite(call, callable)
50825169
then innercc = TSpecificCall(call)
50835170
else innercc = TSomeCall()
50845171
)

0 commit comments

Comments
 (0)