@@ -1834,15 +1834,55 @@ module IteratorFlow {
18341834
18351835 private module IteratorSsa = SsaImpl:: Make< Location , SsaInput > ;
18361836
1837- private class Def extends IteratorSsa:: DefinitionExt {
1837+ private module DataFlowIntegrationInput implements IteratorSsa:: DataFlowIntegrationInputSig {
1838+ private import codeql.util.Void
1839+
1840+ class Expr extends Instruction {
1841+ Expr ( ) {
1842+ exists ( IRBlock bb , int i |
1843+ SsaInput:: variableRead ( bb , i , _, true ) and
1844+ this = bb .getInstruction ( i )
1845+ )
1846+ }
1847+
1848+ predicate hasCfgNode ( SsaInput:: BasicBlock bb , int i ) { bb .getInstruction ( i ) = this }
1849+ }
1850+
1851+ predicate ssaDefHasSource ( IteratorSsa:: WriteDefinition def ) { none ( ) }
1852+
1853+ predicate allowFlowIntoUncertainDef ( IteratorSsa:: UncertainWriteDefinition def ) { any ( ) }
1854+
1855+ class Guard extends Void {
1856+ predicate controlsBranchEdge (
1857+ SsaInput:: BasicBlock bb1 , SsaInput:: BasicBlock bb2 , boolean branch
1858+ ) {
1859+ none ( )
1860+ }
1861+ }
1862+
1863+ predicate guardDirectlyControlsBlock ( Guard guard , SsaInput:: BasicBlock bb , boolean branch ) {
1864+ none ( )
1865+ }
1866+
1867+ predicate supportBarrierGuardsOnPhiEdges ( ) { none ( ) }
1868+ }
1869+
1870+ private module DataFlowIntegrationImpl =
1871+ IteratorSsa:: DataFlowIntegration< DataFlowIntegrationInput > ;
1872+
1873+ private class IteratorSynthNode extends DataFlowIntegrationImpl:: SsaNode {
1874+ IteratorSynthNode ( ) { not this .asDefinition ( ) instanceof IteratorSsa:: WriteDefinition }
1875+ }
1876+
1877+ private class Def extends IteratorSsa:: Definition {
18381878 final override Location getLocation ( ) { result = this .getImpl ( ) .getLocation ( ) }
18391879
18401880 /**
18411881 * Holds if this definition (or use) has index `index` in block `block`,
18421882 * and is a definition (or use) of the variable `sv`.
18431883 */
18441884 predicate hasIndexInBlock ( IRBlock block , int index , SourceVariable sv ) {
1845- super .definesAt ( sv , block , index , _ )
1885+ super .definesAt ( sv , block , index )
18461886 }
18471887
18481888 private Ssa:: DefImpl getImpl ( ) {
@@ -1859,46 +1899,15 @@ module IteratorFlow {
18591899 int getIndirectionIndex ( ) { result = this .getImpl ( ) .getIndirectionIndex ( ) }
18601900 }
18611901
1862- private class PhiNode extends IteratorSsa:: DefinitionExt {
1863- PhiNode ( ) {
1864- this instanceof IteratorSsa:: PhiNode or
1865- this instanceof IteratorSsa:: PhiReadNode
1866- }
1867-
1868- SsaIteratorNode getNode ( ) { result .getIteratorFlowNode ( ) = this }
1869- }
1870-
1871- cached
1872- private module IteratorSsaCached {
1873- cached
1874- predicate adjacentDefRead ( IRBlock bb1 , int i1 , SourceVariable sv , IRBlock bb2 , int i2 ) {
1875- IteratorSsa:: adjacentDefReadExt ( _, sv , bb1 , i1 , bb2 , i2 )
1876- or
1877- exists ( PhiNode phi |
1878- IteratorSsa:: lastRefRedefExt ( _, sv , bb1 , i1 , phi ) and
1879- phi .definesAt ( sv , bb2 , i2 , _)
1880- )
1881- }
1882-
1883- cached
1884- Node getAPriorDefinition ( IteratorSsa:: DefinitionExt next ) {
1885- exists ( IRBlock bb , int i , SourceVariable sv , IteratorSsa:: DefinitionExt def |
1886- IteratorSsa:: lastRefRedefExt ( pragma [ only_bind_into ] ( def ) , pragma [ only_bind_into ] ( sv ) ,
1887- pragma [ only_bind_into ] ( bb ) , pragma [ only_bind_into ] ( i ) , next ) and
1888- nodeToDefOrUse ( result , sv , bb , i , _)
1889- )
1890- }
1891- }
1892-
18931902 /** The set of nodes necessary for iterator flow. */
1894- class IteratorFlowNode instanceof PhiNode {
1903+ class IteratorFlowNode instanceof IteratorSynthNode {
18951904 /** Gets a textual representation of this node. */
18961905 string toString ( ) { result = super .toString ( ) }
18971906
18981907 /** Gets the type of this node. */
18991908 DataFlowType getType ( ) {
19001909 exists ( Ssa:: SourceVariable sv |
1901- super .definesAt ( sv , _ , _ , _ ) and
1910+ super .getSourceVariable ( ) = sv and
19021911 result = sv .getType ( )
19031912 )
19041913 }
@@ -1910,60 +1919,33 @@ module IteratorFlow {
19101919 Location getLocation ( ) { result = super .getBasicBlock ( ) .getLocation ( ) }
19111920 }
19121921
1913- private import IteratorSsaCached
1914-
1915- private predicate defToNode ( Node node , Def def , boolean uncertain ) {
1916- (
1917- nodeHasOperand ( node , def .getValue ( ) .asOperand ( ) , def .getIndirectionIndex ( ) )
1918- or
1919- nodeHasInstruction ( node , def .getValue ( ) .asInstruction ( ) , def .getIndirectionIndex ( ) )
1920- ) and
1921- uncertain = false
1922- }
1923-
1924- private predicate nodeToDefOrUse (
1925- Node node , SourceVariable sv , IRBlock bb , int i , boolean uncertain
1926- ) {
1927- exists ( Def def |
1928- def .hasIndexInBlock ( bb , i , sv ) and
1929- defToNode ( node , def , uncertain )
1930- )
1922+ private predicate defToNode ( Node node , Def def ) {
1923+ nodeHasOperand ( node , def .getValue ( ) .asOperand ( ) , def .getIndirectionIndex ( ) )
19311924 or
1932- useToNode ( bb , i , sv , node ) and
1933- uncertain = false
1925+ nodeHasInstruction ( node , def .getValue ( ) .asInstruction ( ) , def .getIndirectionIndex ( ) )
19341926 }
19351927
1936- private predicate useToNode ( IRBlock bb , int i , SourceVariable sv , Node nodeTo ) {
1937- exists ( PhiNode phi |
1938- phi .definesAt ( sv , bb , i , _) and
1939- nodeTo = phi .getNode ( )
1940- )
1928+ bindingset [ result , v]
1929+ pragma [ inline_late]
1930+ private DataFlowIntegrationImpl:: Node fromDfNode ( Node n , SourceVariable v ) {
1931+ result = n .( SsaIteratorNode ) .getIteratorFlowNode ( )
19411932 or
1942- exists ( Ssa:: UseImpl use |
1943- use .hasIndexInBlock ( bb , i , sv ) and
1944- nodeTo = use .getNode ( )
1933+ exists ( Ssa:: UseImpl use , IRBlock bb , int i |
1934+ result .( DataFlowIntegrationImpl:: ExprNode ) .getExpr ( ) .hasCfgNode ( bb , i ) and
1935+ use .hasIndexInBlock ( bb , i , v ) and
1936+ use .getNode ( ) = n
19451937 )
1938+ or
1939+ defToNode ( n , result .( DataFlowIntegrationImpl:: SsaDefinitionNode ) .getDefinition ( ) )
19461940 }
19471941
19481942 /**
19491943 * Holds if `nodeFrom` flows to `nodeTo` in a single step.
19501944 */
19511945 predicate localFlowStep ( Node nodeFrom , Node nodeTo ) {
1952- exists (
1953- Node nFrom , SourceVariable sv , IRBlock bb1 , int i1 , IRBlock bb2 , int i2 , boolean uncertain
1954- |
1955- adjacentDefRead ( bb1 , i1 , sv , bb2 , i2 ) and
1956- nodeToDefOrUse ( nFrom , sv , bb1 , i1 , uncertain ) and
1957- useToNode ( bb2 , i2 , sv , nodeTo )
1958- |
1959- if uncertain = true
1960- then
1961- nodeFrom =
1962- [
1963- nFrom ,
1964- getAPriorDefinition ( any ( IteratorSsa:: DefinitionExt next | next .definesAt ( sv , bb1 , i1 , _) ) )
1965- ]
1966- else nFrom = nodeFrom
1946+ exists ( SourceVariable v |
1947+ nodeFrom != nodeTo and
1948+ DataFlowIntegrationImpl:: localFlowStep ( v , fromDfNode ( nodeFrom , v ) , fromDfNode ( nodeTo , v ) , _)
19671949 )
19681950 }
19691951}
0 commit comments