66 * Provides classes for working with static single assignment (SSA) form.
77 */
88module Ssa {
9- private import semmle.code.powershell.Cfg
109 private import powershell
10+ private import semmle.code.powershell.Cfg
1111 private import internal.SsaImpl as SsaImpl
12- private import CfgNodes
13- private import ExprNodes
12+ private import CfgNodes:: ExprNodes
1413
1514 /** A static single assignment (SSA) definition. */
1615 class Definition extends SsaImpl:: Definition {
@@ -23,8 +22,10 @@ module Ssa {
2322 exists ( BasicBlock bb , int i | this .definesAt ( _, bb , i ) | result = bb .getNode ( i ) )
2423 }
2524
26- /** Gets a control-flow node that reads the value of this SSA definition. */
27- final AstCfgNode getARead ( ) { result = SsaImpl:: getARead ( this ) }
25+ /**
26+ * Gets a control-flow node that reads the value of this SSA definition.
27+ */
28+ final VarReadAccessCfgNode getARead ( ) { result = SsaImpl:: getARead ( this ) }
2829
2930 /**
3031 * Gets a first control-flow node that reads the value of this SSA definition.
@@ -38,16 +39,14 @@ module Ssa {
3839 * That is, a read that can reach the end of the enclosing CFG scope, or another
3940 * SSA definition for the source variable, without passing through any other read.
4041 */
41- final VarReadAccessCfgNode getALastRead ( ) { SsaImpl:: lastRead ( this , result ) }
42+ deprecated final VarReadAccessCfgNode getALastRead ( ) { SsaImpl:: lastRead ( this , result ) }
4243
4344 /**
4445 * Holds if `read1` and `read2` are adjacent reads of this SSA definition.
4546 * That is, `read2` can be reached from `read1` without passing through
4647 * another read.
4748 */
48- final predicate hasAdjacentReads (
49- VarReadAccessCfgNode read1 , VarReadAccessCfgNode read2
50- ) {
49+ final predicate hasAdjacentReads ( VarReadAccessCfgNode read1 , VarReadAccessCfgNode read2 ) {
5150 SsaImpl:: adjacentReadPair ( this , read1 , read2 )
5251 }
5352
@@ -91,7 +90,7 @@ module Ssa {
9190 /**
9291 * Holds if this SSA definition assigns `value` to the underlying variable.
9392 */
94- predicate assigns ( CfgNodes:: StmtCfgNode value ) {
93+ predicate assigns ( CfgNodes:: ExprCfgNode value ) {
9594 exists ( CfgNodes:: StmtNodes:: AssignStmtCfgNode a , BasicBlock bb , int i |
9695 this .definesAt ( _, bb , i ) and
9796 a = bb .getNode ( i ) and
@@ -104,19 +103,19 @@ module Ssa {
104103 final override Location getLocation ( ) { result = write .getLocation ( ) }
105104 }
106105
107- class ParameterDefinition extends Definition , SsaImpl:: WriteDefinition {
108- private Variable v ;
106+ /**
107+ * An SSA definition that corresponds to the value of `this` upon entry to a method.
108+ */
109+ class ThisDefinition extends Definition , SsaImpl:: WriteDefinition {
110+ private ThisParameter v ;
109111
110- ParameterDefinition ( ) {
111- exists ( BasicBlock bb , int i |
112- this .definesAt ( v , bb , i ) and
113- SsaImpl:: parameterWrite ( bb , i , v )
114- )
115- }
112+ ThisDefinition ( ) { exists ( BasicBlock bb , int i | this .definesAt ( v , bb , i ) ) }
113+
114+ override ThisParameter getSourceVariable ( ) { result = v }
116115
117- final override string toString ( ) { result = "<parameter> " + v }
116+ final override string toString ( ) { result = "self ( " + v . getDeclaringScope ( ) + ")" }
118117
119- final override Location getLocation ( ) { result = v .getLocation ( ) }
118+ final override Location getLocation ( ) { result = this . getControlFlowNode ( ) .getLocation ( ) }
120119 }
121120
122121 /**
@@ -138,7 +137,7 @@ module Ssa {
138137 final override Location getLocation ( ) { result = this .getBasicBlock ( ) .getLocation ( ) }
139138 }
140139
141- /** A phi node. */
140+ /** phi node. */
142141 class PhiNode extends Definition , SsaImpl:: PhiNode {
143142 /** Gets an input of this phi node. */
144143 final Definition getAnInput ( ) { this .hasInputFromBlock ( result , _) }
@@ -148,7 +147,20 @@ module Ssa {
148147 inp = SsaImpl:: phiHasInputFromBlock ( this , bb )
149148 }
150149
151- override string toString ( ) { result = "phi" }
150+ private string getSplitString ( ) {
151+ result = this .getBasicBlock ( ) .getFirstNode ( ) .( CfgNodes:: AstCfgNode ) .getSplitsString ( )
152+ }
153+
154+ override string toString ( ) {
155+ exists ( string prefix |
156+ prefix = "[" + this .getSplitString ( ) + "] "
157+ or
158+ not exists ( this .getSplitString ( ) ) and
159+ prefix = ""
160+ |
161+ result = prefix + "phi"
162+ )
163+ }
152164
153165 /**
154166 * The location of a phi node is the same as the location of the first node
0 commit comments