@@ -127,10 +127,11 @@ private predicate sideEffectCfg(ControlFlow::Node src, ControlFlow::Node dst) {
127127
128128/**
129129 * Holds if `dominator` is the immediate dominator of `node` in
130- * the side-effect CFG.
130+ * the side-effect CFG belonging to `entry` .
131131 */
132- private predicate iDomEffect ( ControlFlow:: Node dominator , ControlFlow:: Node node ) =
133- idominance( entryNode / 1 , sideEffectCfg / 2 ) ( _, dominator , node )
132+ private predicate iDomEffect (
133+ ControlFlow:: Node entry , ControlFlow:: Node dominator , ControlFlow:: Node node
134+ ) = idominance( entryNode / 1 , sideEffectCfg / 2 ) ( entry , dominator , node )
134135
135136/**
136137 * Gets the most recent side effect. To be more precise, `result` is a
@@ -181,15 +182,21 @@ private predicate iDomEffect(ControlFlow::Node dominator, ControlFlow::Node node
181182 * The immediate dominator path to line 015 is 000 - 009 - 012 - 015.
182183 * Therefore, the most recent side effect for line 015 is line 009.
183184 */
184- cached
185- private ControlFlow:: Node mostRecentSideEffect ( ControlFlow:: Node node ) {
186- exists ( ControlFlow:: Node entry |
187- entryNode ( entry ) and
188- iDomEffect ( entry , result ) and
189- iDomEffect * ( result , node )
185+ private ControlFlow:: Node mostRecentSideEffect ( ControlFlow:: Node entry , ControlFlow:: Node node ) {
186+ iDomEffect ( entry , entry , result ) and
187+ result = node
188+ or
189+ exists ( ControlFlow:: Node mid |
190+ result = mostRecentSideEffect ( entry , mid ) and
191+ iDomEffect ( entry , mid , node )
190192 )
191193}
192194
195+ cached
196+ private ControlFlow:: Node mostRecentSideEffectUnique ( ControlFlow:: Node node ) {
197+ result = unique( | | mostRecentSideEffect ( _, node ) )
198+ }
199+
193200/** Used to represent the "global value number" of an expression. */
194201cached
195202private newtype GvnBase =
@@ -369,10 +376,12 @@ private predicate mkMethodAccess(DataFlow::Node access, GVN qualifier, Method m)
369376 )
370377}
371378
372- private predicate analyzableFieldRead ( Read fread , DataFlow:: Node base , Field f ) {
379+ private predicate analyzableFieldRead (
380+ Read fread , DataFlow:: Node base , Field f , ControlFlow:: Node dominator
381+ ) {
373382 exists ( IR:: ReadInstruction r | r = fread .asInstruction ( ) |
374383 r .readsField ( base .asInstruction ( ) , f ) and
375- strictcount ( mostRecentSideEffect ( r ) ) = 1 and
384+ dominator = mostRecentSideEffectUnique ( r ) and
376385 not r .isConst ( )
377386 )
378387}
@@ -381,9 +390,8 @@ private predicate mkFieldRead(
381390 DataFlow:: Node fread , GVN qualifier , Field v , ControlFlow:: Node dominator
382391) {
383392 exists ( DataFlow:: Node base |
384- analyzableFieldRead ( fread , base , v ) and
385- qualifier = globalValueNumber ( base ) and
386- dominator = mostRecentSideEffect ( fread .asInstruction ( ) )
393+ analyzableFieldRead ( fread , base , v , dominator ) and
394+ qualifier = globalValueNumber ( base )
387395 )
388396}
389397
@@ -421,18 +429,17 @@ private predicate incompleteSsa(ValueEntity v) {
421429/**
422430 * Holds if `access` is an access to a variable `target` for which SSA information is incomplete.
423431 */
424- private predicate analyzableOtherVariable ( DataFlow:: Node access , ValueEntity target ) {
432+ private predicate analyzableOtherVariable (
433+ DataFlow:: Node access , ValueEntity target , ControlFlow:: Node dominator
434+ ) {
425435 access .asInstruction ( ) .reads ( target ) and
426436 incompleteSsa ( target ) and
427- strictcount ( mostRecentSideEffect ( access .asInstruction ( ) ) ) = 1 and
437+ dominator = mostRecentSideEffectUnique ( access .asInstruction ( ) ) and
428438 not access .isConst ( ) and
429439 not target instanceof Function
430440}
431441
432- private predicate mkOtherVariable ( DataFlow:: Node access , ValueEntity x , ControlFlow:: Node dominator ) {
433- analyzableOtherVariable ( access , x ) and
434- dominator = mostRecentSideEffect ( access .asInstruction ( ) )
435- }
442+ private predicate mkOtherVariable = analyzableOtherVariable / 3 ;
436443
437444private predicate analyzableBinaryOp (
438445 DataFlow:: BinaryOperationNode op , string opname , DataFlow:: Node lhs , DataFlow:: Node rhs
@@ -463,29 +470,29 @@ private predicate mkUnaryOp(DataFlow::UnaryOperationNode op, GVN child, string o
463470 opname = op .getOperator ( )
464471}
465472
466- private predicate analyzableIndexExpr ( DataFlow:: ElementReadNode ae ) {
467- strictcount ( mostRecentSideEffect ( ae .asInstruction ( ) ) ) = 1 and
473+ private predicate analyzableIndexExpr ( DataFlow:: ElementReadNode ae , ControlFlow :: Node dominator ) {
474+ dominator = mostRecentSideEffectUnique ( ae .asInstruction ( ) ) and
468475 not ae .isConst ( )
469476}
470477
471478private predicate mkIndex (
472479 DataFlow:: ElementReadNode ae , GVN base , GVN offset , ControlFlow:: Node dominator
473480) {
474- analyzableIndexExpr ( ae ) and
481+ analyzableIndexExpr ( ae , dominator ) and
475482 base = globalValueNumber ( ae .getBase ( ) ) and
476- offset = globalValueNumber ( ae .getIndex ( ) ) and
477- dominator = mostRecentSideEffect ( ae .asInstruction ( ) )
483+ offset = globalValueNumber ( ae .getIndex ( ) )
478484}
479485
480- private predicate analyzablePointerDereferenceExpr ( DataFlow:: PointerDereferenceNode deref ) {
481- strictcount ( mostRecentSideEffect ( deref .asInstruction ( ) ) ) = 1 and
486+ private predicate analyzablePointerDereferenceExpr (
487+ DataFlow:: PointerDereferenceNode deref , ControlFlow:: Node dominator
488+ ) {
489+ dominator = mostRecentSideEffectUnique ( deref .asInstruction ( ) ) and
482490 not deref .isConst ( )
483491}
484492
485493private predicate mkDeref ( DataFlow:: PointerDereferenceNode deref , GVN p , ControlFlow:: Node dominator ) {
486- analyzablePointerDereferenceExpr ( deref ) and
487- p = globalValueNumber ( deref .getOperand ( ) ) and
488- dominator = mostRecentSideEffect ( deref .asInstruction ( ) )
494+ analyzablePointerDereferenceExpr ( deref , dominator ) and
495+ p = globalValueNumber ( deref .getOperand ( ) )
489496}
490497
491498private predicate ssaInit ( SsaExplicitDefinition ssa , DataFlow:: Node rhs ) {
@@ -587,12 +594,12 @@ private predicate analyzableExpr(DataFlow::Node e) {
587594 analyzableConst ( e ) or
588595 any ( DataFlow:: SsaNode ssa ) .getAUse ( ) = e or
589596 e instanceof DataFlow:: SsaNode or
590- analyzableOtherVariable ( e , _) or
597+ analyzableOtherVariable ( e , _, _ ) or
591598 analyzableMethodAccess ( e , _, _) or
592- analyzableFieldRead ( e , _, _) or
599+ analyzableFieldRead ( e , _, _, _ ) or
593600 analyzableCall ( e , _) or
594601 analyzableBinaryOp ( e , _, _, _) or
595602 analyzableUnaryOp ( e ) or
596- analyzableIndexExpr ( e ) or
597- analyzablePointerDereferenceExpr ( e )
603+ analyzableIndexExpr ( e , _ ) or
604+ analyzablePointerDereferenceExpr ( e , _ )
598605}
0 commit comments