@@ -305,6 +305,21 @@ private predicate instanceOfGuarded(VarAccess va, RefType t) {
305305 )
306306}
307307
308+ /**
309+ * Holds if `aa` is an access to a value that is guarded by `instanceof t`.
310+ */
311+ predicate arrayInstanceOfGuarded ( ArrayAccess aa , RefType t ) {
312+ exists ( InstanceOfExpr ioe , BaseSsaVariable v1 , BaseSsaVariable v2 , ArrayAccess aa1 |
313+ ioe .getExpr ( ) = aa1 and
314+ t = ioe .getTypeName ( ) .getType ( ) and
315+ aa1 .getArray ( ) = v1 .getAUse ( ) and
316+ aa1 .getIndexExpr ( ) = v2 .getAUse ( ) and
317+ aa .getArray ( ) = v1 .getAUse ( ) and
318+ aa .getIndexExpr ( ) = v2 .getAUse ( ) and
319+ guardControls_v1 ( ioe , aa .getBasicBlock ( ) , true )
320+ )
321+ }
322+
308323/**
309324 * Holds if `n` has type `t` and this information is discarded, such that `t`
310325 * might be a better type bound for nodes where `n` flows to.
@@ -315,6 +330,7 @@ private predicate typeFlowBase(TypeFlowNode n, RefType t) {
315330 upcastEnhancedForStmt ( n .asSsa ( ) , srctype ) or
316331 downcastSuccessor ( n .asExpr ( ) , srctype ) or
317332 instanceOfGuarded ( n .asExpr ( ) , srctype ) or
333+ arrayInstanceOfGuarded ( n .asExpr ( ) , srctype ) or
318334 n .asExpr ( ) .( FunctionalExpr ) .getConstructedType ( ) = srctype
319335 |
320336 t = srctype .( BoundedType ) .getAnUltimateUpperBoundType ( )
0 commit comments