Skip to content

Commit b456ba2

Browse files
committed
Dataflow: Improve rev-to-fwd call edge pruning.
1 parent f456bf8 commit b456ba2

File tree

1 file changed

+76
-99
lines changed

1 file changed

+76
-99
lines changed

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

Lines changed: 76 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -917,22 +917,46 @@ module MakeImpl<InputSig Lang> {
917917
)
918918
}
919919

920+
predicate callEdgeArgParam(
921+
DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p,
922+
boolean allowsFieldFlow, Ap ap
923+
) {
924+
flowIntoCallNodeCand1(call, arg, p, allowsFieldFlow) and
925+
c = p.getEnclosingCallable() and
926+
exists(ap)
927+
}
928+
929+
predicate callEdgeReturn(
930+
DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out,
931+
boolean allowsFieldFlow, Ap ap
932+
) {
933+
flowOutOfCallNodeCand1(call, ret, kind, out, allowsFieldFlow) and
934+
c = ret.getEnclosingCallable() and
935+
exists(ap)
936+
}
937+
920938
additional predicate stats(
921-
boolean fwd, int nodes, int fields, int conscand, int states, int tuples
939+
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, int calledges
922940
) {
923941
fwd = true and
924942
nodes = count(NodeEx node | fwdFlow(node)) and
925943
fields = count(Content f0 | fwdFlowConsCand(f0)) and
926944
conscand = -1 and
927945
states = count(FlowState state | fwdFlowState(state)) and
928-
tuples = count(NodeEx n, boolean b | fwdFlow(n, b))
946+
tuples = count(NodeEx n, boolean b | fwdFlow(n, b)) and
947+
calledges = -1
929948
or
930949
fwd = false and
931950
nodes = count(NodeEx node | revFlow(node, _)) and
932951
fields = count(Content f0 | revFlowConsCand(f0)) and
933952
conscand = -1 and
934953
states = count(FlowState state | revFlowState(state)) and
935-
tuples = count(NodeEx n, boolean b | revFlow(n, b))
954+
tuples = count(NodeEx n, boolean b | revFlow(n, b)) and
955+
calledges =
956+
count(DataFlowCall call, DataFlowCallable c |
957+
callEdgeArgParam(call, c, _, _, _, _) or
958+
callEdgeReturn(call, c, _, _, _, _, _)
959+
)
936960
}
937961
/* End: Stage 1 logic. */
938962
}
@@ -1093,6 +1117,16 @@ module MakeImpl<InputSig Lang> {
10931117
);
10941118

10951119
predicate readStepCand(NodeEx n1, Content c, NodeEx n2);
1120+
1121+
predicate callEdgeArgParam(
1122+
DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p,
1123+
boolean allowsFieldFlow, Ap ap
1124+
);
1125+
1126+
predicate callEdgeReturn(
1127+
DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out,
1128+
boolean allowsFieldFlow, Ap ap
1129+
);
10961130
}
10971131

10981132
private module MkStage<StageSig PrevStage> {
@@ -1172,14 +1206,6 @@ module MakeImpl<InputSig Lang> {
11721206
Typ t, LocalCc lcc
11731207
);
11741208

1175-
predicate flowOutOfCall(
1176-
DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow
1177-
);
1178-
1179-
predicate flowIntoCall(
1180-
DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow
1181-
);
1182-
11831209
bindingset[node, state, t0, ap]
11841210
predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t);
11851211

@@ -1202,35 +1228,13 @@ module MakeImpl<InputSig Lang> {
12021228
PrevStage::revFlow(node) and result = getTyp(node.getDataFlowType())
12031229
}
12041230

1205-
pragma[nomagic]
1206-
private predicate flowIntoCallApa(
1207-
DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p,
1208-
boolean allowsFieldFlow, ApApprox apa
1209-
) {
1210-
flowIntoCall(call, arg, p, allowsFieldFlow) and
1211-
PrevStage::revFlowAp(p, pragma[only_bind_into](apa)) and
1212-
PrevStage::revFlowAp(arg, pragma[only_bind_into](apa)) and
1213-
c = p.getEnclosingCallable()
1214-
}
1215-
1216-
pragma[nomagic]
1217-
private predicate flowOutOfCallApa(
1218-
DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out,
1219-
boolean allowsFieldFlow, ApApprox apa
1220-
) {
1221-
flowOutOfCall(call, ret, kind, out, allowsFieldFlow) and
1222-
PrevStage::revFlowAp(out, pragma[only_bind_into](apa)) and
1223-
PrevStage::revFlowAp(ret, pragma[only_bind_into](apa)) and
1224-
c = ret.getEnclosingCallable()
1225-
}
1226-
12271231
pragma[nomagic]
12281232
private predicate flowThroughOutOfCall(
12291233
DataFlowCall call, CcCall ccc, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
12301234
ApApprox argApa, ApApprox apa
12311235
) {
12321236
exists(ReturnKindExt kind |
1233-
flowOutOfCallApa(call, _, ret, kind, out, allowsFieldFlow, apa) and
1237+
PrevStage::callEdgeReturn(call, _, ret, kind, out, allowsFieldFlow, apa) and
12341238
PrevStage::callMayFlowThroughRev(call) and
12351239
PrevStage::returnMayFlowThrough(ret, argApa, apa, kind) and
12361240
matchesCall(ccc, call)
@@ -1434,7 +1438,7 @@ module MakeImpl<InputSig Lang> {
14341438
DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p,
14351439
boolean allowsFieldFlow, ApApprox apa
14361440
) {
1437-
flowIntoCallApa(call, c, arg, p, allowsFieldFlow, apa)
1441+
PrevStage::callEdgeArgParam(call, c, arg, p, allowsFieldFlow, apa)
14381442
}
14391443

14401444
bindingset[call, ctx]
@@ -1499,7 +1503,7 @@ module MakeImpl<InputSig Lang> {
14991503
DataFlowCall call, DataFlowCallable c, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow,
15001504
ApApprox apa
15011505
) {
1502-
flowOutOfCallApa(call, c, ret, _, out, allowsFieldFlow, apa)
1506+
PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow, apa)
15031507
}
15041508

15051509
bindingset[c, ret, apa, innercc]
@@ -1510,7 +1514,7 @@ module MakeImpl<InputSig Lang> {
15101514
ApApprox apa, CcNoCall innercc
15111515
) {
15121516
viableImplNotCallContextReducedReverse(innercc) and
1513-
flowOutOfCallApa(call, c, ret, _, out, allowsFieldFlow, apa)
1517+
PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow, apa)
15141518
}
15151519

15161520
pragma[nomagic]
@@ -1546,11 +1550,11 @@ module MakeImpl<InputSig Lang> {
15461550
predicate enableTypeFlow = Param::enableTypeFlow/0;
15471551

15481552
predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) {
1549-
flowIntoCallApa(call, c, _, _, _, _)
1553+
PrevStage::callEdgeArgParam(call, c, _, _, _, _)
15501554
}
15511555

15521556
predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) {
1553-
flowOutOfCallApa(call, c, _, _, _, _, _)
1557+
PrevStage::callEdgeReturn(call, c, _, _, _, _, _)
15541558
}
15551559

15561560
pragma[nomagic]
@@ -1593,7 +1597,7 @@ module MakeImpl<InputSig Lang> {
15931597
DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p,
15941598
boolean allowsFieldFlow, ApApprox apa
15951599
) {
1596-
flowIntoCallApa(call, c, arg, p, allowsFieldFlow, apa) and
1600+
PrevStage::callEdgeArgParam(call, c, arg, p, allowsFieldFlow, apa) and
15971601
FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _)
15981602
}
15991603

@@ -1720,7 +1724,7 @@ module MakeImpl<InputSig Lang> {
17201724
Ap ap
17211725
) {
17221726
exists(ApApprox apa, boolean allowsFieldFlow |
1723-
flowOutOfCallApa(call, c, ret, _, out, allowsFieldFlow, apa) and
1727+
PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow, apa) and
17241728
fwdFlow(ret, _, _, _, _, _, _, ap, apa) and
17251729
pos = ret.getReturnPosition() and
17261730
if allowsFieldFlow = false then ap instanceof ApNil else any()
@@ -2064,6 +2068,35 @@ module MakeImpl<InputSig Lang> {
20642068
)
20652069
}
20662070

2071+
predicate callEdgeArgParam(
2072+
DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p,
2073+
boolean allowsFieldFlow, Ap ap
2074+
) {
2075+
exists(FlowState state |
2076+
flowIntoCallAp(call, c, arg, p, ap) and
2077+
revFlow(arg, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and
2078+
revFlow(p, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and
2079+
allowsFieldFlow = true
2080+
|
2081+
RevTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) or
2082+
RevTypeFlowInput::dataFlowTakenCallEdgeOut(call, c)
2083+
)
2084+
}
2085+
2086+
predicate callEdgeReturn(
2087+
DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out,
2088+
boolean allowsFieldFlow, Ap ap
2089+
) {
2090+
exists(FlowState state, ReturnPosition pos |
2091+
flowOutOfCallAp(call, c, ret, pos, out, ap) and
2092+
revFlow(ret, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and
2093+
revFlow(out, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and
2094+
kind = pos.getKind() and
2095+
allowsFieldFlow = true and
2096+
RevTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _)
2097+
)
2098+
}
2099+
20672100
additional predicate stats(
20682101
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, int calledges,
20692102
int tfnodes, int tftuples
@@ -2287,10 +2320,6 @@ module MakeImpl<InputSig Lang> {
22872320
exists(lcc)
22882321
}
22892322

2290-
predicate flowOutOfCall = flowOutOfCallNodeCand1/5;
2291-
2292-
predicate flowIntoCall = flowIntoCallNodeCand1/4;
2293-
22942323
pragma[nomagic]
22952324
private predicate expectsContentCand(NodeEx node) {
22962325
exists(Content c |
@@ -2544,10 +2573,6 @@ module MakeImpl<InputSig Lang> {
25442573
exists(lcc)
25452574
}
25462575

2547-
predicate flowOutOfCall = flowOutOfCallNodeCand2/5;
2548-
2549-
predicate flowIntoCall = flowIntoCallNodeCand2/4;
2550-
25512576
pragma[nomagic]
25522577
private predicate expectsContentCand(NodeEx node, Ap ap) {
25532578
exists(Content c |
@@ -2639,29 +2664,6 @@ module MakeImpl<InputSig Lang> {
26392664
exists(lcc)
26402665
}
26412666

2642-
pragma[nomagic]
2643-
predicate flowOutOfCall(
2644-
DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2,
2645-
boolean allowsFieldFlow
2646-
) {
2647-
exists(FlowState state |
2648-
flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and
2649-
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
2650-
PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
2651-
)
2652-
}
2653-
2654-
pragma[nomagic]
2655-
predicate flowIntoCall(
2656-
DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow
2657-
) {
2658-
exists(FlowState state |
2659-
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and
2660-
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
2661-
PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
2662-
)
2663-
}
2664-
26652667
pragma[nomagic]
26662668
private predicate clearSet(NodeEx node, ContentSet c) {
26672669
PrevStage::revFlow(node) and
@@ -2944,29 +2946,6 @@ module MakeImpl<InputSig Lang> {
29442946
PrevStage::revFlow(node2, pragma[only_bind_into](state2), _)
29452947
}
29462948

2947-
pragma[nomagic]
2948-
predicate flowOutOfCall(
2949-
DataFlowCall call, RetNodeEx node1, ReturnKindExt kind, NodeEx node2,
2950-
boolean allowsFieldFlow
2951-
) {
2952-
exists(FlowState state |
2953-
flowOutOfCallNodeCand2(call, node1, kind, node2, allowsFieldFlow) and
2954-
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
2955-
PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
2956-
)
2957-
}
2958-
2959-
pragma[nomagic]
2960-
predicate flowIntoCall(
2961-
DataFlowCall call, ArgNodeEx node1, ParamNodeEx node2, boolean allowsFieldFlow
2962-
) {
2963-
exists(FlowState state |
2964-
flowIntoCallNodeCand2(call, node1, node2, allowsFieldFlow) and
2965-
PrevStage::revFlow(node2, pragma[only_bind_into](state), _) and
2966-
PrevStage::revFlow(node1, pragma[only_bind_into](state), _)
2967-
)
2968-
}
2969-
29702949
bindingset[node, state, t0, ap]
29712950
predicate filter(NodeEx node, FlowState state, Typ t0, Ap ap, Typ t) {
29722951
strengthenType(node, t0, t) and
@@ -4136,15 +4115,13 @@ module MakeImpl<InputSig Lang> {
41364115
) {
41374116
stage = "1 Fwd" and
41384117
n = 10 and
4139-
Stage1::stats(true, nodes, fields, conscand, states, tuples) and
4140-
calledges = -1 and
4118+
Stage1::stats(true, nodes, fields, conscand, states, tuples, calledges) and
41414119
tfnodes = -1 and
41424120
tftuples = -1
41434121
or
41444122
stage = "1 Rev" and
41454123
n = 15 and
4146-
Stage1::stats(false, nodes, fields, conscand, states, tuples) and
4147-
calledges = -1 and
4124+
Stage1::stats(false, nodes, fields, conscand, states, tuples, calledges) and
41484125
tfnodes = -1 and
41494126
tftuples = -1
41504127
or

0 commit comments

Comments
 (0)