@@ -1459,6 +1459,15 @@ module Make<LocationSig Location, InputSig<Location> Input> {
14591459 )
14601460 }
14611461
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+
14621471 /** Holds if SSA definition `def` assigns `value` to the underlying variable. */
14631472 predicate ssaDefAssigns ( WriteDefinition def , Expr value ) ;
14641473
@@ -1665,6 +1674,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
16651674
16661675 cached
16671676 private newtype TNode =
1677+ TWriteDefSource ( WriteDefinition def ) { DfInput:: ssaDefHasSource ( def ) } or
16681678 TParamNode ( DfInput:: Parameter p ) {
16691679 exists ( WriteDefinition def | DfInput:: ssaDefInitializesParam ( def , p ) )
16701680 } or
@@ -1696,6 +1706,22 @@ module Make<LocationSig Location, InputSig<Location> Input> {
16961706
16971707 final class Node = NodeImpl ;
16981708
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+
16991725 /** A parameter node. */
17001726 private class ParameterNodeImpl extends NodeImpl , TParamNode {
17011727 private DfInput:: Parameter p ;
@@ -1976,6 +2002,9 @@ module Make<LocationSig Location, InputSig<Location> Input> {
19762002 */
19772003 predicate localFlowStep ( SourceVariable v , Node nodeFrom , Node nodeTo , boolean isUseStep ) {
19782004 exists ( Definition def |
2005+ // Flow from write definition source into SSA definition
2006+ nodeFrom = TWriteDefSource ( def )
2007+ or
19792008 // Flow from assignment into SSA definition
19802009 DfInput:: ssaDefAssigns ( def , nodeFrom .( ExprNode ) .getExpr ( ) )
19812010 or
@@ -2012,6 +2041,9 @@ module Make<LocationSig Location, InputSig<Location> Input> {
20122041 /** Holds if the value of `nodeTo` is given by `nodeFrom`. */
20132042 predicate localMustFlowStep ( SourceVariable v , Node nodeFrom , Node nodeTo ) {
20142043 exists ( Definition def |
2044+ // Flow from write definition source into SSA definition
2045+ nodeFrom = TWriteDefSource ( def )
2046+ or
20152047 // Flow from assignment into SSA definition
20162048 DfInput:: ssaDefAssigns ( def , nodeFrom .( ExprNode ) .getExpr ( ) )
20172049 or
0 commit comments