From 508b6050a813aba8ea29555117772e8002deb811 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 26 Feb 2020 13:51:25 +0100 Subject: [PATCH] Java: Remove some irrelevant bounds from TypeFlow. --- .../semmle/code/java/dataflow/TypeFlow.qll | 41 +++++++++++++++++-- .../src/semmle/code/java/dispatch/ObjFlow.qll | 1 + 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/java/ql/src/semmle/code/java/dataflow/TypeFlow.qll b/java/ql/src/semmle/code/java/dataflow/TypeFlow.qll index e9f32aadbbe..24cf918a9b7 100644 --- a/java/ql/src/semmle/code/java/dataflow/TypeFlow.qll +++ b/java/ql/src/semmle/code/java/dataflow/TypeFlow.qll @@ -364,13 +364,45 @@ private predicate typeFlow(TypeFlowNode n, RefType t) { typeFlowJoin(lastRank(n), n, t) } +pragma[nomagic] +predicate erasedTypeBound(RefType t) { + exists(RefType t0 | typeFlow(_, t0) and t = t0.getErasure()) +} + +pragma[nomagic] +predicate typeBound(RefType t) { typeFlow(_, t) } + +/** + * Holds if we have a bound for `n` that is better than `t`, taking only erased + * types into account. + */ +pragma[nomagic] +private predicate irrelevantErasedBound(TypeFlowNode n, RefType t) { + exists(RefType bound | + typeFlow(n, bound) + or + n.getType() = bound and typeFlow(n, _) + | + t = bound.getErasure().(RefType).getASourceSupertype+() and + erasedTypeBound(t) + ) +} + /** * Holds if we have a bound for `n` that is better than `t`. */ -pragma[noinline] +pragma[nomagic] private predicate irrelevantBound(TypeFlowNode n, RefType t) { - exists(RefType bound | typeFlow(n, bound) or n.getType() = bound | - t = bound.getErasure().(RefType).getASourceSupertype+() + exists(RefType bound | + typeFlow(n, bound) and + t = bound.getASupertype+() and + typeBound(t) and + typeFlow(n, t) and + not t.getASupertype*() = bound + or + n.getType() = bound and + typeFlow(n, t) and + t = bound.getASupertype*() ) } @@ -380,7 +412,8 @@ private predicate irrelevantBound(TypeFlowNode n, RefType t) { */ private predicate bestTypeFlow(TypeFlowNode n, RefType t) { typeFlow(n, t) and - not irrelevantBound(n, t.getErasure()) + not irrelevantErasedBound(n, t.getErasure()) and + not irrelevantBound(n, t) } cached diff --git a/java/ql/src/semmle/code/java/dispatch/ObjFlow.qll b/java/ql/src/semmle/code/java/dispatch/ObjFlow.qll index 4d97bfdc3cc..11537ac144b 100644 --- a/java/ql/src/semmle/code/java/dispatch/ObjFlow.qll +++ b/java/ql/src/semmle/code/java/dispatch/ObjFlow.qll @@ -305,6 +305,7 @@ private module Unification { arg2 = t2.getTypeArgument(pos) } + pragma[nomagic] predicate failsUnification(Type t1, Type t2) { unificationTargets(t1, t2) and (