@@ -1834,15 +1834,55 @@ module IteratorFlow {
1834
1834
1835
1835
private module IteratorSsa = SsaImpl:: Make< Location , SsaInput > ;
1836
1836
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 {
1838
1878
final override Location getLocation ( ) { result = this .getImpl ( ) .getLocation ( ) }
1839
1879
1840
1880
/**
1841
1881
* Holds if this definition (or use) has index `index` in block `block`,
1842
1882
* and is a definition (or use) of the variable `sv`.
1843
1883
*/
1844
1884
predicate hasIndexInBlock ( IRBlock block , int index , SourceVariable sv ) {
1845
- super .definesAt ( sv , block , index , _ )
1885
+ super .definesAt ( sv , block , index )
1846
1886
}
1847
1887
1848
1888
private Ssa:: DefImpl getImpl ( ) {
@@ -1859,46 +1899,15 @@ module IteratorFlow {
1859
1899
int getIndirectionIndex ( ) { result = this .getImpl ( ) .getIndirectionIndex ( ) }
1860
1900
}
1861
1901
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
-
1893
1902
/** The set of nodes necessary for iterator flow. */
1894
- class IteratorFlowNode instanceof PhiNode {
1903
+ class IteratorFlowNode instanceof IteratorSynthNode {
1895
1904
/** Gets a textual representation of this node. */
1896
1905
string toString ( ) { result = super .toString ( ) }
1897
1906
1898
1907
/** Gets the type of this node. */
1899
1908
DataFlowType getType ( ) {
1900
1909
exists ( Ssa:: SourceVariable sv |
1901
- super .definesAt ( sv , _ , _ , _ ) and
1910
+ super .getSourceVariable ( ) = sv and
1902
1911
result = sv .getType ( )
1903
1912
)
1904
1913
}
@@ -1910,60 +1919,33 @@ module IteratorFlow {
1910
1919
Location getLocation ( ) { result = super .getBasicBlock ( ) .getLocation ( ) }
1911
1920
}
1912
1921
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 ( ) )
1931
1924
or
1932
- useToNode ( bb , i , sv , node ) and
1933
- uncertain = false
1925
+ nodeHasInstruction ( node , def .getValue ( ) .asInstruction ( ) , def .getIndirectionIndex ( ) )
1934
1926
}
1935
1927
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 ( )
1941
1932
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
1945
1937
)
1938
+ or
1939
+ defToNode ( n , result .( DataFlowIntegrationImpl:: SsaDefinitionNode ) .getDefinition ( ) )
1946
1940
}
1947
1941
1948
1942
/**
1949
1943
* Holds if `nodeFrom` flows to `nodeTo` in a single step.
1950
1944
*/
1951
1945
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 ) , _)
1967
1949
)
1968
1950
}
1969
1951
}
0 commit comments