Skip to content

Commit 7692a9e

Browse files
committed
Java: Minor TypeFlow tweaks.
1 parent 85d4742 commit 7692a9e

File tree

1 file changed

+36
-9
lines changed

1 file changed

+36
-9
lines changed

java/ql/lib/semmle/code/java/dataflow/TypeFlow.qll

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ private predicate exactTypeBase(TypeFlowNode n, RefType t) {
337337
n.asExpr() = e and
338338
e.getType() = t and
339339
not e instanceof FunctionalExpr and
340-
exists(RefType sub | sub.getASourceSupertype() = t.getSourceDeclaration())
340+
exists(SrcRefType sub | sub.getASourceSupertype() = t.getSourceDeclaration())
341341
)
342342
}
343343

@@ -384,17 +384,23 @@ private predicate upcastCand(TypeFlowNode n, RefType t1, RefType t1e, RefType t2
384384
)
385385
}
386386

387+
private predicate unconstrained(BoundedType t) {
388+
t.(Wildcard).isUnconstrained()
389+
or
390+
t.(BoundedType).getUpperBoundType() instanceof TypeObject and
391+
not t.(Wildcard).hasLowerBound()
392+
or
393+
unconstrained(t.(BoundedType).getUpperBoundType())
394+
or
395+
unconstrained(t.(Wildcard).getLowerBoundType())
396+
}
397+
387398
/** Holds if `t` is a raw type or parameterised type with unrestricted type arguments. */
388399
private predicate unbound(RefType t) {
389400
t instanceof RawType
390401
or
391402
exists(ParameterizedType pt | pt = t |
392-
forex(RefType arg | arg = pt.getATypeArgument() |
393-
arg.(Wildcard).isUnconstrained()
394-
or
395-
arg.(BoundedType).getUpperBoundType() instanceof TypeObject and
396-
not arg.(Wildcard).hasLowerBound()
397-
)
403+
forex(RefType arg | arg = pt.getATypeArgument() | unconstrained(arg))
398404
)
399405
}
400406

@@ -492,9 +498,10 @@ predicate arrayInstanceOfGuarded(ArrayAccess aa, RefType t) {
492498

493499
/**
494500
* Holds if `n` has type `t` and this information is discarded, such that `t`
495-
* might be a better type bound for nodes where `n` flows to.
501+
* might be a better type bound for nodes where `n` flows to. This might include
502+
* multiple bounds for a single node.
496503
*/
497-
private predicate typeFlowBase(TypeFlowNode n, RefType t) {
504+
private predicate typeFlowBaseCand(TypeFlowNode n, RefType t) {
498505
exists(RefType srctype |
499506
upcast(n, srctype) or
500507
upcastEnhancedForStmt(n.asSsa(), srctype) or
@@ -509,6 +516,26 @@ private predicate typeFlowBase(TypeFlowNode n, RefType t) {
509516
)
510517
}
511518

519+
/**
520+
* Holds if `n` has type `t` and this information is discarded, such that `t`
521+
* might be a better type bound for nodes where `n` flows to. This only includes
522+
* the best such bound for each node.
523+
*/
524+
private predicate typeFlowBase(TypeFlowNode n, RefType t) {
525+
exists(RefType te |
526+
typeFlowBaseCand(n, t) and
527+
te = t.getErasure() and
528+
not exists(RefType better |
529+
typeFlowBaseCand(n, better) and
530+
better != t and
531+
not t.getASupertype+() = better
532+
|
533+
better.getASupertype+() = t or
534+
better.getErasure().(RefType).getASourceSupertype+() = te
535+
)
536+
)
537+
}
538+
512539
private module TypeFlowPropagation implements TypePropagation {
513540
predicate candType = typeFlow/2;
514541

0 commit comments

Comments
 (0)