Ruby: Add tests for phi reads

This commit is contained in:
Tom Hvitved
2022-11-10 14:28:35 +01:00
parent bd78e73131
commit 67f31ffdf0
9 changed files with 220 additions and 15 deletions

View File

@@ -1,5 +1,6 @@
import codeql.ruby.dataflow.SSA
import codeql.ruby.dataflow.internal.SsaImpl::Consistency
import codeql.ruby.dataflow.internal.SsaImpl
import Consistency
class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
override predicate hasLocationInfo(
@@ -8,3 +9,11 @@ class MyRelevantDefinition extends RelevantDefinition, Ssa::Definition {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}
class MyRelevantDefinitionExt extends RelevantDefinitionExt, DefinitionExt {
override predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
}
}

View File

@@ -2,6 +2,7 @@ private import codeql.ssa.Ssa as SsaImplCommon
private import codeql.ruby.AST
private import codeql.ruby.CFG as Cfg
private import codeql.ruby.controlflow.internal.ControlFlowGraphImplShared as ControlFlowGraphImplShared
private import codeql.ruby.dataflow.SSA
private import codeql.ruby.ast.Variable
private import Cfg::CfgNodes::ExprNodes
@@ -61,7 +62,23 @@ private module SsaInput implements SsaImplCommon::InputSig {
}
}
import SsaImplCommon::Make<SsaInput>
private import SsaImplCommon::Make<SsaInput> as Impl
class Definition = Impl::Definition;
class WriteDefinition = Impl::WriteDefinition;
class UncertainWriteDefinition = Impl::UncertainWriteDefinition;
class PhiNode = Impl::PhiNode;
module Consistency = Impl::Consistency;
module ExposedForTestingOnly {
predicate ssaDefReachesReadExt = Impl::ssaDefReachesReadExt/4;
predicate phiHasInputFromBlockExt = Impl::phiHasInputFromBlockExt/3;
}
/** Holds if `v` is uninitialized at index `i` in entry block `bb`. */
predicate uninitializedWrite(Cfg::EntryBasicBlock bb, int i, LocalVariable v) {
@@ -204,7 +221,7 @@ private predicate adjacentDefRead(
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2,
SsaInput::SourceVariable v
) {
adjacentDefRead(def, bb1, i1, bb2, i2) and
Impl::adjacentDefRead(def, bb1, i1, bb2, i2) and
v = def.getSourceVariable()
}
@@ -220,7 +237,7 @@ private predicate adjacentDefReachesRead(
exists(SsaInput::BasicBlock bb3, int i3 |
adjacentDefReachesRead(def, bb1, i1, bb3, i3) and
SsaInput::variableRead(bb3, i3, _, false) and
adjacentDefRead(def, bb3, i3, bb2, i2)
Impl::adjacentDefRead(def, bb3, i3, bb2, i2)
)
}
@@ -243,11 +260,11 @@ private predicate adjacentDefReachesUncertainRead(
/** Same as `lastRefRedef`, but skips uncertain reads. */
pragma[nomagic]
private predicate lastRefSkipUncertainReads(Definition def, SsaInput::BasicBlock bb, int i) {
lastRef(def, bb, i) and
Impl::lastRef(def, bb, i) and
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
or
exists(SsaInput::BasicBlock bb0, int i0 |
lastRef(def, bb0, i0) and
Impl::lastRef(def, bb0, i0) and
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
)
}
@@ -304,7 +321,7 @@ private module Cached {
cached
VariableReadAccessCfgNode getARead(Definition def) {
exists(LocalVariable v, Cfg::BasicBlock bb, int i |
ssaDefReachesRead(v, def, bb, i) and
Impl::ssaDefReachesRead(v, def, bb, i) and
variableReadActual(bb, i, v) and
result = bb.getNode(i)
)
@@ -315,7 +332,7 @@ private module Cached {
Definition def, CallCfgNode call, LocalVariable v, Cfg::CfgScope scope
) {
exists(Cfg::BasicBlock bb, int i |
ssaDefReachesRead(v, def, bb, i) and
Impl::ssaDefReachesRead(v, def, bb, i) and
capturedCallRead(call, bb, i, v) and
scope.getOuterCfgScope() = bb.getScope()
)
@@ -360,7 +377,7 @@ private module Cached {
Definition def, LocalVariable v, Cfg::CfgScope scope
) {
exists(Cfg::BasicBlock bb, int i |
ssaDefReachesRead(v, def, bb, i) and
Impl::ssaDefReachesRead(v, def, bb, i) and
capturedExitRead(bb, i, v) and
scope = bb.getScope().getOuterCfgScope*()
)
@@ -403,7 +420,7 @@ private module Cached {
cached
Definition phiHasInputFromBlock(PhiNode phi, Cfg::BasicBlock bb) {
phiHasInputFromBlock(phi, result, bb)
Impl::phiHasInputFromBlock(phi, result, bb)
}
/**
@@ -459,19 +476,45 @@ private module Cached {
*/
cached
predicate lastRefBeforeRedef(Definition def, Cfg::BasicBlock bb, int i, Definition next) {
lastRefRedef(def, bb, i, next) and
Impl::lastRefRedef(def, bb, i, next) and
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
or
exists(SsaInput::BasicBlock bb0, int i0 |
lastRefRedef(def, bb0, i0, next) and
Impl::lastRefRedef(def, bb0, i0, next) and
adjacentDefReachesUncertainRead(def, bb, i, bb0, i0)
)
}
cached
Definition uncertainWriteDefinitionInput(UncertainWriteDefinition def) {
uncertainWriteDefinitionInput(def, result)
Impl::uncertainWriteDefinitionInput(def, result)
}
}
import Cached
/**
* An extended static single assignment (SSA) definition.
*
* This is either a normal SSA definition (`Definition`) or a
* phi-read node (`PhiReadNode`).
*
* Only intended for internal use.
*/
class DefinitionExt extends Impl::DefinitionExt {
override string toString() { result = this.(Ssa::Definition).toString() }
/** Gets the location of this definition. */
Location getLocation() { result = this.(Ssa::Definition).getLocation() }
}
/**
* A phi-read node.
*
* Only intended for internal use.
*/
class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
override string toString() { result = "SSA phi read(" + this.getSourceVariable() + ")" }
override Location getLocation() { result = this.getBasicBlock().getLocation() }
}

View File

@@ -38,6 +38,10 @@ parameterVariable
| ssa.rb:53:8:53:10 | foo | ssa.rb:53:8:53:10 | foo |
| ssa.rb:64:8:64:8 | a | ssa.rb:64:8:64:8 | a |
| ssa.rb:66:15:66:15 | a | ssa.rb:66:15:66:15 | a |
| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 |
| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 |
| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 |
| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 |
parameterNoVariable
| parameters.rb:45:22:45:22 | _ |
parameterVariableNoAccess

View File

@@ -164,6 +164,12 @@ definition
| ssa.rb:83:7:87:5 | <captured> self | ssa.rb:81:1:88:3 | self |
| ssa.rb:84:10:86:8 | <captured> captured | ssa.rb:82:3:82:10 | captured |
| ssa.rb:84:10:86:8 | <captured> self | ssa.rb:81:1:88:3 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self |
| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 |
| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 |
| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 |
| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x |
read
| class_variables.rb:1:1:29:4 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self |
| class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self |
@@ -347,6 +353,18 @@ read
| ssa.rb:83:7:87:5 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self |
| ssa.rb:84:10:86:8 | <captured> captured | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
| ssa.rb:84:10:86:8 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:99:5:99:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:101:5:101:10 | self |
| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:92:7:92:8 | b1 |
| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:94:10:94:11 | b2 |
| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:98:7:98:8 | b3 |
| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:100:10:100:11 | b4 |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:101:10:101:10 | x |
firstRead
| class_variables.rb:1:1:29:4 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self |
| class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self |
@@ -485,6 +503,18 @@ firstRead
| ssa.rb:83:7:87:5 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self |
| ssa.rb:84:10:86:8 | <captured> captured | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
| ssa.rb:84:10:86:8 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:99:5:99:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:101:5:101:10 | self |
| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:92:7:92:8 | b1 |
| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:94:10:94:11 | b2 |
| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:98:7:98:8 | b3 |
| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:100:10:100:11 | b4 |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:101:10:101:10 | x |
lastRead
| class_variables.rb:1:1:29:4 | self (class_variables.rb) | class_variables.rb:1:1:29:4 | self | class_variables.rb:3:1:3:5 | self |
| class_variables.rb:5:1:7:3 | self (print) | class_variables.rb:5:1:7:3 | self | class_variables.rb:6:2:6:6 | self |
@@ -624,6 +654,18 @@ lastRead
| ssa.rb:83:7:87:5 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:84:6:86:8 | self |
| ssa.rb:84:10:86:8 | <captured> captured | ssa.rb:82:3:82:10 | captured | ssa.rb:85:15:85:22 | captured |
| ssa.rb:84:10:86:8 | <captured> self | ssa.rb:81:1:88:3 | self | ssa.rb:85:10:85:22 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:99:5:99:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:101:5:101:10 | self |
| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:92:7:92:8 | b1 |
| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:94:10:94:11 | b2 |
| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:98:7:98:8 | b3 |
| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:100:10:100:11 | b4 |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:101:10:101:10 | x |
adjacentReads
| class_variables.rb:26:1:29:3 | self (N) | class_variables.rb:26:1:29:3 | self | class_variables.rb:27:3:27:11 | self | class_variables.rb:28:3:28:7 | self |
| instance_variables.rb:1:1:44:4 | self (instance_variables.rb) | instance_variables.rb:1:1:44:4 | self | instance_variables.rb:1:1:1:4 | self | instance_variables.rb:11:1:11:9 | self |
@@ -674,6 +716,14 @@ adjacentReads
| ssa.rb:38:1:42:3 | self (m4) | ssa.rb:38:1:42:3 | self | ssa.rb:39:8:39:9 | self | ssa.rb:41:3:41:13 | self |
| ssa.rb:66:11:70:5 | <captured> captured | ssa.rb:65:3:65:10 | captured | ssa.rb:68:10:68:17 | captured | ssa.rb:69:5:69:12 | captured |
| ssa.rb:66:11:70:5 | <captured> self | ssa.rb:64:1:72:3 | self | ssa.rb:67:5:67:10 | self | ssa.rb:68:5:68:17 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self | ssa.rb:99:5:99:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:93:5:93:10 | self | ssa.rb:101:5:101:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self | ssa.rb:99:5:99:10 | self |
| ssa.rb:90:1:103:3 | self (m12) | ssa.rb:90:1:103:3 | self | ssa.rb:95:5:95:10 | self | ssa.rb:101:5:101:10 | self |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | ssa.rb:99:10:99:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:93:10:93:10 | x | ssa.rb:101:10:101:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | ssa.rb:99:10:99:10 | x |
| ssa.rb:91:3:91:7 | ... = ... | ssa.rb:91:3:91:3 | x | ssa.rb:95:10:95:10 | x | ssa.rb:101:10:101:10 | x |
phi
| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:1:38:3 | <uninitialized> |
| parameters.rb:37:3:37:18 | phi | parameters.rb:35:16:35:16 | b | parameters.rb:35:16:35:20 | ... = ... |
@@ -689,3 +739,30 @@ phi
| ssa.rb:45:3:45:12 | phi | ssa.rb:45:3:45:3 | x | ssa.rb:45:3:45:7 | ... = ... |
| ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:49:1:51:3 | <uninitialized> |
| ssa.rb:50:3:50:8 | phi | ssa.rb:49:14:49:14 | y | ssa.rb:49:14:49:19 | ... = ... |
phiReadNode
| parameters.rb:26:3:26:11 | SSA phi read(name) | parameters.rb:25:15:25:18 | name |
| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:1:1:16:3 | self |
| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:18:1:23:3 | self |
| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:90:1:103:3 | self |
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:3 | x |
| ssa.rb:94:3:95:10 | SSA phi read(self) | ssa.rb:90:1:103:3 | self |
| ssa.rb:94:3:95:10 | SSA phi read(x) | ssa.rb:91:3:91:3 | x |
phiReadNodeRead
| parameters.rb:26:3:26:11 | SSA phi read(name) | parameters.rb:25:15:25:18 | name | parameters.rb:26:8:26:11 | name |
| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:1:1:16:3 | self | ssa.rb:15:3:15:8 | self |
| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:18:1:23:3 | self | ssa.rb:20:5:20:10 | self |
| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:90:1:103:3 | self | ssa.rb:99:5:99:10 | self |
| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:90:1:103:3 | self | ssa.rb:101:5:101:10 | self |
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:3 | x | ssa.rb:99:10:99:10 | x |
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:3 | x | ssa.rb:101:10:101:10 | x |
phiReadInput
| parameters.rb:26:3:26:11 | SSA phi read(name) | parameters.rb:25:15:25:18 | name |
| ssa.rb:5:3:13:5 | SSA phi read(self) | ssa.rb:1:1:16:3 | self (m) |
| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:18:1:23:3 | self (m1) |
| ssa.rb:19:9:19:9 | SSA phi read(self) | ssa.rb:19:9:19:9 | SSA phi read(self) |
| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:90:1:103:3 | self (m12) |
| ssa.rb:92:3:96:5 | SSA phi read(self) | ssa.rb:94:3:95:10 | SSA phi read(self) |
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:91:3:91:7 | ... = ... |
| ssa.rb:92:3:96:5 | SSA phi read(x) | ssa.rb:94:3:95:10 | SSA phi read(x) |
| ssa.rb:94:3:95:10 | SSA phi read(self) | ssa.rb:90:1:103:3 | self (m12) |
| ssa.rb:94:3:95:10 | SSA phi read(x) | ssa.rb:91:3:91:7 | ... = ... |

View File

@@ -1,6 +1,8 @@
import codeql.ruby.AST
import codeql.ruby.CFG
import codeql.ruby.dataflow.SSA
import codeql.ruby.dataflow.internal.SsaImpl
import ExposedForTestingOnly
query predicate definition(Ssa::Definition def, Variable v) { def.getSourceVariable() = v }
@@ -24,3 +26,17 @@ query predicate adjacentReads(Ssa::Definition def, Variable v, CfgNode read1, Cf
query predicate phi(Ssa::PhiNode phi, Variable v, Ssa::Definition input) {
phi.getSourceVariable() = v and input = phi.getAnInput()
}
query predicate phiReadNode(PhiReadNode phi, Variable v) { phi.getSourceVariable() = v }
query predicate phiReadNodeRead(PhiReadNode phi, Variable v, CfgNode read) {
phi.getSourceVariable() = v and
exists(BasicBlock bb, int i |
ssaDefReachesReadExt(v, phi, bb, i) and
read = bb.getNode(i)
)
}
query predicate phiReadInput(PhiReadNode phi, DefinitionExt inp) {
phiHasInputFromBlockExt(phi, inp, _)
}

View File

@@ -85,4 +85,19 @@ def m11
puts captured
end
end
end
def m12(b1, b2, b3, b4)
x = 0
if (b1) then
puts x
elsif (b2) then
puts x
end
# phi read for x
if (b3) then
puts x
elsif (b4) then
puts x
end
end

View File

@@ -279,6 +279,23 @@ variableAccess
| ssa.rb:84:6:86:8 | self | ssa.rb:81:1:88:3 | self | ssa.rb:81:1:88:3 | m11 |
| ssa.rb:85:10:85:22 | self | ssa.rb:81:1:88:3 | self | ssa.rb:81:1:88:3 | m11 |
| ssa.rb:85:15:85:22 | captured | ssa.rb:82:3:82:10 | captured | ssa.rb:81:1:88:3 | m11 |
| ssa.rb:90:9:90:10 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:90:13:90:14 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:90:17:90:18 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:90:21:90:22 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:92:7:92:8 | b1 | ssa.rb:90:9:90:10 | b1 | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:93:5:93:10 | self | ssa.rb:90:1:103:3 | self | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:93:10:93:10 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:94:10:94:11 | b2 | ssa.rb:90:13:90:14 | b2 | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:95:5:95:10 | self | ssa.rb:90:1:103:3 | self | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:95:10:95:10 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:98:7:98:8 | b3 | ssa.rb:90:17:90:18 | b3 | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:99:5:99:10 | self | ssa.rb:90:1:103:3 | self | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:99:10:99:10 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:100:10:100:11 | b4 | ssa.rb:90:21:90:22 | b4 | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:101:5:101:10 | self | ssa.rb:90:1:103:3 | self | ssa.rb:90:1:103:3 | m12 |
| ssa.rb:101:10:101:10 | x | ssa.rb:91:3:91:3 | x | ssa.rb:90:1:103:3 | m12 |
explicitWrite
| class_variables.rb:1:1:1:3 | @@x | class_variables.rb:1:1:1:8 | ... = ... |
| class_variables.rb:19:3:19:5 | @@x | class_variables.rb:19:3:19:10 | ... = ... |
@@ -349,6 +366,7 @@ explicitWrite
| ssa.rb:69:5:69:12 | captured | ssa.rb:69:5:69:17 | ... = ... |
| ssa.rb:75:3:75:10 | captured | ssa.rb:75:3:75:14 | ... = ... |
| ssa.rb:82:3:82:10 | captured | ssa.rb:82:3:82:14 | ... = ... |
| ssa.rb:91:3:91:3 | x | ssa.rb:91:3:91:7 | ... = ... |
implicitWrite
| nested_scopes.rb:15:23:15:23 | a |
| nested_scopes.rb:16:26:16:26 | x |
@@ -390,6 +408,10 @@ implicitWrite
| ssa.rb:53:8:53:10 | foo |
| ssa.rb:64:8:64:8 | a |
| ssa.rb:66:15:66:15 | a |
| ssa.rb:90:9:90:10 | b1 |
| ssa.rb:90:13:90:14 | b2 |
| ssa.rb:90:17:90:18 | b3 |
| ssa.rb:90:21:90:22 | b4 |
readAccess
| class_variables.rb:3:1:3:5 | self |
| class_variables.rb:3:3:3:5 | @@x |
@@ -582,3 +604,15 @@ readAccess
| ssa.rb:84:6:86:8 | self |
| ssa.rb:85:10:85:22 | self |
| ssa.rb:85:15:85:22 | captured |
| ssa.rb:92:7:92:8 | b1 |
| ssa.rb:93:5:93:10 | self |
| ssa.rb:93:10:93:10 | x |
| ssa.rb:94:10:94:11 | b2 |
| ssa.rb:95:5:95:10 | self |
| ssa.rb:95:10:95:10 | x |
| ssa.rb:98:7:98:8 | b3 |
| ssa.rb:99:5:99:10 | self |
| ssa.rb:99:10:99:10 | x |
| ssa.rb:100:10:100:11 | b4 |
| ssa.rb:101:5:101:10 | self |
| ssa.rb:101:10:101:10 | x |

View File

@@ -120,7 +120,7 @@
| scopes.rb:43:2:43:4 | foo |
| scopes.rb:46:5:46:8 | var2 |
| ssa.rb:1:1:16:3 | self |
| ssa.rb:1:1:88:3 | self |
| ssa.rb:1:1:103:3 | self |
| ssa.rb:1:7:1:7 | b |
| ssa.rb:2:3:2:3 | i |
| ssa.rb:18:1:23:3 | self |
@@ -152,3 +152,9 @@
| ssa.rb:75:3:75:10 | captured |
| ssa.rb:81:1:88:3 | self |
| ssa.rb:82:3:82:10 | captured |
| ssa.rb:90:1:103:3 | self |
| ssa.rb:90:9:90:10 | b1 |
| ssa.rb:90:13:90:14 | b2 |
| ssa.rb:90:17:90:18 | b3 |
| ssa.rb:90:21:90:22 | b4 |
| ssa.rb:91:3:91:3 | x |

View File

@@ -57,7 +57,7 @@
| scopes.rb:37:1:39:3 | foo |
| scopes.rb:41:1:49:3 | M |
| ssa.rb:1:1:16:3 | m |
| ssa.rb:1:1:88:3 | ssa.rb |
| ssa.rb:1:1:103:3 | ssa.rb |
| ssa.rb:18:1:23:3 | m1 |
| ssa.rb:25:1:30:3 | m2 |
| ssa.rb:26:3:28:5 | { ... } |
@@ -75,3 +75,4 @@
| ssa.rb:81:1:88:3 | m11 |
| ssa.rb:83:7:87:5 | do ... end |
| ssa.rb:84:10:86:8 | do ... end |
| ssa.rb:90:1:103:3 | m12 |