C#: Fix a few minor performance regressions

This commit is contained in:
Tom Hvitved
2019-03-18 14:36:41 +01:00
parent af1c502b11
commit 6cd87757f6
3 changed files with 22 additions and 6 deletions

View File

@@ -49,18 +49,28 @@ predicate isTriedAgainstException(ControlFlowElement cfe, ExceptionClass ec) {
)
}
private class DisposeCall extends MethodCall {
DisposeCall() { this.getTarget() instanceof DisposeMethod }
}
private predicate reachesDisposeCall(DisposeCall disposeCall, DataFlow::Node node) {
DataFlow::localFlowStep(node, DataFlow::exprNode(disposeCall.getQualifier()))
or
exists(DataFlow::Node mid | reachesDisposeCall(disposeCall, mid) |
DataFlow::localFlowStep(node, mid)
)
}
/**
* Holds if `disposeCall` disposes the object created by `disposableCreation`.
*/
predicate disposeReachableFromDisposableCreation(MethodCall disposeCall, Expr disposableCreation) {
predicate disposeReachableFromDisposableCreation(DisposeCall disposeCall, Expr disposableCreation) {
// The qualifier of the Dispose call flows from something that introduced a disposable into scope
(
disposableCreation instanceof LocalScopeDisposableCreation or
disposableCreation instanceof MethodCall
) and
DataFlow::localFlowStep+(DataFlow::exprNode(disposableCreation),
DataFlow::exprNode(disposeCall.getQualifier())) and
disposeCall.getTarget() instanceof DisposeMethod
reachesDisposeCall(disposeCall, DataFlow::exprNode(disposableCreation))
}
class MethodCallThatMayThrow extends MethodCall {
@@ -73,7 +83,7 @@ ControlFlowElement getACatchOrFinallyClauseChild() {
result = getACatchOrFinallyClauseChild().getAChild()
}
from MethodCall disposeCall, Expr disposableCreation, MethodCallThatMayThrow callThatThrows
from DisposeCall disposeCall, Expr disposableCreation, MethodCallThatMayThrow callThatThrows
where
disposeReachableFromDisposableCreation(disposeCall, disposableCreation) and
// The dispose call is not, itself, within a dispose method.

View File

@@ -76,6 +76,11 @@ class AssignableRead extends AssignableAccess {
not nameOfChild(_, this)
}
pragma[noinline]
private ControlFlow::Node getAnAdjacentReadSameVar() {
Ssa::Internal::adjacentReadPairSameVar(this.getAControlFlowNode(), result)
}
/**
* Gets a next read of the same underlying assignable. That is, a read
* that can be reached from this read without passing through any other reads,
@@ -102,7 +107,7 @@ class AssignableRead extends AssignableAccess {
*/
AssignableRead getANextRead() {
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
Ssa::Internal::adjacentReadPairSameVar(this.getAControlFlowNode(), cfn)
cfn = this.getAnAdjacentReadSameVar()
)
}

View File

@@ -704,6 +704,7 @@ module DataFlow {
)
}
pragma[nomagic]
private ControlFlowElement getANonExactScopeChild(ControlFlowElement scope) {
scope = getAScope(false) and
result = scope