@@ -29,6 +29,8 @@ module SsaInput implements SsaImplCommon::InputSig<Location> {
2929 (
3030 uninitializedWrite ( bb , i , v )
3131 or
32+ parameterWrite ( bb , i , v )
33+ or
3234 variableWriteActual ( bb , i , v , _)
3335 ) and
3436 certain = true
@@ -58,6 +60,39 @@ predicate uninitializedWrite(Cfg::EntryBasicBlock bb, int i, LocalVariable v) {
5860 i = - 1
5961}
6062
63+ /**
64+ * Gets index of `p` in a version of the enclosing function where the parameter
65+ * list is reversed.
66+ *
67+ * For example, given
68+ * ```ps
69+ * function f($a, $b) { ... }
70+ * ```
71+ * the inverted index of `$a` is 1, and the inverted index of `$b` is 0.
72+ */
73+ private int getInvertedIndex ( Parameter p ) {
74+ exists ( int i |
75+ p .getIndex ( ) = i or
76+ p .hasParameterBlock ( _, i )
77+ |
78+ result = p .getFunction ( ) .getNumberOfParameters ( ) - i - 1
79+ )
80+ }
81+
82+ /**
83+ * Holds if the the SSA definition of `p` should be placed at index `i` in
84+ * block `bb`. Note that the index may be negative.
85+ */
86+ predicate parameterWrite ( Cfg:: EntryBasicBlock bb , int i , Parameter p ) {
87+ exists ( Function f |
88+ f .getEntryBasicBlock ( ) = bb and
89+ p .getFunction ( ) = f and
90+ // If the enclosing function has 2 parameters we map the index of parameter
91+ // 0 to -2, the index of parameter 1 to -1.
92+ i = - getInvertedIndex ( p ) - 1
93+ )
94+ }
95+
6196/** Holds if `v` is read at index `i` in basic block `bb`. */
6297private predicate variableReadActual ( Cfg:: BasicBlock bb , int i , LocalScopeVariable v ) {
6398 exists ( VarReadAccess read |
@@ -159,6 +194,9 @@ private module Cached {
159194 n = bb .getNode ( i )
160195 |
161196 write .isExplicitWrite ( n )
197+ or
198+ write .isImplicitWrite ( ) and
199+ n = write
162200 )
163201 }
164202
@@ -281,19 +319,20 @@ class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
281319 override Location getLocation ( ) { result = Impl:: PhiReadNode .super .getLocation ( ) }
282320}
283321
284- abstract class NormalParameter extends Parameter { }
285-
286322/** Gets the SSA definition node corresponding to parameter `p`. */
287323pragma [ nomagic]
288324DefinitionExt getParameterDef ( Parameter p ) {
289- none ( ) // TODO
325+ exists ( Cfg:: EntryBasicBlock bb , int i |
326+ parameterWrite ( bb , i , p ) and
327+ result .definesAt ( p , bb , i , _)
328+ )
290329}
291330
292- private newtype TParameterExt = TNormalParameter ( NormalParameter p )
331+ private newtype TParameterExt = TNormalParameter ( Parameter p )
293332
294333/** A normal parameter or an implicit `self` parameter. */
295334class ParameterExt extends TParameterExt {
296- NormalParameter asParameter ( ) { this = TNormalParameter ( result ) }
335+ Parameter asParameter ( ) { this = TNormalParameter ( result ) }
297336
298337 predicate isInitializedBy ( WriteDefinition def ) { def = getParameterDef ( this .asParameter ( ) ) }
299338
0 commit comments