@@ -76,9 +76,14 @@ private predicate joinStep0(TypeFlowNode n1, TypeFlowNode n2) {
7676 or
7777 n2 .asExpr ( ) .( ConditionalExpr ) .getFalseExpr ( ) = n1 .asExpr ( )
7878 or
79- n2 .asField ( ) .getAnAssignedValue ( ) = n1 .asExpr ( )
79+ exists ( Field f , Expr e |
80+ f = n2 .asField ( ) and
81+ f .getAnAssignedValue ( ) = e and
82+ e = n1 .asExpr ( ) and
83+ not e .( FieldAccess ) .getField ( ) = f
84+ )
8085 or
81- n2 .asSsa ( ) .( BaseSsaPhiNode ) .getAPhiInput ( ) = n1 .asSsa ( )
86+ n2 .asSsa ( ) .( BaseSsaPhiNode ) .getAnUltimateLocalDefinition ( ) = n1 .asSsa ( )
8287 or
8388 exists ( ReturnStmt ret |
8489 n2 .asMethod ( ) = ret .getEnclosingCallable ( ) and ret .getResult ( ) = n1 .asExpr ( )
@@ -89,7 +94,9 @@ private predicate joinStep0(TypeFlowNode n1, TypeFlowNode n2) {
8994 exists ( Argument arg , Parameter p |
9095 privateParamArg ( p , arg ) and
9196 n1 .asExpr ( ) = arg and
92- n2 .asSsa ( ) .( BaseSsaImplicitInit ) .isParameterDefinition ( p )
97+ n2 .asSsa ( ) .( BaseSsaImplicitInit ) .isParameterDefinition ( p ) and
98+ // skip trivial recursion
99+ not arg = n2 .asSsa ( ) .getAUse ( )
93100 )
94101}
95102
@@ -121,9 +128,18 @@ private predicate step(TypeFlowNode n1, TypeFlowNode n2) {
121128private predicate isNull ( TypeFlowNode n ) {
122129 n .asExpr ( ) instanceof NullLiteral
123130 or
131+ exists ( LocalVariableDeclExpr decl |
132+ n .asSsa ( ) .( BaseSsaUpdate ) .getDefiningExpr ( ) = decl and
133+ not decl .hasImplicitInit ( ) and
134+ not exists ( decl .getInit ( ) )
135+ )
136+ or
124137 exists ( TypeFlowNode mid | isNull ( mid ) and step ( mid , n ) )
125138 or
126- forex ( TypeFlowNode mid | joinStep0 ( mid , n ) | isNull ( mid ) )
139+ forex ( TypeFlowNode mid | joinStep0 ( mid , n ) | isNull ( mid ) ) and
140+ // Fields that are never assigned a non-null value are probably set by
141+ // reflection and are thus not always null.
142+ not exists ( n .asField ( ) )
127143}
128144
129145/**
@@ -155,6 +171,15 @@ private predicate joinStepRank(int r, TypeFlowNode n1, TypeFlowNode n2) {
155171
156172private int lastRank ( TypeFlowNode n ) { result = max ( int r | joinStepRank ( r , _, n ) ) }
157173
174+ private predicate exactTypeBase ( TypeFlowNode n , RefType t ) {
175+ exists ( ClassInstanceExpr e |
176+ n .asExpr ( ) = e and
177+ e .getType ( ) = t and
178+ not e instanceof FunctionalExpr and
179+ exists ( RefType sub | sub .getASourceSupertype ( ) = t .getSourceDeclaration ( ) )
180+ )
181+ }
182+
158183private predicate exactTypeRank ( int r , TypeFlowNode n , RefType t ) {
159184 forall ( TypeFlowNode mid | joinStepRank ( r , mid , n ) | exactType ( mid , t ) ) and
160185 joinStepRank ( r , _, n )
@@ -171,12 +196,7 @@ private predicate exactTypeJoin(int r, TypeFlowNode n, RefType t) {
171196 * non-trivial lower bound, that is, `t` has a subtype.
172197 */
173198private predicate exactType ( TypeFlowNode n , RefType t ) {
174- exists ( ClassInstanceExpr e |
175- n .asExpr ( ) = e and
176- e .getType ( ) = t and
177- not e instanceof FunctionalExpr and
178- exists ( RefType sub | sub .getASourceSupertype ( ) = t .getSourceDeclaration ( ) )
179- )
199+ exactTypeBase ( n , t )
180200 or
181201 exists ( TypeFlowNode mid | exactType ( mid , t ) and step ( mid , n ) )
182202 or
@@ -289,6 +309,24 @@ private predicate instanceOfGuarded(VarAccess va, RefType t) {
289309 )
290310}
291311
312+ /**
313+ * Holds if `n` has type `t` and this information is discarded, such that `t`
314+ * might be a better type bound for nodes where `n` flows to.
315+ */
316+ private predicate typeFlowBase ( TypeFlowNode n , RefType t ) {
317+ exists ( RefType srctype |
318+ upcast ( n , srctype ) or
319+ upcastEnhancedForStmt ( n .asSsa ( ) , srctype ) or
320+ downcastSuccessor ( n .asExpr ( ) , srctype ) or
321+ instanceOfGuarded ( n .asExpr ( ) , srctype ) or
322+ n .asExpr ( ) .( FunctionalExpr ) .getConstructedType ( ) = srctype
323+ |
324+ t = srctype .( BoundedType ) .getAnUltimateUpperBoundType ( )
325+ or
326+ t = srctype and not srctype instanceof BoundedType
327+ )
328+ }
329+
292330/**
293331 * Holds if `t` is a bound that holds on one of the incoming edges to `n` and
294332 * thus is a candidate bound for `n`.
@@ -320,15 +358,7 @@ private predicate typeFlowJoin(int r, TypeFlowNode n, RefType t) {
320358 * likely to be better than the static type of `n`.
321359 */
322360private predicate typeFlow ( TypeFlowNode n , RefType t ) {
323- upcast ( n , t )
324- or
325- upcastEnhancedForStmt ( n .asSsa ( ) , t )
326- or
327- downcastSuccessor ( n .asExpr ( ) , t )
328- or
329- instanceOfGuarded ( n .asExpr ( ) , t )
330- or
331- n .asExpr ( ) .( FunctionalExpr ) .getConstructedType ( ) = t
361+ typeFlowBase ( n , t )
332362 or
333363 exists ( TypeFlowNode mid | typeFlow ( mid , t ) and step ( mid , n ) )
334364 or
@@ -363,17 +393,13 @@ private module TypeFlowBounds {
363393 */
364394 cached
365395 predicate fieldTypeFlow ( Field f , RefType t , boolean exact ) {
366- exists ( TypeFlowNode n , RefType srctype |
396+ exists ( TypeFlowNode n |
367397 n .asField ( ) = f and
368398 (
369- exactType ( n , srctype ) and exact = true
399+ exactType ( n , t ) and exact = true
370400 or
371- not exactType ( n , _) and bestTypeFlow ( n , srctype ) and exact = false
401+ not exactType ( n , _) and bestTypeFlow ( n , t ) and exact = false
372402 )
373- |
374- t = srctype .( BoundedType ) .getAnUltimateUpperBoundType ( )
375- or
376- t = srctype and not srctype instanceof BoundedType
377403 )
378404 }
379405
@@ -384,17 +410,13 @@ private module TypeFlowBounds {
384410 */
385411 cached
386412 predicate exprTypeFlow ( Expr e , RefType t , boolean exact ) {
387- exists ( TypeFlowNode n , RefType srctype |
413+ exists ( TypeFlowNode n |
388414 n .asExpr ( ) = e and
389415 (
390- exactType ( n , srctype ) and exact = true
416+ exactType ( n , t ) and exact = true
391417 or
392- not exactType ( n , _) and bestTypeFlow ( n , srctype ) and exact = false
418+ not exactType ( n , _) and bestTypeFlow ( n , t ) and exact = false
393419 )
394- |
395- t = srctype .( BoundedType ) .getAnUltimateUpperBoundType ( )
396- or
397- t = srctype and not srctype instanceof BoundedType
398420 )
399421 }
400422}
0 commit comments