@@ -1977,13 +1977,23 @@ module IteratorFlow {
19771977 }
19781978
19791979 /**
1980- * Gets an ultimate definition of `def`.
1981- *
1982- * Note: Unlike `def.getAnUltimateDefinition()` this predicate also
1983- * traverses back through iterator increment and decrement operations.
1980+ * Holds if `write` is an instruction that writes to address `address`
19841981 */
1985- private Ssa:: Definition getAnUltimateDefinition ( Ssa:: Definition def ) {
1986- result = def .getAnUltimateDefinition ( )
1982+ private predicate isIteratorWrite ( Instruction write , Operand address ) {
1983+ exists ( Ssa:: DefImpl writeDef , IRBlock bb , int i |
1984+ writeDef .hasIndexInBlock ( _, bb , i ) and
1985+ bb .getInstruction ( i ) = write and
1986+ address = writeDef .getAddressOperand ( )
1987+ )
1988+ }
1989+
1990+ private module GetAnUltimateDefinitionInput implements Ssa:: GetAnUltimateDefinitionSig {
1991+ predicate isRelevantUltimateDefinition ( Ssa:: Definition def ) { fwd ( _, def ) }
1992+ }
1993+
1994+ private Ssa:: Definition getAnUltimateDefinitionStep ( Ssa:: Definition def ) {
1995+ result =
1996+ Ssa:: GetAnUltimateDefinition< GetAnUltimateDefinitionInput > :: getAnUltimateDefinition ( def )
19871997 or
19881998 exists ( IRBlock bb , int i , IteratorCrementCall crementCall , Ssa:: SourceVariable sv |
19891999 crementCall = def .getValue ( ) .asInstruction ( ) .( StoreInstruction ) .getSourceValue ( ) and
@@ -1993,14 +2003,28 @@ module IteratorFlow {
19932003 )
19942004 }
19952005
1996- /**
1997- * Holds if `write` is an instruction that writes to address `address`
1998- */
1999- private predicate isIteratorWrite ( Instruction write , Operand address ) {
2000- exists ( Ssa:: DefImpl writeDef , IRBlock bb , int i |
2001- writeDef .hasIndexInBlock ( _, bb , i ) and
2002- bb .getInstruction ( i ) = write and
2003- address = writeDef .getAddressOperand ( )
2006+ private predicate isSource ( GetsIteratorCall beginCall , Ssa:: Definition def ) {
2007+ exists ( StoreInstruction beginStore |
2008+ beginStore = def .getValue ( ) .asInstruction ( ) and
2009+ operandForFullyConvertedCall ( beginStore .getSourceValueOperand ( ) , beginCall )
2010+ )
2011+ }
2012+
2013+ private predicate isSink ( Instruction writeToDeref , Ssa:: Definition def ) {
2014+ exists ( IteratorPointerDereferenceCall starCall , Operand address , IRBlock bbStar , int iStar |
2015+ isIteratorWrite ( writeToDeref , address ) and
2016+ operandForFullyConvertedCall ( address , starCall ) and
2017+ bbStar .getInstruction ( iStar ) = starCall and
2018+ Ssa:: ssaDefReachesRead ( _, def , bbStar , iStar )
2019+ )
2020+ }
2021+
2022+ private predicate fwd ( GetsIteratorCall beginCall , Ssa:: Definition def ) {
2023+ isSource ( beginCall , def )
2024+ or
2025+ exists ( Ssa:: Definition def0 |
2026+ fwd ( beginCall , def0 ) and
2027+ def0 = getAnUltimateDefinitionStep ( def )
20042028 )
20052029 }
20062030
@@ -2016,17 +2040,9 @@ module IteratorFlow {
20162040 private predicate isIteratorStoreInstruction (
20172041 GetsIteratorCall beginCall , Instruction writeToDeref
20182042 ) {
2019- exists (
2020- StoreInstruction beginStore , IRBlock bbStar , int iStar , Ssa:: Definition def ,
2021- IteratorPointerDereferenceCall starCall , Ssa:: Definition ultimate , Operand address
2022- |
2023- isIteratorWrite ( writeToDeref , address ) and
2024- operandForFullyConvertedCall ( address , starCall ) and
2025- bbStar .getInstruction ( iStar ) = starCall and
2026- Ssa:: ssaDefReachesRead ( _, def , bbStar , iStar ) and
2027- ultimate = getAnUltimateDefinition * ( def ) and
2028- beginStore = ultimate .getValue ( ) .asInstruction ( ) and
2029- operandForFullyConvertedCall ( beginStore .getSourceValueOperand ( ) , beginCall )
2043+ exists ( Ssa:: Definition def |
2044+ fwd ( beginCall , def ) and
2045+ isSink ( writeToDeref , def )
20302046 )
20312047 }
20322048
0 commit comments