Skip to content

Commit 7fc536d

Browse files
committed
Data flow: Add precise call contexts to stage 2
1 parent 789e2e4 commit 7fc536d

File tree

2 files changed

+33
-18
lines changed

2 files changed

+33
-18
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -923,28 +923,29 @@ private module Stage2 {
923923

924924
ApOption apSome(Ap ap) { result = TBooleanSome(ap) }
925925

926-
class Cc = boolean;
927-
928-
class CcCall extends Cc {
929-
CcCall() { this = true }
926+
class Cc = CallContext;
930927

931-
/** Holds if this call context may be `call`. */
932-
predicate matchesCall(DataFlowCall call) { any() }
933-
}
928+
class CcCall = CallContextCall;
934929

935-
class CcNoCall extends Cc {
936-
CcNoCall() { this = false }
937-
}
930+
class CcNoCall = CallContextNoCall;
938931

939-
Cc ccNone() { result = false }
932+
Cc ccNone() { result instanceof CallContextAny }
940933

941934
private class LocalCc = Unit;
942935

943936
bindingset[call, c, outercc]
944-
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
937+
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
938+
checkCallContextCall(outercc, call, c) and
939+
if recordDataFlowCallSiteDispatch(call, c)
940+
then result = TSpecificCall(call)
941+
else result = TSomeCall()
942+
}
945943

946944
bindingset[call, c, innercc]
947-
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
945+
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
946+
checkCallContextReturn(innercc, c, call) and
947+
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
948+
}
948949

949950
bindingset[node, cc, config]
950951
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
@@ -2117,7 +2118,7 @@ private module Stage3 {
21172118
private predicate flowCandSummaryCtx(NodeEx node, AccessPathFront argApf, Configuration config) {
21182119
exists(AccessPathFront apf |
21192120
Stage3::revFlow(node, true, _, apf, config) and
2120-
Stage3::fwdFlow(node, true, TAccessPathFrontSome(argApf), apf, config)
2121+
Stage3::fwdFlow(node, any(Stage3::CcCall ccc), TAccessPathFrontSome(argApf), apf, config)
21212122
)
21222123
}
21232124

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -786,13 +786,18 @@ private module Cached {
786786
}
787787

788788
/**
789-
* Holds if the call context `call` either improves virtual dispatch in
790-
* `callable` or if it allows us to prune unreachable nodes in `callable`.
789+
* Holds if the call context `call` improves virtual dispatch in `callable`.
791790
*/
792791
cached
793-
predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
792+
predicate recordDataFlowCallSiteDispatch(DataFlowCall call, DataFlowCallable callable) {
794793
reducedViableImplInCallContext(_, callable, call)
795-
or
794+
}
795+
796+
/**
797+
* Holds if the call context `call` allows us to prune unreachable nodes in `callable`.
798+
*/
799+
cached
800+
predicate recordDataFlowCallSiteUnreachable(DataFlowCall call, DataFlowCallable callable) {
796801
exists(Node n | getNodeEnclosingCallable(n) = callable | isUnreachableInCallCached(n, call))
797802
}
798803

@@ -846,6 +851,15 @@ private module Cached {
846851
TAccessPathFrontSome(AccessPathFront apf)
847852
}
848853

854+
/**
855+
* Holds if the call context `call` either improves virtual dispatch in
856+
* `callable` or if it allows us to prune unreachable nodes in `callable`.
857+
*/
858+
predicate recordDataFlowCallSite(DataFlowCall call, DataFlowCallable callable) {
859+
recordDataFlowCallSiteDispatch(call, callable) or
860+
recordDataFlowCallSiteUnreachable(call, callable)
861+
}
862+
849863
/**
850864
* A `Node` at which a cast can occur such that the type should be checked.
851865
*/

0 commit comments

Comments
 (0)