Merge pull request #16875 from hvitved/csharp/ssa-param-def

C#: Move implicit entry definitions inside method bodies in SSA construction
This commit is contained in:
Tom Hvitved 2024-07-04 10:51:06 +02:00 коммит произвёл GitHub
Родитель 456c649c7d c5c97aca50
Коммит d675304703
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
31 изменённых файлов: 326 добавлений и 137 удалений

Просмотреть файл

@ -393,6 +393,8 @@ private import AssignableInternal
*/
class AssignableDefinition extends TAssignableDefinition {
/**
* DEPRECATED: Use `this.getExpr().getAControlFlowNode()` instead.
*
* Gets a control flow node that updates the targeted assignable when
* reached.
*
@ -400,7 +402,9 @@ class AssignableDefinition extends TAssignableDefinition {
* the definitions of `x` and `y` in `M(out x, out y)` and `(x, y) = (0, 1)`
* relate to the same call to `M` and assignment node, respectively.
*/
ControlFlow::Node getAControlFlowNode() { result = this.getExpr().getAControlFlowNode() }
deprecated ControlFlow::Node getAControlFlowNode() {
result = this.getExpr().getAControlFlowNode()
}
/**
* Gets the underlying expression that updates the targeted assignable when
@ -477,6 +481,11 @@ class AssignableDefinition extends TAssignableDefinition {
exists(Ssa::ExplicitDefinition def | result = def.getAFirstReadAtNode(cfn) |
this = def.getADefinition()
)
or
exists(Ssa::ImplicitParameterDefinition def | result = def.getAFirstReadAtNode(cfn) |
this.(AssignableDefinitions::ImplicitParameterDefinition).getParameter() =
def.getParameter()
)
)
}
@ -550,7 +559,7 @@ module AssignableDefinitions {
ControlFlow::BasicBlock bb, Parameter p, AssignableDefinition def
) {
def = any(RefArg arg).getAnAnalyzableRefDef(p) and
bb.getANode() = def.getAControlFlowNode()
bb.getANode() = def.getExpr().getAControlFlowNode()
}
/**
@ -662,7 +671,9 @@ module AssignableDefinitions {
/** Gets the underlying parameter. */
Parameter getParameter() { result = p }
override ControlFlow::Node getAControlFlowNode() { result = p.getCallable().getEntryPoint() }
deprecated override ControlFlow::Node getAControlFlowNode() {
result = p.getCallable().getEntryPoint()
}
override Parameter getElement() { result = p }

Просмотреть файл

@ -5,6 +5,7 @@
*/
import csharp
private import internal.Location
/**
* INTERNAL: Do not use.
@ -65,14 +66,6 @@ private ControlFlowElement getBody(Callable c) {
result = getStatementBody(c)
}
pragma[nomagic]
private SourceLocation getASourceLocation(Element e) {
result = e.getALocation().(SourceLocation) and
not exists(e.getALocation().(SourceLocation).getMappedLocation())
or
result = e.getALocation().(SourceLocation).getMappedLocation()
}
pragma[nomagic]
private predicate hasNoSourceLocation(Element e) { not exists(getASourceLocation(e)) }

Просмотреть файл

@ -50,6 +50,27 @@ class Location extends @location {
/** Gets the 1-based column number (inclusive) where this location ends. */
final int getEndColumn() { this.hasLocationInfo(_, _, _, _, result) }
/** Holds if this location starts strictly before the specified location. */
bindingset[this, other]
pragma[inline_late]
predicate strictlyBefore(Location other) {
this.getFile() = other.getFile() and
(
this.getStartLine() < other.getStartLine()
or
this.getStartLine() = other.getStartLine() and this.getStartColumn() < other.getStartColumn()
)
}
/** Holds if this location starts before the specified location. */
bindingset[this, other]
pragma[inline_late]
predicate before(Location other) {
this.getStartLine() < other.getStartLine()
or
this.getStartLine() = other.getStartLine() and this.getStartColumn() <= other.getStartColumn()
}
}
/** An empty location. */

Просмотреть файл

@ -157,9 +157,9 @@ private ControlFlowElement getANullCheck(
exists(Expr e, G::AbstractValue v | v.branch(result, s, e) | exprImpliesSsaDef(e, v, def, nv))
}
private predicate isMaybeNullArgument(Ssa::ExplicitDefinition def, MaybeNullExpr arg) {
private predicate isMaybeNullArgument(Ssa::ImplicitParameterDefinition def, MaybeNullExpr arg) {
exists(AssignableDefinitions::ImplicitParameterDefinition pdef, Parameter p |
pdef = def.getADefinition()
p = def.getParameter()
|
p = pdef.getParameter().getUnboundDeclaration() and
arg = p.getAnAssignedArgument() and
@ -208,9 +208,9 @@ private predicate hasMultipleParamsArguments(Call c) {
)
}
private predicate isNullDefaultArgument(Ssa::ExplicitDefinition def, AlwaysNullExpr arg) {
private predicate isNullDefaultArgument(Ssa::ImplicitParameterDefinition def, AlwaysNullExpr arg) {
exists(AssignableDefinitions::ImplicitParameterDefinition pdef, Parameter p |
pdef = def.getADefinition()
p = def.getParameter()
|
p = pdef.getParameter().getUnboundDeclaration() and
arg = p.getDefaultValue() and
@ -543,9 +543,10 @@ class Dereference extends G::DereferenceableExpr {
p.fromSource() // assume all non-source extension methods perform a dereference
implies
exists(
Ssa::ExplicitDefinition def, AssignableDefinitions::ImplicitParameterDefinition pdef
Ssa::ImplicitParameterDefinition def,
AssignableDefinitions::ImplicitParameterDefinition pdef
|
pdef = def.getADefinition()
p = def.getParameter()
|
p.getUnboundDeclaration() = pdef.getParameter() and
def.getARead() instanceof Dereference

Просмотреть файл

@ -9,6 +9,24 @@ import csharp
*/
module Ssa {
private import internal.SsaImpl as SsaImpl
private import semmle.code.csharp.internal.Location
pragma[nomagic]
private predicate assignableDefinitionLocalScopeVariable(
AssignableDefinition ad, LocalScopeVariable v, Callable c
) {
ad.getTarget() = v and
ad.getEnclosingCallable() = c
}
pragma[nomagic]
private predicate localScopeSourceVariable(
SourceVariables::LocalScopeSourceVariable sv, LocalScopeVariable v, Callable c1, Callable c2
) {
sv.getAssignable() = v and
sv.getEnclosingCallable() = c1 and
v.getCallable() = c2
}
/**
* A variable that can be SSA converted.
@ -34,11 +52,10 @@ module Ssa {
or
// Local variable declaration without initializer
not exists(result.getTargetAccess()) and
this =
any(SourceVariables::LocalScopeSourceVariable v |
result.getTarget() = v.getAssignable() and
result.getEnclosingCallable() = v.getEnclosingCallable()
)
exists(LocalScopeVariable v, Callable c |
assignableDefinitionLocalScopeVariable(result, v, c) and
localScopeSourceVariable(this, v, c, _)
)
}
/**
@ -507,9 +524,7 @@ module Ssa {
override Element getElement() { result = ad.getElement() }
override string toString() {
if this.getADefinition() instanceof AssignableDefinitions::ImplicitParameterDefinition
then result = SsaImpl::getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")"
else result = SsaImpl::getToStringPrefix(this) + "SSA def(" + this.getSourceVariable() + ")"
result = SsaImpl::getToStringPrefix(this) + "SSA def(" + this.getSourceVariable() + ")"
}
override Location getLocation() { result = ad.getLocation() }
@ -537,7 +552,7 @@ module Ssa {
/**
* An SSA definition representing the implicit initialization of a variable
* at the beginning of a callable. Either the variable is a local scope variable
* at the beginning of a callable. Either a parameter, a local scope variable
* captured by the callable, or a field or property accessed inside the callable.
*/
class ImplicitEntryDefinition extends ImplicitDefinition {
@ -551,7 +566,7 @@ module Ssa {
/** Gets the callable that this entry definition belongs to. */
final Callable getCallable() { result = this.getBasicBlock().getCallable() }
override Callable getElement() { result = this.getCallable() }
override Element getElement() { result = this.getCallable() }
override string toString() {
if this.getSourceVariable().getAssignable() instanceof LocalScopeVariable
@ -566,6 +581,54 @@ module Ssa {
override Location getLocation() { result = this.getCallable().getLocation() }
}
private module NearestLocationInput implements NearestLocationInputSig {
class C = ImplicitParameterDefinition;
predicate relevantLocations(ImplicitParameterDefinition def, Location l1, Location l2) {
not def.getBasicBlock() instanceof ControlFlow::BasicBlocks::EntryBlock and
l1 = def.getParameter().getALocation() and
l2 = def.getBasicBlock().getLocation()
}
}
pragma[nomagic]
private predicate implicitEntryDef(ImplicitEntryDefinition def, SourceVariable v, Callable c) {
v = def.getSourceVariable() and
c = def.getCallable()
}
/**
* An SSA definition representing the implicit initialization of a parameter
* at the beginning of a callable.
*/
class ImplicitParameterDefinition extends ImplicitEntryDefinition {
private Parameter p;
ImplicitParameterDefinition() {
exists(SourceVariable sv, Callable c |
implicitEntryDef(this, sv, c) and
localScopeSourceVariable(sv, p, _, c)
)
}
/** Gets the parameter that this entry definition represents. */
Parameter getParameter() { result = p }
override Element getElement() { result = this.getParameter() }
override string toString() {
result = SsaImpl::getToStringPrefix(this) + "SSA param(" + this.getParameter() + ")"
}
override Location getLocation() {
not NearestLocation<NearestLocationInput>::nearestLocation(this, _, _) and
result = p.getLocation()
or
// multi-bodied method: use matching parameter location
NearestLocation<NearestLocationInput>::nearestLocation(this, result, _)
}
}
/**
* An SSA definition representing the potential definition of a variable
* via a call.

Просмотреть файл

@ -14,7 +14,7 @@ module BaseSsa {
private predicate definitionAt(
AssignableDefinition def, ControlFlow::BasicBlock bb, int i, SsaInput::SourceVariable v
) {
bb.getNode(i) = def.getAControlFlowNode() and
bb.getNode(i) = def.getExpr().getAControlFlowNode() and
v = def.getTarget() and
// In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x`
not exists(TupleAssignmentDefinition first, TupleAssignmentDefinition second | first = def |
@ -27,8 +27,19 @@ module BaseSsa {
private predicate implicitEntryDef(
Callable c, ControlFlow::BasicBlocks::EntryBlock bb, SsaInput::SourceVariable v
) {
v.isReadonlyCapturedBy(c) and
c = bb.getCallable()
exists(ControlFlow::ControlFlow::BasicBlocks::EntryBlock entry |
c = entry.getCallable() and
// In case `c` has multiple bodies, we want each body to gets its own implicit
// entry definition. In case `c` doesn't have multiple bodies, the line below
// is simply the same as `bb = entry`, because `entry.getFirstNode().getASuccessor()`
// will be in the entry block.
bb = entry.getFirstNode().getASuccessor().getBasicBlock() and
c = v.getCallable()
|
v.isReadonlyCapturedBy(c)
or
v instanceof Parameter
)
}
private module SsaInput implements SsaImplCommon::InputSig<Location> {
@ -85,6 +96,13 @@ module BaseSsa {
)
}
final predicate isImplicitEntryDefinition(SsaInput::SourceVariable v) {
exists(ControlFlow::BasicBlock bb |
this.definesAt(v, bb, -1) and
implicitEntryDef(_, bb, v)
)
}
private Definition getAPhiInputOrPriorDefinition() {
result = this.(PhiNode).getAnInput() or
SsaImpl::uncertainWriteDefinitionInput(this, result)

Просмотреть файл

@ -199,7 +199,7 @@ abstract class ControlFlowReachabilityConfiguration extends string {
exists(ControlFlow::BasicBlock bb, boolean isSuccessor, int i, int j |
this.reachesBasicBlockDefinitionBase(e, def, isSuccessor, cfn, i, bb) and
cfnDef = bb.getNode(j) and
def.getAControlFlowNode() = cfnDef
def.getExpr().getAControlFlowNode() = cfnDef
|
isSuccessor = true and j >= i
or
@ -208,7 +208,7 @@ abstract class ControlFlowReachabilityConfiguration extends string {
or
exists(ControlFlow::BasicBlock bb |
this.reachesBasicBlockDefinitionRec(e, def, _, cfn, bb) and
def.getAControlFlowNode() = cfnDef and
def.getExpr().getAControlFlowNode() = cfnDef and
cfnDef = bb.getANode()
)
}

Просмотреть файл

@ -44,7 +44,8 @@ private ControlFlow::Node getAPrimaryConstructorParameterCfn(ParameterAccess pa)
(
result = pa.(ParameterRead).getAControlFlowNode()
or
pa = any(AssignableDefinition def | result = def.getAControlFlowNode()).getTargetAccess()
pa =
any(AssignableDefinition def | result = def.getExpr().getAControlFlowNode()).getTargetAccess()
)
}
@ -354,9 +355,7 @@ module VariableCapture {
VariableWrite() {
def.getTarget() = v.asLocalScopeVariable() and
this = def.getAControlFlowNode() and
// the shared variable capture library inserts implicit parameter definitions
not def instanceof AssignableDefinitions::ImplicitParameterDefinition
this = def.getExpr().getAControlFlowNode()
}
ControlFlow::Node getRhs() { LocalFlow::defAssigns(def, this, result) }
@ -1100,13 +1099,10 @@ private module Cached {
TExprNode(ControlFlow::Nodes::ElementNode cfn) { cfn.getAstNode() instanceof Expr } or
TSsaDefinitionExtNode(SsaImpl::DefinitionExt def) {
// Handled by `TExplicitParameterNode` below
not def.(Ssa::ExplicitDefinition).getADefinition() instanceof
AssignableDefinitions::ImplicitParameterDefinition
not def instanceof Ssa::ImplicitParameterDefinition
} or
TAssignableDefinitionNode(AssignableDefinition def, ControlFlow::Node cfn) {
cfn = def.getAControlFlowNode() and
// Handled by `TExplicitParameterNode` below
not def instanceof AssignableDefinitions::ImplicitParameterDefinition
cfn = def.getExpr().getAControlFlowNode()
} or
TExplicitParameterNode(Parameter p) {
p = any(DataFlowCallable dfc).asCallable().getAParameter()
@ -1353,10 +1349,7 @@ private module ParameterNodes {
ExplicitParameterNode() { this = TExplicitParameterNode(parameter) }
/** Gets the SSA definition corresponding to this parameter, if any. */
Ssa::ExplicitDefinition getSsaDefinition() {
result.getADefinition().(AssignableDefinitions::ImplicitParameterDefinition).getParameter() =
parameter
}
Ssa::ImplicitParameterDefinition getSsaDefinition() { result.getParameter() = parameter }
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
c.asCallable().getParameter(pos.getPosition()) = parameter

Просмотреть файл

@ -139,7 +139,7 @@ private module SourceVariableImpl {
ControlFlow::BasicBlock bb, int i, Ssa::SourceVariable v, AssignableDefinition ad
) {
ad = v.getADefinition() and
ad.getAControlFlowNode() = bb.getNode(i) and
ad.getExpr().getAControlFlowNode() = bb.getNode(i) and
// In cases like `(x, x) = (0, 1)`, we discard the first (dead) definition of `x`
not exists(TupleAssignmentDefinition first, TupleAssignmentDefinition second | first = ad |
second.getAssignment() = first.getAssignment() and
@ -233,7 +233,7 @@ private module SourceVariableImpl {
def.getTarget() = lv and
lv.isRef() and
lv = v.getAssignable() and
bb.getNode(i) = def.getAControlFlowNode() and
bb.getNode(i) = def.getExpr().getAControlFlowNode() and
not def.getAssignment() instanceof LocalVariableDeclAndInitExpr
)
}
@ -867,11 +867,14 @@ private module Cached {
}
cached
predicate implicitEntryDefinition(
ControlFlow::ControlFlow::BasicBlocks::EntryBlock bb, Ssa::SourceVariable v
) {
exists(Callable c |
c = bb.getCallable() and
predicate implicitEntryDefinition(ControlFlow::ControlFlow::BasicBlock bb, Ssa::SourceVariable v) {
exists(ControlFlow::ControlFlow::BasicBlocks::EntryBlock entry, Callable c |
c = entry.getCallable() and
// In case `c` has multiple bodies, we want each body to gets its own implicit
// entry definition. In case `c` doesn't have multiple bodies, the line below
// is simply the same as `bb = entry`, because `entry.getFirstNode().getASuccessor()`
// will be in the entry block.
bb = entry.getFirstNode().getASuccessor().getBasicBlock() and
c = v.getEnclosingCallable()
|
// Captured variable
@ -883,6 +886,8 @@ private module Cached {
or
// Each tracked field and property has an implicit entry definition
v instanceof PlainFieldOrPropSourceVariable
or
v.getAssignable() instanceof Parameter
)
}

Просмотреть файл

@ -199,7 +199,7 @@ abstract class ControlFlowReachabilityConfiguration extends string {
exists(ControlFlow::BasicBlock bb, boolean isSuccessor, int i, int j |
this.reachesBasicBlockDefinitionBase(e, def, isSuccessor, cfn, i, bb) and
cfnDef = bb.getNode(j) and
def.getAControlFlowNode() = cfnDef
def.getExpr().getAControlFlowNode() = cfnDef
|
isSuccessor = true and j >= i
or
@ -208,7 +208,7 @@ abstract class ControlFlowReachabilityConfiguration extends string {
or
exists(ControlFlow::BasicBlock bb |
this.reachesBasicBlockDefinitionRec(e, def, _, cfn, bb) and
def.getAControlFlowNode() = cfnDef and
def.getExpr().getAControlFlowNode() = cfnDef and
cfnDef = bb.getANode()
)
}

Просмотреть файл

@ -314,12 +314,8 @@ private module Internal {
1 < strictcount(this.getADynamicTarget().getUnboundDeclaration()) and
c = this.getCall().getEnclosingCallable().getUnboundDeclaration() and
(
exists(
BaseSsa::Definition def, AssignableDefinitions::ImplicitParameterDefinition pdef,
Parameter p
|
pdef = def.getDefinition() and
p = pdef.getTarget() and
exists(BaseSsa::Definition def, Parameter p |
def.isImplicitEntryDefinition(p) and
this.getSyntheticQualifier() = def.getARead() and
p.getPosition() = i and
c.getAParameter() = p and

Просмотреть файл

@ -0,0 +1,72 @@
private import csharp
private SourceLocation fromMappedLocation(SourceLocation loc) { result.getMappedLocation() = loc }
pragma[nomagic]
private Location unmap(Location l, File f) {
(
result = fromMappedLocation(l)
or
not exists(fromMappedLocation(l)) and
result = l
) and
f = result.getFile()
}
bindingset[l1, l2]
pragma[inline_late]
private predicate inSameFile0(Location l1, Location l2) { l1.getFile() = l2.getFile() }
/** Holds if `l1` and `l2` are in the same file. */
bindingset[l1, l2]
pragma[inline_late]
predicate inSameFile(Location l1, Location l2) { inSameFile0(unmap(l1, _), unmap(l2, _)) }
/** Gets a source location for `e`, if any. */
pragma[nomagic]
SourceLocation getASourceLocation(Element e) {
result = e.getALocation() and
not exists(result.getMappedLocation())
or
result = e.getALocation().(SourceLocation).getMappedLocation()
}
/** Provides the input to `NearestLocation`. */
signature module NearestLocationInputSig {
class C {
string toString();
Location getLocation();
}
predicate relevantLocations(C c, Location l1, Location l2);
}
module NearestLocation<NearestLocationInputSig Input> {
pragma[nomagic]
private predicate relevantLocationsUnmapped(
Input::C c, Location l1, Location l2, Location l1unmapped
) {
exists(Location l2unmapped, File f |
Input::relevantLocations(c, pragma[only_bind_into](l1), pragma[only_bind_into](l2)) and
l1unmapped = unmap(l1, f) and
l2unmapped = unmap(l2, f) and
l1unmapped.before(l2unmapped)
)
}
/**
* Holds if `l1` is the location nearest to (and before) `l2` amongst
* all locations `l` such that `Input::relevantLocations(c, l, l2)` holds.
*/
pragma[nomagic]
predicate nearestLocation(Input::C c, Location l1, Location l2) {
l1 =
max(Location loc, Location l1unmapped, int startline1, int startcolumn1 |
relevantLocationsUnmapped(c, loc, l2, l1unmapped) and
l1unmapped.hasLocationInfo(_, startline1, startcolumn1, _, _)
|
loc order by startline1, startcolumn1
)
}
}

Просмотреть файл

@ -16,7 +16,7 @@
import csharp
predicate lockedFieldUpdate(LockStmt lock, Field f, AssignableDefinition def) {
lock.getAChild+() = def.getAControlFlowNode().getAstNode() and
lock.getAChild+() = def.getExpr() and
def.getTarget() = f
}

Просмотреть файл

@ -127,7 +127,7 @@ class RelevantDefinition extends AssignableDefinition {
/** Holds if this definition is dead and we want to report it. */
predicate isDead() {
// Ensure that the definition is not in dead code
exists(this.getAControlFlowNode()) and
exists(this.getExpr().getAControlFlowNode()) and
not this.isMaybeLive() and
// Allow dead initializer assignments, such as `string s = string.Empty`, but only
// if the initializer expression assigns a default-like value, and there exists another

Просмотреть файл

@ -1,9 +1,5 @@
| Assignables.cs:5:9:5:17 | ... = ... | Assignables.cs:5:9:5:17 | ... = ... |
| Assignables.cs:6:32:6:34 | ... = ... | Assignables.cs:6:32:6:34 | ... = ... |
| Assignables.cs:9:18:9:18 | i | Assignables.cs:9:23:9:25 | enter get_Item |
| Assignables.cs:9:18:9:18 | i | Assignables.cs:9:41:9:43 | enter set_Item |
| Assignables.cs:9:41:9:43 | value | Assignables.cs:9:41:9:43 | enter set_Item |
| Assignables.cs:11:16:11:24 | parameter | Assignables.cs:11:10:11:10 | enter M |
| Assignables.cs:13:13:13:24 | Int32 variable = ... | Assignables.cs:13:13:13:24 | Int32 variable = ... |
| Assignables.cs:14:9:14:28 | ... = ... | Assignables.cs:14:9:14:28 | ... = ... |
| Assignables.cs:15:9:15:18 | ...-- | Assignables.cs:15:9:15:18 | ...-- |
@ -14,8 +10,6 @@
| Assignables.cs:20:9:20:33 | ... = ... | Assignables.cs:20:9:20:33 | ... = ... |
| Assignables.cs:21:9:21:18 | ...++ | Assignables.cs:21:9:21:18 | ...++ |
| Assignables.cs:22:22:22:50 | EventHandler callback = ... | Assignables.cs:22:22:22:50 | EventHandler callback = ... |
| Assignables.cs:22:34:22:39 | sender | Assignables.cs:22:33:22:50 | enter (...) => ... |
| Assignables.cs:22:42:22:42 | e | Assignables.cs:22:33:22:50 | enter (...) => ... |
| Assignables.cs:23:9:23:25 | ... += ... | Assignables.cs:23:9:23:25 | ... += ... |
| Assignables.cs:25:9:25:25 | ... -= ... | Assignables.cs:25:9:25:25 | ... -= ... |
| Assignables.cs:26:9:26:33 | ... = ... | Assignables.cs:26:9:26:33 | ... = ... |
@ -27,27 +21,14 @@
| Assignables.cs:32:37:32:41 | access to field Field | Assignables.cs:32:9:32:42 | call to method RefUncertain2 |
| Assignables.cs:34:29:34:33 | access to field Field | Assignables.cs:34:9:34:45 | call to method RefCertainOneOf |
| Assignables.cs:34:40:34:44 | access to field Field | Assignables.cs:34:9:34:45 | call to method RefCertainOneOf |
| Assignables.cs:37:22:37:22 | o | Assignables.cs:37:10:37:12 | enter Out |
| Assignables.cs:39:9:39:13 | ... = ... | Assignables.cs:39:9:39:13 | ... = ... |
| Assignables.cs:42:26:42:26 | x | Assignables.cs:42:10:42:22 | enter RefCertain`1 |
| Assignables.cs:42:35:42:35 | y | Assignables.cs:42:10:42:22 | enter RefCertain`1 |
| Assignables.cs:42:43:42:43 | b | Assignables.cs:42:10:42:22 | enter RefCertain`1 |
| Assignables.cs:45:13:45:17 | ... = ... | Assignables.cs:45:13:45:17 | ... = ... |
| Assignables.cs:47:31:47:31 | access to parameter y | Assignables.cs:47:13:47:38 | call to method RefCertain`1 |
| Assignables.cs:50:27:50:27 | x | Assignables.cs:50:10:50:21 | enter RefUncertain |
| Assignables.cs:50:38:50:38 | y | Assignables.cs:50:10:50:21 | enter RefUncertain |
| Assignables.cs:53:13:53:17 | ... = ... | Assignables.cs:53:13:53:17 | ... = ... |
| Assignables.cs:56:28:56:28 | x | Assignables.cs:56:10:56:22 | enter RefUncertain2 |
| Assignables.cs:56:39:56:39 | y | Assignables.cs:56:10:56:22 | enter RefUncertain2 |
| Assignables.cs:59:13:59:17 | ... = ... | Assignables.cs:59:13:59:17 | ... = ... |
| Assignables.cs:61:33:61:33 | access to parameter y | Assignables.cs:61:13:61:34 | call to method RefUncertain |
| Assignables.cs:64:34:64:34 | x | Assignables.cs:64:10:64:24 | enter RefCertainOneOf |
| Assignables.cs:64:45:64:45 | y | Assignables.cs:64:10:64:24 | enter RefCertainOneOf |
| Assignables.cs:67:13:67:17 | ... = ... | Assignables.cs:67:13:67:17 | ... = ... |
| Assignables.cs:69:13:69:17 | ... = ... | Assignables.cs:69:13:69:17 | ... = ... |
| Assignables.cs:72:21:72:21 | x | Assignables.cs:72:10:72:15 | enter NonRef |
| Assignables.cs:72:32:72:32 | y | Assignables.cs:72:10:72:15 | enter NonRef |
| Assignables.cs:76:69:76:70 | ss | Assignables.cs:76:10:76:20 | enter LocalNoInit |
| Assignables.cs:78:22:78:22 | String s | Assignables.cs:78:22:78:22 | String s |
| Assignables.cs:82:21:82:33 | String temp = ... | Assignables.cs:82:21:82:33 | String temp = ... |
| Assignables.cs:84:30:84:30 | Exception e | Assignables.cs:84:30:84:30 | [exception: OutOfMemoryException] Exception e |
@ -73,8 +54,6 @@
| Assignables.cs:109:14:109:19 | Int32* p = ... | Assignables.cs:109:14:109:19 | Int32* p = ... |
| Assignables.cs:109:18:109:19 | &... | Assignables.cs:109:18:109:19 | &... |
| Assignables.cs:110:9:110:14 | ... = ... | Assignables.cs:110:9:110:14 | ... = ... |
| Assignables.cs:113:25:113:25 | i | Assignables.cs:113:5:113:15 | enter Assignables |
| Assignables.cs:113:39:113:39 | s | Assignables.cs:113:5:113:15 | enter Assignables |
| Assignables.cs:113:44:113:48 | ... = ... | Assignables.cs:113:44:113:48 | ... = ... |
| Assignables.cs:113:51:113:56 | ... = ... | Assignables.cs:113:51:113:56 | ... = ... |
| Assignables.cs:117:13:117:13 | Int32 i | Assignables.cs:117:13:117:13 | Int32 i |
@ -84,12 +63,10 @@
| Assignables.cs:124:13:124:13 | Int32 i | Assignables.cs:124:13:124:13 | Int32 i |
| Assignables.cs:125:13:125:25 | String s = ... | Assignables.cs:125:13:125:25 | String s = ... |
| Assignables.cs:126:9:126:30 | ... = ... | Assignables.cs:126:9:126:30 | ... = ... |
| Assignables.cs:130:31:130:31 | d | Assignables.cs:130:10:130:20 | enter DelegateRef |
| Assignables.cs:132:13:132:17 | Int32 x = ... | Assignables.cs:132:13:132:17 | Int32 x = ... |
| Assignables.cs:133:15:133:15 | access to local variable x | Assignables.cs:133:9:133:30 | delegate call |
| Assignables.cs:133:29:133:29 | String s | Assignables.cs:133:9:133:30 | delegate call |
| Assignables.cs:138:19:138:50 | MemoryStream x = ... | Assignables.cs:138:19:138:50 | MemoryStream x = ... |
| Discards.cs:5:30:5:30 | x | Discards.cs:5:19:5:19 | enter f |
| Discards.cs:7:9:7:17 | ... = ... | Discards.cs:7:9:7:17 | ... = ... |
| Discards.cs:13:9:13:20 | ... = ... | Discards.cs:13:9:13:20 | ... = ... |
| Discards.cs:18:9:18:25 | ... = ... | Discards.cs:18:9:18:25 | ... = ... |
@ -101,10 +78,7 @@
| Discards.cs:20:9:20:33 | ... = ... | Discards.cs:20:9:20:33 | ... = ... |
| Discards.cs:20:17:20:17 | Double y | Discards.cs:20:17:20:17 | Double y |
| Discards.cs:20:32:20:32 | Boolean z | Discards.cs:20:22:20:33 | call to method f |
| Discards.cs:23:27:23:30 | args | Discards.cs:23:10:23:16 | enter Foreach |
| Discards.cs:25:22:25:22 | String _ | Discards.cs:25:22:25:22 | String _ |
| Discards.cs:30:24:30:24 | o | Discards.cs:30:10:30:15 | enter Switch |
| Finally.cs:5:16:5:16 | b | Finally.cs:5:9:5:9 | enter M |
| Finally.cs:7:13:7:17 | Int32 i = ... | Finally.cs:7:13:7:17 | Int32 i = ... |
| Finally.cs:15:13:15:17 | ... = ... | Finally.cs:15:13:15:17 | ... = ... |
| Finally.cs:15:13:15:17 | ... = ... | Finally.cs:15:13:15:17 | [finally: exception(Exception)] ... = ... |

Просмотреть файл

@ -1,4 +1,4 @@
import csharp
from AssignableDefinition def
select def, def.getAControlFlowNode()
select def, def.getExpr().getAControlFlowNode()

Просмотреть файл

@ -1,7 +1,13 @@
import csharp
from AssignableDefinition def, AssignableRead read, Ssa::Definition ssaDef
from AssignableDefinition def, AssignableRead read, Ssa::Definition ult, Ssa::Definition ssaDef
where
ssaDef.getAnUltimateDefinition().(Ssa::ExplicitDefinition).getADefinition() = def and
ssaDef.getAnUltimateDefinition() = ult and
(
ult.(Ssa::ExplicitDefinition).getADefinition() = def
or
ult.(Ssa::ImplicitParameterDefinition).getParameter() =
def.(AssignableDefinitions::ImplicitParameterDefinition).getParameter()
) and
read = ssaDef.getARead()
select def, read

Просмотреть файл

@ -5,11 +5,13 @@ private import semmle.code.csharp.controlflow.internal.PreSsa
predicate defReaches(
AssignableDefinition def, PreSsa::SimpleLocalScopeVariable v, ControlFlow::Node cfn
) {
def.getTarget() = v and cfn = def.getAControlFlowNode().getASuccessor()
def.getTarget() = v and cfn = def.getExpr().getAControlFlowNode().getASuccessor()
or
exists(ControlFlow::Node mid | defReaches(def, v, mid) |
not mid =
any(AssignableDefinition ad | ad.getTarget() = v and ad.isCertain()).getAControlFlowNode() and
any(AssignableDefinition ad | ad.getTarget() = v and ad.isCertain())
.getExpr()
.getAControlFlowNode() and
cfn = mid.getASuccessor()
)
}

Просмотреть файл

@ -8,7 +8,9 @@ predicate parameterReaches(Parameter p, ControlFlow::Node cfn) {
or
exists(ControlFlow::Node mid | parameterReaches(p, mid) |
not mid =
any(AssignableDefinition ad | ad.getTarget() = p and ad.isCertain()).getAControlFlowNode() and
any(AssignableDefinition ad | ad.getTarget() = p and ad.isCertain())
.getExpr()
.getAControlFlowNode() and
cfn = mid.getASuccessor()
)
}
@ -22,7 +24,8 @@ private LocalScopeVariableRead getAReachableUncertainRead(
AssignableDefinitions::ImplicitParameterDefinition p
) {
exists(Ssa::Definition ssaDef |
p = ssaDef.getAnUltimateDefinition().(Ssa::ExplicitDefinition).getADefinition()
p.getParameter() =
ssaDef.getAnUltimateDefinition().(Ssa::ImplicitParameterDefinition).getParameter()
|
result = ssaDef.getARead()
)

Просмотреть файл

@ -9,7 +9,9 @@ predicate useReaches(
or
exists(ControlFlow::Node mid | useReaches(read, v, mid) |
not mid =
any(AssignableDefinition ad | ad.getTarget() = v and ad.isCertain()).getAControlFlowNode() and
any(AssignableDefinition ad | ad.getTarget() = v and ad.isCertain())
.getExpr()
.getAControlFlowNode() and
cfn = mid.getASuccessor()
)
}

Просмотреть файл

@ -82,6 +82,8 @@
| Fields.cs:93:19:93:23 | Field | Fields.cs:102:9:102:28 | ... = ... | Fields.cs:104:16:104:25 | access to field Field |
| Fields.cs:95:19:95:19 | f | Fields.cs:95:19:95:19 | f | Fields.cs:97:9:97:9 | access to parameter f |
| Fields.cs:107:33:107:33 | f | Fields.cs:107:33:107:33 | f | Fields.cs:107:38:107:38 | access to parameter f |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:28:5:28 | access to parameter x |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:28:3:28 | access to parameter x |
| OutRef.cs:5:9:5:13 | Field | OutRef.cs:13:28:13:32 | access to field Field | OutRef.cs:15:13:15:17 | access to field Field |
| OutRef.cs:5:9:5:13 | Field | OutRef.cs:16:21:16:25 | access to field Field | OutRef.cs:17:13:17:17 | access to field Field |
| OutRef.cs:5:9:5:13 | Field | OutRef.cs:16:32:16:36 | access to field Field | OutRef.cs:17:13:17:17 | access to field Field |

Просмотреть файл

@ -0,0 +1,6 @@
// semmle-extractor-options: --separate-compilation
class MultiImpl
{
public int M(int x) => x; // x should have one SSA definition per implementation
}

Просмотреть файл

@ -0,0 +1,4 @@
class MultiImpl
{
public int M(int x) => x; // x should have one SSA definition per implementation
}

Просмотреть файл

@ -159,6 +159,8 @@
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) |

Просмотреть файл

@ -146,6 +146,8 @@
| Fields.cs:114:9:114:22 | SSA call def(this.Field) | Fields.cs:114:9:114:22 | call to method SetField |
| Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:114:9:114:22 | call to method SetField |
| Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:114:9:114:22 | call to method SetField |
| MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | x |
| MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | x |
| OutRef.cs:7:10:7:10 | SSA entry def(this.Field) | OutRef.cs:7:10:7:10 | M |
| OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:9:13:9:17 | Int32 j = ... |
| OutRef.cs:10:25:10:25 | SSA def(i) | OutRef.cs:10:9:10:33 | call to method OutRefM |

Просмотреть файл

@ -136,6 +136,8 @@
| Fields.cs:115:20:115:29 | this.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field) | Fields.cs:117:17:117:26 | access to field Field |
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:117:17:117:32 | access to field Field |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:117:17:117:35 | access to field xs |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:28:5:28 | access to parameter x |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationB.cs:3:28:3:28 | access to parameter x |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:10:32:10:32 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:22:29:22:29 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) | OutRef.cs:24:29:24:29 | access to local variable j |

Просмотреть файл

@ -3,18 +3,10 @@
| Capture.cs:19:20:19:20 | b | Capture.cs:19:20:23:13 | SSA def(b) | Capture.cs:19:20:23:13 | Action b = ... |
| Capture.cs:30:16:30:16 | c | Capture.cs:30:16:30:35 | SSA def(c) | Capture.cs:30:16:30:35 | Action c = ... |
| Capture.cs:52:16:52:16 | b | Capture.cs:52:16:52:43 | SSA def(b) | Capture.cs:52:16:52:43 | Action b = ... |
| Capture.cs:57:57:57:63 | strings | Capture.cs:57:57:57:63 | SSA param(strings) | Capture.cs:57:57:57:63 | strings |
| Capture.cs:60:27:60:27 | e | Capture.cs:60:27:60:38 | SSA def(e) | Capture.cs:60:27:60:38 | Func<String,Int32> e = ... |
| Capture.cs:65:45:65:51 | strings | Capture.cs:65:45:65:51 | SSA param(strings) | Capture.cs:65:45:65:51 | strings |
| Capture.cs:68:32:68:32 | s | Capture.cs:68:32:68:32 | SSA param(s) | Capture.cs:68:32:68:32 | s |
| Capture.cs:69:25:69:25 | s | Capture.cs:69:25:69:25 | SSA param(s) | Capture.cs:69:25:69:25 | s |
| Capture.cs:73:67:73:73 | strings | Capture.cs:73:67:73:73 | SSA param(strings) | Capture.cs:73:67:73:73 | strings |
| Capture.cs:76:63:76:63 | e | Capture.cs:76:63:76:81 | SSA def(e) | Capture.cs:76:63:76:81 | Expression<Func<String,Int32>> e = ... |
| Capture.cs:81:28:81:28 | i | Capture.cs:81:28:81:28 | SSA param(i) | Capture.cs:81:28:81:28 | i |
| Capture.cs:81:28:81:28 | i | Capture.cs:81:34:81:36 | SSA def(i) | Capture.cs:81:34:81:36 | ...++ |
| Capture.cs:83:65:83:71 | strings | Capture.cs:83:65:83:71 | SSA param(strings) | Capture.cs:83:65:83:71 | strings |
| Capture.cs:86:64:86:64 | e | Capture.cs:86:64:86:73 | SSA def(e) | Capture.cs:86:64:86:73 | Expression<Func<String,Boolean>> e = ... |
| Capture.cs:92:18:92:18 | d | Capture.cs:92:18:92:18 | SSA param(d) | Capture.cs:92:18:92:18 | d |
| Capture.cs:98:17:98:17 | x | Capture.cs:98:17:98:21 | SSA def(x) | Capture.cs:98:17:98:21 | Int32 x = ... |
| Capture.cs:117:17:117:17 | x | Capture.cs:117:17:117:21 | SSA def(x) | Capture.cs:117:17:117:21 | Int32 x = ... |
| Capture.cs:198:28:198:29 | eh | Capture.cs:198:28:198:44 | SSA def(eh) | Capture.cs:198:28:198:44 | MyEventHandler eh = ... |
@ -22,19 +14,14 @@
| Capture.cs:210:24:210:24 | p | Capture.cs:210:24:210:59 | SSA def(p) | Capture.cs:210:24:210:59 | Process p = ... |
| Capture.cs:212:30:212:35 | exited | Capture.cs:212:30:212:71 | SSA def(exited) | Capture.cs:212:30:212:71 | EventHandler exited = ... |
| Capture.cs:248:36:248:36 | j | Capture.cs:251:13:251:17 | SSA def(j) | Capture.cs:251:13:251:17 | ... = ... |
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:7:25:7:25 | b |
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:15:17:15:21 | Int32 i = ... |
| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | [finally: exception(Exception)] SSA def(i) | Consistency.cs:15:17:15:21 | Int32 i = ... |
| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:25:29:25:29 | Consistency c |
| Consistency.cs:30:30:30:30 | c | Consistency.cs:32:9:32:29 | SSA def(c) | Consistency.cs:32:9:32:29 | ... = ... |
| Consistency.cs:44:11:44:11 | s | Consistency.cs:44:11:44:11 | SSA def(s) | Consistency.cs:44:11:44:11 | S s |
| Consistency.cs:49:30:49:30 | a | Consistency.cs:49:30:49:30 | SSA param(a) | Consistency.cs:49:30:49:30 | a |
| Consistency.cs:49:37:49:37 | i | Consistency.cs:49:37:49:37 | SSA param(i) | Consistency.cs:49:37:49:37 | i |
| Consistency.cs:51:20:51:20 | a | Consistency.cs:51:20:51:20 | SSA param(a) | Consistency.cs:51:20:51:20 | a |
| Consistency.cs:56:17:56:17 | k | Consistency.cs:56:17:56:40 | SSA def(k) | Consistency.cs:56:17:56:40 | Int32 k = ... |
| Consistency.cs:56:17:56:17 | k | Consistency.cs:57:9:57:13 | SSA def(k) | Consistency.cs:57:9:57:13 | ... = ... |
| Consistency.cs:56:17:56:17 | k | Consistency.cs:58:9:58:13 | SSA def(k) | Consistency.cs:58:9:58:13 | ... = ... |
| DefUse.cs:3:26:3:26 | w | DefUse.cs:3:26:3:26 | SSA param(w) | DefUse.cs:3:26:3:26 | w |
| DefUse.cs:3:26:3:26 | w | DefUse.cs:19:13:19:18 | SSA def(w) | DefUse.cs:19:13:19:18 | ... = ... |
| DefUse.cs:3:26:3:26 | w | DefUse.cs:29:13:29:18 | SSA def(w) | DefUse.cs:29:13:29:18 | ... = ... |
| DefUse.cs:5:13:5:13 | x | DefUse.cs:5:13:5:17 | SSA def(x) | DefUse.cs:5:13:5:17 | Int32 x = ... |
@ -64,24 +51,17 @@
| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:104:9:104:15 | SSA def(x5) | DefUse.cs:104:9:104:15 | ... = ... |
| DefUse.cs:114:42:114:42 | i | DefUse.cs:114:47:114:52 | SSA def(i) | DefUse.cs:114:47:114:52 | ... = ... |
| DefUse.cs:116:42:116:42 | i | DefUse.cs:116:47:116:51 | SSA def(i) | DefUse.cs:116:47:116:51 | ... = ... |
| DefUse.cs:118:45:118:45 | i | DefUse.cs:118:45:118:45 | SSA param(i) | DefUse.cs:118:45:118:45 | i |
| DefUse.cs:118:45:118:45 | i | DefUse.cs:118:68:118:72 | SSA def(i) | DefUse.cs:118:68:118:72 | ... = ... |
| DefUse.cs:118:56:118:56 | j | DefUse.cs:118:61:118:65 | SSA def(j) | DefUse.cs:118:61:118:65 | ... = ... |
| DefUse.cs:128:19:128:19 | i | DefUse.cs:128:19:128:19 | SSA param(i) | DefUse.cs:128:19:128:19 | i |
| DefUse.cs:134:22:134:22 | d | DefUse.cs:134:22:134:22 | SSA param(d) | DefUse.cs:134:22:134:22 | d |
| DefUse.cs:142:68:142:69 | ie | DefUse.cs:142:68:142:69 | SSA param(ie) | DefUse.cs:142:68:142:69 | ie |
| DefUse.cs:144:22:144:22 | x | DefUse.cs:144:22:144:22 | SSA def(x) | DefUse.cs:144:22:144:22 | String x |
| DefUse.cs:155:9:155:14 | this.Field4 | DefUse.cs:155:9:155:18 | SSA def(this.Field4) | DefUse.cs:155:9:155:18 | ... = ... |
| DefUse.cs:171:23:171:23 | a | DefUse.cs:171:23:180:9 | SSA def(a) | DefUse.cs:171:23:180:9 | Action a = ... |
| DefUse.cs:171:23:171:23 | a | DefUse.cs:186:9:190:9 | SSA def(a) | DefUse.cs:186:9:190:9 | ... = ... |
| DefUse.cs:184:9:184:14 | this.Field5 | DefUse.cs:184:9:184:18 | SSA def(this.Field5) | DefUse.cs:184:9:184:18 | ... = ... |
| DefUse.cs:188:13:188:18 | this.Field5 | DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:188:13:188:22 | ... = ... |
| Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:6:23:6:23 | i |
| Example.cs:8:9:8:18 | this.Field | Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:8:9:8:22 | ... = ... |
| Example.cs:8:9:8:18 | this.Field | Example.cs:11:13:11:30 | SSA def(this.Field) | Example.cs:11:13:11:30 | ... = ... |
| Example.cs:18:16:18:16 | p | Example.cs:18:16:18:16 | SSA param(p) | Example.cs:18:16:18:16 | p |
| Example.cs:18:16:18:16 | p | Example.cs:23:13:23:17 | SSA def(p) | Example.cs:23:13:23:17 | ... = ... |
| Example.cs:18:24:18:24 | b | Example.cs:18:24:18:24 | SSA param(b) | Example.cs:18:24:18:24 | b |
| Fields.cs:18:15:18:15 | x | Fields.cs:20:9:20:14 | SSA def(x) | Fields.cs:20:9:20:14 | ... = ... |
| Fields.cs:18:19:18:20 | this.xs | Fields.cs:24:9:24:23 | SSA def(this.xs) | Fields.cs:24:9:24:23 | ... = ... |
| Fields.cs:30:13:30:13 | f | Fields.cs:30:13:30:28 | SSA def(f) | Fields.cs:30:13:30:28 | Fields f = ... |
@ -97,10 +77,8 @@
| Fields.cs:80:9:80:12 | f.xs | Fields.cs:88:9:88:25 | SSA def(f.xs) | Fields.cs:88:9:88:25 | ... = ... |
| Fields.cs:82:9:82:15 | this.xs | Fields.cs:85:9:85:22 | SSA def(this.xs) | Fields.cs:85:9:85:22 | ... = ... |
| Fields.cs:82:9:82:15 | this.xs | Fields.cs:87:9:87:22 | SSA def(this.xs) | Fields.cs:87:9:87:22 | ... = ... |
| Fields.cs:95:19:95:19 | f | Fields.cs:95:19:95:19 | SSA param(f) | Fields.cs:95:19:95:19 | f |
| Fields.cs:97:9:97:15 | f.Field | Fields.cs:97:9:97:30 | SSA def(f.Field) | Fields.cs:97:9:97:30 | ... = ... |
| Fields.cs:102:9:102:18 | this.Field | Fields.cs:102:9:102:28 | SSA def(this.Field) | Fields.cs:102:9:102:28 | ... = ... |
| Fields.cs:107:33:107:33 | f | Fields.cs:107:33:107:33 | SSA param(f) | Fields.cs:107:33:107:33 | f |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:9:13:9:17 | Int32 j = ... |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:10:32:10:32 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) | OutRef.cs:22:22:22:22 | access to local variable j |
@ -114,12 +92,8 @@
| OutRef.cs:18:13:18:13 | t | OutRef.cs:18:13:18:28 | SSA def(t) | OutRef.cs:18:13:18:28 | OutRef t = ... |
| OutRef.cs:19:32:19:38 | t.Field | OutRef.cs:19:32:19:38 | SSA def(t.Field) | OutRef.cs:19:32:19:38 | access to field Field |
| OutRef.cs:28:26:28:26 | i | OutRef.cs:30:9:30:13 | SSA def(i) | OutRef.cs:30:9:30:13 | ... = ... |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:28:37:28:37 | SSA param(j) | OutRef.cs:28:37:28:37 | j |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:31:9:31:13 | SSA def(j) | OutRef.cs:31:9:31:13 | ... = ... |
| OutRef.cs:34:27:34:27 | i | OutRef.cs:36:9:36:13 | SSA def(i) | OutRef.cs:36:9:36:13 | ... = ... |
| OutRef.cs:34:38:34:38 | j | OutRef.cs:34:38:34:38 | SSA param(j) | OutRef.cs:34:38:34:38 | j |
| OutRef.cs:39:24:39:24 | b | OutRef.cs:39:24:39:24 | SSA param(b) | OutRef.cs:39:24:39:24 | b |
| OutRef.cs:39:35:39:35 | j | OutRef.cs:39:35:39:35 | SSA param(j) | OutRef.cs:39:35:39:35 | j |
| OutRef.cs:39:35:39:35 | j | OutRef.cs:42:13:42:17 | SSA def(j) | OutRef.cs:42:13:42:17 | ... = ... |
| Patterns.cs:7:16:7:16 | o | Patterns.cs:7:16:7:23 | SSA def(o) | Patterns.cs:7:16:7:23 | Object o = ... |
| Patterns.cs:8:22:8:23 | i1 | Patterns.cs:8:18:8:23 | SSA def(i1) | Patterns.cs:8:18:8:23 | Int32 i1 |
@ -134,7 +108,6 @@
| Properties.cs:31:19:31:22 | f.xs | Properties.cs:45:9:45:25 | SSA def(f.xs) | Properties.cs:45:9:45:25 | ... = ... |
| Properties.cs:32:15:32:15 | z | Properties.cs:47:9:47:14 | SSA def(z) | Properties.cs:47:9:47:14 | ... = ... |
| Properties.cs:32:19:32:20 | this.xs | Properties.cs:42:9:42:23 | SSA def(this.xs) | Properties.cs:42:9:42:23 | ... = ... |
| Properties.cs:61:23:61:23 | i | Properties.cs:61:23:61:23 | SSA param(i) | Properties.cs:61:23:61:23 | i |
| Properties.cs:61:23:61:23 | i | Properties.cs:63:16:63:18 | SSA def(i) | Properties.cs:63:16:63:18 | ...-- |
| Properties.cs:73:13:73:13 | f | Properties.cs:73:13:73:32 | SSA def(f) | Properties.cs:73:13:73:32 | Properties f = ... |
| Properties.cs:74:23:74:23 | a | Properties.cs:74:23:74:54 | SSA def(a) | Properties.cs:74:23:74:54 | Action a = ... |
@ -144,21 +117,15 @@
| Properties.cs:76:9:76:12 | f.xs | Properties.cs:84:9:84:25 | SSA def(f.xs) | Properties.cs:84:9:84:25 | ... = ... |
| Properties.cs:78:9:78:15 | this.xs | Properties.cs:81:9:81:22 | SSA def(this.xs) | Properties.cs:81:9:81:22 | ... = ... |
| Properties.cs:78:9:78:15 | this.xs | Properties.cs:83:9:83:22 | SSA def(this.xs) | Properties.cs:83:9:83:22 | ... = ... |
| Properties.cs:106:37:106:37 | p | Properties.cs:106:37:106:37 | SSA param(p) | Properties.cs:106:37:106:37 | p |
| Splitting.cs:3:18:3:18 | b | Splitting.cs:3:18:3:18 | SSA param(b) | Splitting.cs:3:18:3:18 | b |
| Splitting.cs:5:13:5:13 | x | Splitting.cs:7:13:7:19 | [b (line 3): true] SSA def(x) | Splitting.cs:7:13:7:19 | ... = ... |
| Splitting.cs:5:13:5:13 | x | Splitting.cs:10:13:10:19 | [b (line 3): false] SSA def(x) | Splitting.cs:10:13:10:19 | ... = ... |
| Splitting.cs:22:18:22:18 | b | Splitting.cs:22:18:22:18 | SSA param(b) | Splitting.cs:22:18:22:18 | b |
| Splitting.cs:24:13:24:13 | x | Splitting.cs:29:13:29:19 | [b (line 22): false] SSA def(x) | Splitting.cs:29:13:29:19 | ... = ... |
| Splitting.cs:24:13:24:13 | x | Splitting.cs:32:9:32:15 | [b (line 22): false] SSA def(x) | Splitting.cs:32:9:32:15 | ... = ... |
| Splitting.cs:24:13:24:13 | x | Splitting.cs:32:9:32:15 | [b (line 22): true] SSA def(x) | Splitting.cs:32:9:32:15 | ... = ... |
| Splitting.cs:42:18:42:18 | b | Splitting.cs:42:18:42:18 | SSA param(b) | Splitting.cs:42:18:42:18 | b |
| Splitting.cs:44:13:44:13 | x | Splitting.cs:46:13:46:19 | [b (line 42): true] SSA def(x) | Splitting.cs:46:13:46:19 | ... = ... |
| Splitting.cs:44:13:44:13 | x | Splitting.cs:49:13:49:19 | [b (line 42): false] SSA def(x) | Splitting.cs:49:13:49:19 | ... = ... |
| Test.cs:5:15:5:20 | param1 | Test.cs:5:15:5:20 | SSA param(param1) | Test.cs:5:15:5:20 | param1 |
| Test.cs:5:15:5:20 | param1 | Test.cs:27:17:27:24 | SSA def(param1) | Test.cs:27:17:27:24 | ...++ |
| Test.cs:5:15:5:20 | param1 | Test.cs:41:13:41:23 | SSA def(param1) | Test.cs:41:13:41:23 | ... = ... |
| Test.cs:5:67:5:72 | param2 | Test.cs:5:67:5:72 | SSA param(param2) | Test.cs:5:67:5:72 | param2 |
| Test.cs:7:9:7:13 | this.field | Test.cs:7:9:7:17 | SSA def(this.field) | Test.cs:7:9:7:17 | ... = ... |
| Test.cs:7:9:7:13 | this.field | Test.cs:21:13:21:22 | SSA def(this.field) | Test.cs:21:13:21:22 | ... = ... |
| Test.cs:8:13:8:13 | x | Test.cs:8:13:8:17 | SSA def(x) | Test.cs:8:13:8:17 | Int32 x = ... |
@ -174,18 +141,10 @@
| Test.cs:34:18:34:18 | i | Test.cs:34:18:34:22 | SSA def(i) | Test.cs:34:18:34:22 | Int32 i = ... |
| Test.cs:34:18:34:18 | i | Test.cs:34:33:34:35 | SSA def(i) | Test.cs:34:33:34:35 | ...++ |
| Test.cs:39:22:39:22 | w | Test.cs:39:22:39:22 | SSA def(w) | Test.cs:39:22:39:22 | Int32 w |
| Test.cs:46:16:46:18 | in | Test.cs:46:16:46:18 | SSA param(in) | Test.cs:46:16:46:18 | in |
| Test.cs:46:29:46:32 | out | Test.cs:50:13:50:20 | SSA def(out) | Test.cs:50:13:50:20 | ... = ... |
| Test.cs:46:29:46:32 | out | Test.cs:54:13:54:20 | SSA def(out) | Test.cs:54:13:54:20 | ... = ... |
| Test.cs:56:13:56:17 | this.field | Test.cs:57:9:57:17 | SSA def(this.field) | Test.cs:57:9:57:17 | ... = ... |
| Test.cs:62:16:62:16 | x | Test.cs:62:16:62:16 | SSA param(x) | Test.cs:62:16:62:16 | x |
| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | [exception: DivideByZeroException] SSA def(e) | Test.cs:68:45:68:45 | DivideByZeroException e |
| Test.cs:76:24:76:25 | b1 | Test.cs:76:24:76:25 | SSA param(b1) | Test.cs:76:24:76:25 | b1 |
| Test.cs:76:33:76:34 | b2 | Test.cs:76:33:76:34 | SSA param(b2) | Test.cs:76:33:76:34 | b2 |
| Test.cs:76:42:76:43 | b3 | Test.cs:76:42:76:43 | SSA param(b3) | Test.cs:76:42:76:43 | b3 |
| Test.cs:76:51:76:52 | b4 | Test.cs:76:51:76:52 | SSA param(b4) | Test.cs:76:51:76:52 | b4 |
| Test.cs:76:60:76:61 | b5 | Test.cs:76:60:76:61 | SSA param(b5) | Test.cs:76:60:76:61 | b5 |
| Test.cs:76:69:76:70 | b6 | Test.cs:76:69:76:70 | SSA param(b6) | Test.cs:76:69:76:70 | b6 |
| Test.cs:78:13:78:13 | x | Test.cs:78:13:78:17 | SSA def(x) | Test.cs:78:13:78:17 | Int32 x = ... |
| Test.cs:78:13:78:13 | x | Test.cs:108:13:108:17 | SSA def(x) | Test.cs:108:13:108:17 | ... = ... |
| Tuples.cs:10:14:10:14 | x | Tuples.cs:10:9:10:54 | SSA def(x) | Tuples.cs:10:9:10:54 | ... = ... |

Просмотреть файл

@ -0,0 +1,43 @@
| Capture.cs:57:57:57:63 | strings | Capture.cs:57:57:57:63 | SSA param(strings) | Capture.cs:57:57:57:63 | strings |
| Capture.cs:65:45:65:51 | strings | Capture.cs:65:45:65:51 | SSA param(strings) | Capture.cs:65:45:65:51 | strings |
| Capture.cs:68:32:68:32 | s | Capture.cs:68:32:68:32 | SSA param(s) | Capture.cs:68:32:68:32 | s |
| Capture.cs:69:25:69:25 | s | Capture.cs:69:25:69:25 | SSA param(s) | Capture.cs:69:25:69:25 | s |
| Capture.cs:73:67:73:73 | strings | Capture.cs:73:67:73:73 | SSA param(strings) | Capture.cs:73:67:73:73 | strings |
| Capture.cs:81:28:81:28 | i | Capture.cs:81:28:81:28 | SSA param(i) | Capture.cs:81:28:81:28 | i |
| Capture.cs:83:65:83:71 | strings | Capture.cs:83:65:83:71 | SSA param(strings) | Capture.cs:83:65:83:71 | strings |
| Capture.cs:92:18:92:18 | d | Capture.cs:92:18:92:18 | SSA param(d) | Capture.cs:92:18:92:18 | d |
| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:7:25:7:25 | b |
| Consistency.cs:49:30:49:30 | a | Consistency.cs:49:30:49:30 | SSA param(a) | Consistency.cs:49:30:49:30 | a |
| Consistency.cs:49:37:49:37 | i | Consistency.cs:49:37:49:37 | SSA param(i) | Consistency.cs:49:37:49:37 | i |
| Consistency.cs:51:20:51:20 | a | Consistency.cs:51:20:51:20 | SSA param(a) | Consistency.cs:51:20:51:20 | a |
| DefUse.cs:3:26:3:26 | w | DefUse.cs:3:26:3:26 | SSA param(w) | DefUse.cs:3:26:3:26 | w |
| DefUse.cs:118:45:118:45 | i | DefUse.cs:118:45:118:45 | SSA param(i) | DefUse.cs:118:45:118:45 | i |
| DefUse.cs:128:19:128:19 | i | DefUse.cs:128:19:128:19 | SSA param(i) | DefUse.cs:128:19:128:19 | i |
| DefUse.cs:134:22:134:22 | d | DefUse.cs:134:22:134:22 | SSA param(d) | DefUse.cs:134:22:134:22 | d |
| DefUse.cs:142:68:142:69 | ie | DefUse.cs:142:68:142:69 | SSA param(ie) | DefUse.cs:142:68:142:69 | ie |
| Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | SSA param(i) | Example.cs:6:23:6:23 | i |
| Example.cs:18:16:18:16 | p | Example.cs:18:16:18:16 | SSA param(p) | Example.cs:18:16:18:16 | p |
| Example.cs:18:24:18:24 | b | Example.cs:18:24:18:24 | SSA param(b) | Example.cs:18:24:18:24 | b |
| Fields.cs:95:19:95:19 | f | Fields.cs:95:19:95:19 | SSA param(f) | Fields.cs:95:19:95:19 | f |
| Fields.cs:107:33:107:33 | f | Fields.cs:107:33:107:33 | SSA param(f) | Fields.cs:107:33:107:33 | f |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | x |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | x |
| OutRef.cs:28:37:28:37 | j | OutRef.cs:28:37:28:37 | SSA param(j) | OutRef.cs:28:37:28:37 | j |
| OutRef.cs:34:38:34:38 | j | OutRef.cs:34:38:34:38 | SSA param(j) | OutRef.cs:34:38:34:38 | j |
| OutRef.cs:39:24:39:24 | b | OutRef.cs:39:24:39:24 | SSA param(b) | OutRef.cs:39:24:39:24 | b |
| OutRef.cs:39:35:39:35 | j | OutRef.cs:39:35:39:35 | SSA param(j) | OutRef.cs:39:35:39:35 | j |
| Properties.cs:61:23:61:23 | i | Properties.cs:61:23:61:23 | SSA param(i) | Properties.cs:61:23:61:23 | i |
| Properties.cs:106:37:106:37 | p | Properties.cs:106:37:106:37 | SSA param(p) | Properties.cs:106:37:106:37 | p |
| Splitting.cs:3:18:3:18 | b | Splitting.cs:3:18:3:18 | SSA param(b) | Splitting.cs:3:18:3:18 | b |
| Splitting.cs:22:18:22:18 | b | Splitting.cs:22:18:22:18 | SSA param(b) | Splitting.cs:22:18:22:18 | b |
| Splitting.cs:42:18:42:18 | b | Splitting.cs:42:18:42:18 | SSA param(b) | Splitting.cs:42:18:42:18 | b |
| Test.cs:5:15:5:20 | param1 | Test.cs:5:15:5:20 | SSA param(param1) | Test.cs:5:15:5:20 | param1 |
| Test.cs:5:67:5:72 | param2 | Test.cs:5:67:5:72 | SSA param(param2) | Test.cs:5:67:5:72 | param2 |
| Test.cs:46:16:46:18 | in | Test.cs:46:16:46:18 | SSA param(in) | Test.cs:46:16:46:18 | in |
| Test.cs:62:16:62:16 | x | Test.cs:62:16:62:16 | SSA param(x) | Test.cs:62:16:62:16 | x |
| Test.cs:76:24:76:25 | b1 | Test.cs:76:24:76:25 | SSA param(b1) | Test.cs:76:24:76:25 | b1 |
| Test.cs:76:33:76:34 | b2 | Test.cs:76:33:76:34 | SSA param(b2) | Test.cs:76:33:76:34 | b2 |
| Test.cs:76:42:76:43 | b3 | Test.cs:76:42:76:43 | SSA param(b3) | Test.cs:76:42:76:43 | b3 |
| Test.cs:76:51:76:52 | b4 | Test.cs:76:51:76:52 | SSA param(b4) | Test.cs:76:51:76:52 | b4 |
| Test.cs:76:60:76:61 | b5 | Test.cs:76:60:76:61 | SSA param(b5) | Test.cs:76:60:76:61 | b5 |
| Test.cs:76:69:76:70 | b6 | Test.cs:76:69:76:70 | SSA param(b6) | Test.cs:76:69:76:70 | b6 |

Просмотреть файл

@ -0,0 +1,5 @@
import csharp
from Ssa::SourceVariable v, Ssa::ImplicitParameterDefinition def
where v = def.getSourceVariable()
select v, def, def.getParameter()

Просмотреть файл

@ -193,6 +193,8 @@
| Fields.cs:115:20:115:35 | this.Field.Field | Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:117:17:117:32 | access to field Field |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:116:21:116:39 | access to field xs |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:117:17:117:35 | access to field xs |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:28:5:28 | access to parameter x |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationB.cs:3:28:3:28 | access to parameter x |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:10:32:10:32 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:12:13:12:13 | access to local variable j |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:22:29:22:29 | access to local variable j |

Просмотреть файл

@ -206,6 +206,8 @@
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:109:10:109:10 | SSA qualifier def(this.Field.Field.xs) |
| Fields.cs:116:21:116:39 | this.Field.Field.xs | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationA.cs:5:22:5:22 | SSA param(x) | MultiImplementationA.cs:5:22:5:22 | SSA param(x) |
| MultiImplementationA.cs:5:22:5:22 | x | MultiImplementationB.cs:3:22:3:22 | SSA param(x) | MultiImplementationB.cs:3:22:3:22 | SSA param(x) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:9:13:9:17 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:10:32:10:32 | SSA def(j) |
| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | SSA def(j) | OutRef.cs:22:22:22:22 | SSA def(j) |