Java: Remove low confidence dispatch for which we have a manual summary.

This commit is contained in:
Anders Schack-Mulligen
2022-08-23 15:50:30 +02:00
parent d713910714
commit ba3ebeec2c
2 changed files with 68 additions and 4 deletions

View File

@@ -8,9 +8,27 @@ private import semmle.code.java.dataflow.TypeFlow
private import semmle.code.java.dispatch.internal.Unification
private module DispatchImpl {
private predicate hasHighConfidenceTarget(Call c) {
exists(SummarizedCallable sc |
sc = c.getCallee().getSourceDeclaration() and not sc.isAutoGenerated()
)
or
exists(Callable srcTgt |
srcTgt = VirtualDispatch::viableCallable(c) and
not VirtualDispatch::lowConfidenceDispatchTarget(c, srcTgt)
)
}
private Callable sourceDispatch(Call c) {
result = VirtualDispatch::viableCallable(c) and
if VirtualDispatch::lowConfidenceDispatchTarget(c, result)
then not hasHighConfidenceTarget(c)
else any()
}
/** Gets a viable implementation of the target of the given `Call`. */
DataFlowCallable viableCallable(DataFlowCall c) {
result.asCallable() = VirtualDispatch::viableCallable(c.asCall())
result.asCallable() = sourceDispatch(c.asCall())
or
result.asSummarizedCallable() = c.asCall().getCallee().getSourceDeclaration()
}
@@ -22,7 +40,7 @@ private module DispatchImpl {
*/
private predicate mayBenefitFromCallContext(MethodAccess ma, Callable c, int i) {
exists(Parameter p |
2 <= strictcount(VirtualDispatch::viableImpl(ma)) and
2 <= strictcount(sourceDispatch(ma)) and
ma.getQualifier().(VarAccess).getVariable() = p and
p.getPosition() = i and
c.getAParameter() = p and
@@ -31,7 +49,7 @@ private module DispatchImpl {
)
or
exists(OwnInstanceAccess ia |
2 <= strictcount(VirtualDispatch::viableImpl(ma)) and
2 <= strictcount(sourceDispatch(ma)) and
(ia.isExplicit(ma.getQualifier()) or ia.isImplicitMethodQualifier(ma)) and
i = -1 and
c = ma.getEnclosingCallable()
@@ -47,7 +65,7 @@ private module DispatchImpl {
private predicate relevantContext(Call ctx, int i) {
exists(Callable c |
mayBenefitFromCallContext(_, c, i) and
c = VirtualDispatch::viableCallable(ctx)
c = sourceDispatch(ctx)
)
}