@@ -1459,6 +1459,15 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1459
1459
)
1460
1460
}
1461
1461
1462
+ /**
1463
+ * Holds if `def` has some form of input flow. For example, the right-hand
1464
+ * side of an assignment or a parameter of an SSA entry definition.
1465
+ *
1466
+ * For such definitions, a flow step is added from a synthetic node
1467
+ * representing the source to the definition.
1468
+ */
1469
+ default predicate ssaDefHasSource ( WriteDefinition def ) { any ( ) }
1470
+
1462
1471
/** Holds if SSA definition `def` assigns `value` to the underlying variable. */
1463
1472
predicate ssaDefAssigns ( WriteDefinition def , Expr value ) ;
1464
1473
@@ -1665,6 +1674,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1665
1674
1666
1675
cached
1667
1676
private newtype TNode =
1677
+ TWriteDefSource ( WriteDefinition def ) { DfInput:: ssaDefHasSource ( def ) } or
1668
1678
TParamNode ( DfInput:: Parameter p ) {
1669
1679
exists ( WriteDefinition def | DfInput:: ssaDefInitializesParam ( def , p ) )
1670
1680
} or
@@ -1696,6 +1706,22 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1696
1706
1697
1707
final class Node = NodeImpl ;
1698
1708
1709
+ /** A source of a write definition. */
1710
+ private class WriteDefSourceNodeImpl extends NodeImpl , TWriteDefSource {
1711
+ private WriteDefinition def ;
1712
+
1713
+ WriteDefSourceNodeImpl ( ) { this = TWriteDefSource ( def ) }
1714
+
1715
+ /** Gets the underlying definition. */
1716
+ WriteDefinition getDefinition ( ) { result = def }
1717
+
1718
+ override string toString ( ) { result = def .toString ( ) }
1719
+
1720
+ override Location getLocation ( ) { result = def .getLocation ( ) }
1721
+ }
1722
+
1723
+ final class WriteDefSourceNode = WriteDefSourceNodeImpl ;
1724
+
1699
1725
/** A parameter node. */
1700
1726
private class ParameterNodeImpl extends NodeImpl , TParamNode {
1701
1727
private DfInput:: Parameter p ;
@@ -1976,6 +2002,9 @@ module Make<LocationSig Location, InputSig<Location> Input> {
1976
2002
*/
1977
2003
predicate localFlowStep ( SourceVariable v , Node nodeFrom , Node nodeTo , boolean isUseStep ) {
1978
2004
exists ( Definition def |
2005
+ // Flow from write definition source into SSA definition
2006
+ nodeFrom = TWriteDefSource ( def )
2007
+ or
1979
2008
// Flow from assignment into SSA definition
1980
2009
DfInput:: ssaDefAssigns ( def , nodeFrom .( ExprNode ) .getExpr ( ) )
1981
2010
or
@@ -2012,6 +2041,9 @@ module Make<LocationSig Location, InputSig<Location> Input> {
2012
2041
/** Holds if the value of `nodeTo` is given by `nodeFrom`. */
2013
2042
predicate localMustFlowStep ( SourceVariable v , Node nodeFrom , Node nodeTo ) {
2014
2043
exists ( Definition def |
2044
+ // Flow from write definition source into SSA definition
2045
+ nodeFrom = TWriteDefSource ( def )
2046
+ or
2015
2047
// Flow from assignment into SSA definition
2016
2048
DfInput:: ssaDefAssigns ( def , nodeFrom .( ExprNode ) .getExpr ( ) )
2017
2049
or
0 commit comments