mirror of
https://github.com/github/codeql.git
synced 2026-04-26 17:25:19 +02:00
Merge pull request #8038 from michaelnebel/csharp/gvn-cfecomparison
C#: Refactor Structural Comparison for Control Flow Elements.
This commit is contained in:
@@ -5,6 +5,36 @@
|
||||
|
||||
import csharp
|
||||
|
||||
abstract private class GvnKind extends TGvnKind {
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
private class GvnKindExpr extends GvnKind, TGvnKindExpr {
|
||||
private int kind;
|
||||
|
||||
GvnKindExpr() { this = TGvnKindExpr(kind) }
|
||||
|
||||
override string toString() { result = "Expr(" + kind + ")" }
|
||||
}
|
||||
|
||||
private class GvnKindStmt extends GvnKind, TGvnKindStmt {
|
||||
private int kind;
|
||||
|
||||
GvnKindStmt() { this = TGvnKindStmt(kind) }
|
||||
|
||||
override string toString() { result = "Stmt(" + kind + ")" }
|
||||
}
|
||||
|
||||
private class GvnKindDeclaration extends GvnKind, TGvnKindDeclaration {
|
||||
private int kind;
|
||||
private boolean isTargetThis;
|
||||
private Declaration d;
|
||||
|
||||
GvnKindDeclaration() { this = TGvnKindDeclaration(kind, isTargetThis, d) }
|
||||
|
||||
override string toString() { result = "Expr(" + kind + ")," + isTargetThis + "," + d }
|
||||
}
|
||||
|
||||
/** Gets the declaration referenced by the expression `e`, if any. */
|
||||
private Declaration referenceAttribute(Expr e) {
|
||||
result = e.(MethodCall).getTarget()
|
||||
@@ -14,17 +44,156 @@ private Declaration referenceAttribute(Expr e) {
|
||||
result = e.(Access).getTarget()
|
||||
}
|
||||
|
||||
/** Gets the AST node kind element `e`. */
|
||||
private int elementKind(ControlFlowElement e) {
|
||||
expressions(e, result, _)
|
||||
/** Gets a Boolean indicating whether the target of the expression `e` is `this`. */
|
||||
private boolean isTargetThis(Expr e) {
|
||||
result = true and e.(MemberAccess).targetIsThisInstance()
|
||||
or
|
||||
exists(int k | statements(e, k) | result = -k)
|
||||
result = false and not e.(MemberAccess).targetIsThisInstance()
|
||||
}
|
||||
|
||||
private int getNumberOfActualChildren(ControlFlowElement e) {
|
||||
if e.(MemberAccess).targetIsThisInstance()
|
||||
then result = e.getNumberOfChildren() - 1
|
||||
else result = e.getNumberOfChildren()
|
||||
/**
|
||||
* A global value number (GVN) for a control flow element.
|
||||
*
|
||||
* GVNs are used to map control flow elements to a representation that
|
||||
* omits location information, that is, two elements that are structurally
|
||||
* equal will be mapped to the same GVN.
|
||||
*/
|
||||
class Gvn extends TGvn {
|
||||
/** Gets the string representation of this global value number. */
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
private class ConstantGvn extends Gvn, TConstantGvn {
|
||||
override string toString() { this = TConstantGvn(result) }
|
||||
}
|
||||
|
||||
private class GvnNil extends Gvn, TGvnNil {
|
||||
private GvnKind kind;
|
||||
|
||||
GvnNil() { this = TGvnNil(kind) }
|
||||
|
||||
override string toString() { result = "(kind:" + kind + ")" }
|
||||
}
|
||||
|
||||
private class GvnCons extends Gvn, TGvnCons {
|
||||
private Gvn head;
|
||||
private Gvn tail;
|
||||
|
||||
GvnCons() { this = TGvnCons(head, tail) }
|
||||
|
||||
override string toString() { result = "(" + head + " :: " + tail + ")" }
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate gvnKindDeclaration(Expr e, int kind, boolean isTargetThis, Declaration d) {
|
||||
isTargetThis = isTargetThis(e) and
|
||||
d = referenceAttribute(e) and
|
||||
expressions(e, kind, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `GvnKind` of the element `cfe`.
|
||||
*
|
||||
* In case `cfe` is a reference attribute, we encode the entire declaration and whether
|
||||
* the target is semantically equivalent to `this`.
|
||||
*/
|
||||
private GvnKind getGvnKind(ControlFlowElement cfe) {
|
||||
exists(int kind, boolean isTargetThis, Declaration d |
|
||||
gvnKindDeclaration(cfe, kind, isTargetThis, d) and
|
||||
result = TGvnKindDeclaration(kind, isTargetThis, d)
|
||||
)
|
||||
or
|
||||
exists(int kind |
|
||||
not exists(referenceAttribute(cfe)) and
|
||||
expressions(cfe, kind, _) and
|
||||
result = TGvnKindExpr(kind)
|
||||
or
|
||||
statements(cfe, kind) and
|
||||
result = TGvnKindStmt(kind)
|
||||
)
|
||||
}
|
||||
|
||||
private Gvn toGvn(ControlFlowElement cfe, GvnKind kind, int index) {
|
||||
kind = getGvnKind(cfe) and
|
||||
result = TGvnNil(kind) and
|
||||
index = -1
|
||||
or
|
||||
exists(Gvn head, Gvn tail |
|
||||
toGvnCons(cfe, kind, index, head, tail) and
|
||||
result = TGvnCons(head, tail)
|
||||
)
|
||||
}
|
||||
|
||||
private int getNumberOfActualChildren(ControlFlowElement cfe) {
|
||||
if cfe.(MemberAccess).targetIsThisInstance()
|
||||
then result = cfe.getNumberOfChildren() - 1
|
||||
else result = cfe.getNumberOfChildren()
|
||||
}
|
||||
|
||||
private ControlFlowElement getRankedChild(ControlFlowElement cfe, int rnk) {
|
||||
result =
|
||||
rank[rnk + 1](ControlFlowElement child, int j |
|
||||
child = cfe.getChild(j) and
|
||||
(
|
||||
j >= 0
|
||||
or
|
||||
j = -1 and not cfe.(MemberAccess).targetIsThisInstance()
|
||||
)
|
||||
|
|
||||
child order by j
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Gvn toGvnChild(ControlFlowElement cfe, int index) {
|
||||
result = toGvn(getRankedChild(cfe, index))
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate toGvnCons(ControlFlowElement cfe, GvnKind kind, int index, Gvn head, Gvn tail) {
|
||||
tail = toGvn(cfe, kind, index - 1) and
|
||||
head = toGvnChild(cfe, index)
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
cached
|
||||
newtype TGvnKind =
|
||||
TGvnKindExpr(int kind) { expressions(_, kind, _) } or
|
||||
TGvnKindStmt(int kind) { statements(_, kind) } or
|
||||
TGvnKindDeclaration(int kind, boolean thisTarget, Declaration d) {
|
||||
exists(Expr e |
|
||||
d = referenceAttribute(e) and thisTarget = isTargetThis(e) and expressions(e, kind, _)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
newtype TGvn =
|
||||
TConstantGvn(string s) { s = any(Expr e).getValue() } or
|
||||
TGvnNil(GvnKind gkind) or
|
||||
TGvnCons(Gvn head, Gvn tail) { toGvnCons(_, _, _, head, tail) }
|
||||
|
||||
/** Gets the global value number of the element `cfe`. */
|
||||
cached
|
||||
Gvn toGvnCached(ControlFlowElement cfe) {
|
||||
result = TConstantGvn(cfe.(Expr).getValue())
|
||||
or
|
||||
not exists(cfe.(Expr).getValue()) and
|
||||
exists(GvnKind kind, int index |
|
||||
result = toGvn(cfe, kind, index - 1) and
|
||||
index = getNumberOfActualChildren(cfe)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private import Cached
|
||||
|
||||
predicate toGvn = toGvnCached/1;
|
||||
|
||||
pragma[inline]
|
||||
private predicate sameGvn(ControlFlowElement x, ControlFlowElement y) {
|
||||
pragma[only_bind_into](toGvn(pragma[only_bind_out](x))) =
|
||||
pragma[only_bind_into](toGvn(pragma[only_bind_out](y)))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,87 +226,12 @@ abstract class StructuralComparisonConfiguration extends string {
|
||||
*/
|
||||
abstract predicate candidate(ControlFlowElement x, ControlFlowElement y);
|
||||
|
||||
private predicate candidateInternal(ControlFlowElement x, ControlFlowElement y) {
|
||||
candidate(x, y)
|
||||
or
|
||||
exists(ControlFlowElement xParent, ControlFlowElement yParent, int i |
|
||||
candidateInternalChild(xParent, i, x, yParent)
|
||||
|
|
||||
y = yParent.getChild(i)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate candidateInternalChild(
|
||||
ControlFlowElement x, int i, ControlFlowElement xChild, ControlFlowElement y
|
||||
) {
|
||||
candidateInternal(x, y) and
|
||||
xChild = x.getChild(i)
|
||||
}
|
||||
|
||||
private predicate sameByValue(Expr x, Expr y) { sameByValueAux(x, y, y.getValue()) }
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sameByValueAux(Expr x, Expr y, string value) {
|
||||
candidateInternal(x, y) and
|
||||
value = x.getValue()
|
||||
}
|
||||
|
||||
private ControlFlowElement getRankedChild(ControlFlowElement cfe, int rnk, int i) {
|
||||
(candidateInternal(cfe, _) or candidateInternal(_, cfe)) and
|
||||
i =
|
||||
rank[rnk](int j |
|
||||
exists(ControlFlowElement child | child = cfe.getChild(j) |
|
||||
not (j = -1 and cfe.(MemberAccess).targetIsThisInstance())
|
||||
)
|
||||
) and
|
||||
result = cfe.getChild(i)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sameByStructure0(
|
||||
ControlFlowElement x, ControlFlowElement y, int elementKind, int children
|
||||
) {
|
||||
candidateInternal(x, y) and
|
||||
elementKind = elementKind(x) and
|
||||
children = getNumberOfActualChildren(x) and
|
||||
not (x.(Expr).hasValue() and y.(Expr).hasValue())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sameByStructure(ControlFlowElement x, ControlFlowElement y, int i) {
|
||||
i = 0 and
|
||||
// At least one of `x` and `y` must not have a value, they must have
|
||||
// the same kind, and the same number of children
|
||||
sameByStructure0(x, y, elementKind(y), getNumberOfActualChildren(y)) and
|
||||
// If one of them has a reference attribute, they should both reference
|
||||
// the same node
|
||||
(exists(referenceAttribute(x)) implies referenceAttribute(x) = referenceAttribute(y)) and
|
||||
// x is a member access on `this` iff y is
|
||||
(x.(MemberAccess).targetIsThisInstance() implies y.(MemberAccess).targetIsThisInstance()) and
|
||||
(y.(MemberAccess).targetIsThisInstance() implies x.(MemberAccess).targetIsThisInstance())
|
||||
or
|
||||
exists(int j | sameByStructure(x, y, i - 1) |
|
||||
sameInternal(getRankedChild(x, i, j), getRankedChild(y, i, j))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sameInternal(ControlFlowElement x, ControlFlowElement y) {
|
||||
sameByValue(x, y)
|
||||
or
|
||||
sameByStructure(x, y, getNumberOfActualChildren(x))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if elements `x` and `y` structurally equal. `x` and `y` must be
|
||||
* flagged as candidates for structural equality, that is,
|
||||
* `candidate(x, y)` must hold.
|
||||
*/
|
||||
predicate same(ControlFlowElement x, ControlFlowElement y) {
|
||||
candidate(x, y) and
|
||||
sameInternal(x, y)
|
||||
}
|
||||
predicate same(ControlFlowElement x, ControlFlowElement y) { candidate(x, y) and sameGvn(x, y) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,86 +277,11 @@ module Internal {
|
||||
*/
|
||||
abstract predicate candidate(ControlFlowElement x, ControlFlowElement y);
|
||||
|
||||
private predicate candidateInternal(ControlFlowElement x, ControlFlowElement y) {
|
||||
candidate(x, y)
|
||||
or
|
||||
exists(ControlFlowElement xParent, ControlFlowElement yParent, int i |
|
||||
candidateInternalChild(xParent, i, x, yParent)
|
||||
|
|
||||
y = yParent.getChild(i)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate candidateInternalChild(
|
||||
ControlFlowElement x, int i, ControlFlowElement xChild, ControlFlowElement y
|
||||
) {
|
||||
candidateInternal(x, y) and
|
||||
xChild = x.getChild(i)
|
||||
}
|
||||
|
||||
private predicate sameByValue(Expr x, Expr y) { sameByValueAux(x, y, y.getValue()) }
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sameByValueAux(Expr x, Expr y, string value) {
|
||||
candidateInternal(x, y) and
|
||||
value = x.getValue()
|
||||
}
|
||||
|
||||
private ControlFlowElement getRankedChild(ControlFlowElement cfe, int rnk, int i) {
|
||||
(candidateInternal(cfe, _) or candidateInternal(_, cfe)) and
|
||||
i =
|
||||
rank[rnk](int j |
|
||||
exists(ControlFlowElement child | child = cfe.getChild(j) |
|
||||
not (j = -1 and cfe.(MemberAccess).targetIsThisInstance())
|
||||
)
|
||||
) and
|
||||
result = cfe.getChild(i)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sameByStructure0(
|
||||
ControlFlowElement x, ControlFlowElement y, int elementKind, int children
|
||||
) {
|
||||
candidateInternal(x, y) and
|
||||
elementKind = elementKind(x) and
|
||||
children = getNumberOfActualChildren(x) and
|
||||
not (x.(Expr).hasValue() and y.(Expr).hasValue())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sameByStructure(ControlFlowElement x, ControlFlowElement y, int i) {
|
||||
i = 0 and
|
||||
// At least one of `x` and `y` must not have a value, they must have
|
||||
// the same kind, and the same number of children
|
||||
sameByStructure0(x, y, elementKind(y), getNumberOfActualChildren(y)) and
|
||||
// If one of them has a reference attribute, they should both reference
|
||||
// the same node
|
||||
(exists(referenceAttribute(x)) implies referenceAttribute(x) = referenceAttribute(y)) and
|
||||
// x is a member access on `this` iff y is
|
||||
(x.(MemberAccess).targetIsThisInstance() implies y.(MemberAccess).targetIsThisInstance()) and
|
||||
(y.(MemberAccess).targetIsThisInstance() implies x.(MemberAccess).targetIsThisInstance())
|
||||
or
|
||||
exists(int j | sameByStructure(x, y, i - 1) |
|
||||
sameInternal(getRankedChild(x, i, j), getRankedChild(y, i, j))
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate sameInternal(ControlFlowElement x, ControlFlowElement y) {
|
||||
sameByValue(x, y)
|
||||
or
|
||||
sameByStructure(x, y, getNumberOfActualChildren(x))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if elements `x` and `y` structurally equal. `x` and `y` must be
|
||||
* flagged as candidates for structural equality, that is,
|
||||
* `candidate(x, y)` must hold.
|
||||
*/
|
||||
predicate same(ControlFlowElement x, ControlFlowElement y) {
|
||||
candidate(x, y) and
|
||||
sameInternal(x, y)
|
||||
}
|
||||
predicate same(ControlFlowElement x, ControlFlowElement y) { candidate(x, y) and sameGvn(x, y) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
|
||||
public class Class
|
||||
{
|
||||
private readonly int x = 0;
|
||||
private readonly int y = 1;
|
||||
|
||||
public int M0() => 0;
|
||||
public int M1(int a) => a;
|
||||
public int M2(int v1, int v2) => v1 + v2;
|
||||
|
||||
|
||||
public void M3()
|
||||
{
|
||||
var z1 = x + y;
|
||||
var z2 = x + y;
|
||||
}
|
||||
|
||||
public void M4()
|
||||
{
|
||||
var z3 = M1(x);
|
||||
var z4 = M1(x);
|
||||
var z5 = M1(y);
|
||||
var z6 = M0();
|
||||
var z7 = M2(x, y) + M2(x, y);
|
||||
M2(x, y);
|
||||
M2(y, x);
|
||||
M2(y, x);
|
||||
}
|
||||
}
|
||||
|
||||
public class BaseClass
|
||||
{
|
||||
public int Field;
|
||||
public object Prop { get; set; }
|
||||
}
|
||||
|
||||
public class DerivedClass : BaseClass
|
||||
{
|
||||
public void M4()
|
||||
{
|
||||
var x1 = base.Field;
|
||||
var x2 = Field;
|
||||
var x3 = this.Field;
|
||||
}
|
||||
|
||||
public void M5()
|
||||
{
|
||||
var y1 = base.Prop;
|
||||
var y2 = Prop;
|
||||
var y3 = this.Prop;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
same
|
||||
| StructuralComparison.cs:15:18:15:18 | access to field x | StructuralComparison.cs:16:18:16:18 | access to field x |
|
||||
| StructuralComparison.cs:15:18:15:22 | ... + ... | StructuralComparison.cs:16:18:16:22 | ... + ... |
|
||||
| StructuralComparison.cs:15:22:15:22 | access to field y | StructuralComparison.cs:16:22:16:22 | access to field y |
|
||||
| StructuralComparison.cs:21:18:21:22 | call to method M1 | StructuralComparison.cs:22:18:22:22 | call to method M1 |
|
||||
| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:22:21:22:21 | access to field x |
|
||||
| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:25:21:25:21 | access to field x |
|
||||
| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:25:32:25:32 | access to field x |
|
||||
| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:26:12:26:12 | access to field x |
|
||||
| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x |
|
||||
| StructuralComparison.cs:21:21:21:21 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x |
|
||||
| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:25:21:25:21 | access to field x |
|
||||
| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:25:32:25:32 | access to field x |
|
||||
| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:26:12:26:12 | access to field x |
|
||||
| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x |
|
||||
| StructuralComparison.cs:22:21:22:21 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x |
|
||||
| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:25:24:25:24 | access to field y |
|
||||
| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:25:35:25:35 | access to field y |
|
||||
| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:26:15:26:15 | access to field y |
|
||||
| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:27:12:27:12 | access to field y |
|
||||
| StructuralComparison.cs:23:21:23:21 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y |
|
||||
| StructuralComparison.cs:25:18:25:25 | call to method M2 | StructuralComparison.cs:25:29:25:36 | call to method M2 |
|
||||
| StructuralComparison.cs:25:18:25:25 | call to method M2 | StructuralComparison.cs:26:9:26:16 | call to method M2 |
|
||||
| StructuralComparison.cs:25:21:25:21 | access to field x | StructuralComparison.cs:25:32:25:32 | access to field x |
|
||||
| StructuralComparison.cs:25:21:25:21 | access to field x | StructuralComparison.cs:26:12:26:12 | access to field x |
|
||||
| StructuralComparison.cs:25:21:25:21 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x |
|
||||
| StructuralComparison.cs:25:21:25:21 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x |
|
||||
| StructuralComparison.cs:25:24:25:24 | access to field y | StructuralComparison.cs:25:35:25:35 | access to field y |
|
||||
| StructuralComparison.cs:25:24:25:24 | access to field y | StructuralComparison.cs:26:15:26:15 | access to field y |
|
||||
| StructuralComparison.cs:25:24:25:24 | access to field y | StructuralComparison.cs:27:12:27:12 | access to field y |
|
||||
| StructuralComparison.cs:25:24:25:24 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y |
|
||||
| StructuralComparison.cs:25:29:25:36 | call to method M2 | StructuralComparison.cs:26:9:26:16 | call to method M2 |
|
||||
| StructuralComparison.cs:25:32:25:32 | access to field x | StructuralComparison.cs:26:12:26:12 | access to field x |
|
||||
| StructuralComparison.cs:25:32:25:32 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x |
|
||||
| StructuralComparison.cs:25:32:25:32 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x |
|
||||
| StructuralComparison.cs:25:35:25:35 | access to field y | StructuralComparison.cs:26:15:26:15 | access to field y |
|
||||
| StructuralComparison.cs:25:35:25:35 | access to field y | StructuralComparison.cs:27:12:27:12 | access to field y |
|
||||
| StructuralComparison.cs:25:35:25:35 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y |
|
||||
| StructuralComparison.cs:26:12:26:12 | access to field x | StructuralComparison.cs:27:15:27:15 | access to field x |
|
||||
| StructuralComparison.cs:26:12:26:12 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x |
|
||||
| StructuralComparison.cs:26:15:26:15 | access to field y | StructuralComparison.cs:27:12:27:12 | access to field y |
|
||||
| StructuralComparison.cs:26:15:26:15 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y |
|
||||
| StructuralComparison.cs:27:9:27:16 | call to method M2 | StructuralComparison.cs:28:9:28:16 | call to method M2 |
|
||||
| StructuralComparison.cs:27:9:27:17 | ...; | StructuralComparison.cs:28:9:28:17 | ...; |
|
||||
| StructuralComparison.cs:27:12:27:12 | access to field y | StructuralComparison.cs:28:12:28:12 | access to field y |
|
||||
| StructuralComparison.cs:27:15:27:15 | access to field x | StructuralComparison.cs:28:15:28:15 | access to field x |
|
||||
| StructuralComparison.cs:42:18:42:27 | access to field Field | StructuralComparison.cs:43:18:43:22 | access to field Field |
|
||||
| StructuralComparison.cs:42:18:42:27 | access to field Field | StructuralComparison.cs:44:18:44:27 | access to field Field |
|
||||
| StructuralComparison.cs:43:18:43:22 | access to field Field | StructuralComparison.cs:44:18:44:27 | access to field Field |
|
||||
| StructuralComparison.cs:49:18:49:26 | access to property Prop | StructuralComparison.cs:50:18:50:21 | access to property Prop |
|
||||
| StructuralComparison.cs:49:18:49:26 | access to property Prop | StructuralComparison.cs:51:18:51:26 | access to property Prop |
|
||||
| StructuralComparison.cs:50:18:50:21 | access to property Prop | StructuralComparison.cs:51:18:51:26 | access to property Prop |
|
||||
gvn
|
||||
| StructuralComparison.cs:5:26:5:26 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:5:26:5:26 | this access | (kind:Expr(12)) |
|
||||
| StructuralComparison.cs:5:26:5:30 | ... = ... | ((kind:Expr(16),true,x) :: (0 :: (kind:Expr(63)))) |
|
||||
| StructuralComparison.cs:5:30:5:30 | 0 | 0 |
|
||||
| StructuralComparison.cs:6:26:6:26 | access to field y | (kind:Expr(16),true,y) |
|
||||
| StructuralComparison.cs:6:26:6:26 | this access | (kind:Expr(12)) |
|
||||
| StructuralComparison.cs:6:26:6:30 | ... = ... | ((kind:Expr(16),true,y) :: (1 :: (kind:Expr(63)))) |
|
||||
| StructuralComparison.cs:6:30:6:30 | 1 | 1 |
|
||||
| StructuralComparison.cs:8:24:8:24 | 0 | 0 |
|
||||
| StructuralComparison.cs:9:29:9:29 | access to parameter a | (kind:Expr(15),false,a) |
|
||||
| StructuralComparison.cs:10:38:10:39 | access to parameter v1 | (kind:Expr(15),false,v1) |
|
||||
| StructuralComparison.cs:10:38:10:44 | ... + ... | ((kind:Expr(15),false,v2) :: ((kind:Expr(15),false,v1) :: (kind:Expr(44)))) |
|
||||
| StructuralComparison.cs:10:43:10:44 | access to parameter v2 | (kind:Expr(15),false,v2) |
|
||||
| StructuralComparison.cs:14:5:17:5 | {...} | ((((kind:Expr(14),false,z2) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z1) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: (kind:Stmt(1)))) |
|
||||
| StructuralComparison.cs:15:9:15:23 | ... ...; | (((kind:Expr(14),false,z1) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:15:13:15:14 | access to local variable z1 | (kind:Expr(14),false,z1) |
|
||||
| StructuralComparison.cs:15:13:15:22 | Int32 z1 = ... | ((kind:Expr(14),false,z1) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:15:18:15:18 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:15:18:15:18 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:15:18:15:22 | ... + ... | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) |
|
||||
| StructuralComparison.cs:15:22:15:22 | access to field y | (kind:Expr(16),true,y) |
|
||||
| StructuralComparison.cs:15:22:15:22 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:16:9:16:23 | ... ...; | (((kind:Expr(14),false,z2) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:16:13:16:14 | access to local variable z2 | (kind:Expr(14),false,z2) |
|
||||
| StructuralComparison.cs:16:13:16:22 | Int32 z2 = ... | ((kind:Expr(14),false,z2) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:16:18:16:18 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:16:18:16:18 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:16:18:16:22 | ... + ... | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: (kind:Expr(44)))) |
|
||||
| StructuralComparison.cs:16:22:16:22 | access to field y | (kind:Expr(16),true,y) |
|
||||
| StructuralComparison.cs:16:22:16:22 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:20:5:29:5 | {...} | ((((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) :: ((((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) :: ((((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) :: ((((kind:Expr(14),false,z7) :: ((((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z6) :: (((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M0)) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z5) :: (((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z4) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,z3) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: (kind:Stmt(1)))))))))) |
|
||||
| StructuralComparison.cs:21:9:21:23 | ... ...; | (((kind:Expr(14),false,z3) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:21:13:21:14 | access to local variable z3 | (kind:Expr(14),false,z3) |
|
||||
| StructuralComparison.cs:21:13:21:22 | Int32 z3 = ... | ((kind:Expr(14),false,z3) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:21:18:21:22 | call to method M1 | ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) |
|
||||
| StructuralComparison.cs:21:18:21:22 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:21:21:21:21 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:21:21:21:21 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:22:9:22:23 | ... ...; | (((kind:Expr(14),false,z4) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:22:13:22:14 | access to local variable z4 | (kind:Expr(14),false,z4) |
|
||||
| StructuralComparison.cs:22:13:22:22 | Int32 z4 = ... | ((kind:Expr(14),false,z4) :: (((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:22:18:22:22 | call to method M1 | ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) |
|
||||
| StructuralComparison.cs:22:18:22:22 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:22:21:22:21 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:22:21:22:21 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:23:9:23:23 | ... ...; | (((kind:Expr(14),false,z5) :: (((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:23:13:23:14 | access to local variable z5 | (kind:Expr(14),false,z5) |
|
||||
| StructuralComparison.cs:23:13:23:22 | Int32 z5 = ... | ((kind:Expr(14),false,z5) :: (((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:23:18:23:22 | call to method M1 | ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M1))) |
|
||||
| StructuralComparison.cs:23:18:23:22 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:23:21:23:21 | access to field y | (kind:Expr(16),true,y) |
|
||||
| StructuralComparison.cs:23:21:23:21 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:24:9:24:22 | ... ...; | (((kind:Expr(14),false,z6) :: (((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M0)) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:24:13:24:14 | access to local variable z6 | (kind:Expr(14),false,z6) |
|
||||
| StructuralComparison.cs:24:13:24:21 | Int32 z6 = ... | ((kind:Expr(14),false,z6) :: (((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M0)) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:24:18:24:21 | call to method M0 | ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M0)) |
|
||||
| StructuralComparison.cs:24:18:24:21 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:25:9:25:37 | ... ...; | (((kind:Expr(14),false,z7) :: ((((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Expr(44)))) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:25:13:25:14 | access to local variable z7 | (kind:Expr(14),false,z7) |
|
||||
| StructuralComparison.cs:25:13:25:36 | Int32 z7 = ... | ((kind:Expr(14),false,z7) :: ((((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Expr(44)))) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:25:18:25:25 | call to method M2 | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) |
|
||||
| StructuralComparison.cs:25:18:25:25 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:25:18:25:36 | ... + ... | (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Expr(44)))) |
|
||||
| StructuralComparison.cs:25:21:25:21 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:25:21:25:21 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:25:24:25:24 | access to field y | (kind:Expr(16),true,y) |
|
||||
| StructuralComparison.cs:25:24:25:24 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:25:29:25:36 | call to method M2 | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) |
|
||||
| StructuralComparison.cs:25:29:25:36 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:25:32:25:32 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:25:32:25:32 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:25:35:25:35 | access to field y | (kind:Expr(16),true,y) |
|
||||
| StructuralComparison.cs:25:35:25:35 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:26:9:26:16 | call to method M2 | ((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) |
|
||||
| StructuralComparison.cs:26:9:26:16 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:26:9:26:17 | ...; | (((kind:Expr(16),true,y) :: ((kind:Expr(16),true,x) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) |
|
||||
| StructuralComparison.cs:26:12:26:12 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:26:12:26:12 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:26:15:26:15 | access to field y | (kind:Expr(16),true,y) |
|
||||
| StructuralComparison.cs:26:15:26:15 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:27:9:27:16 | call to method M2 | ((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) |
|
||||
| StructuralComparison.cs:27:9:27:16 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:27:9:27:17 | ...; | (((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) |
|
||||
| StructuralComparison.cs:27:12:27:12 | access to field y | (kind:Expr(16),true,y) |
|
||||
| StructuralComparison.cs:27:12:27:12 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:27:15:27:15 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:27:15:27:15 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:28:9:28:16 | call to method M2 | ((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) |
|
||||
| StructuralComparison.cs:28:9:28:16 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:28:9:28:17 | ...; | (((kind:Expr(16),true,x) :: ((kind:Expr(16),true,y) :: ((kind:Expr(12),false,Class) :: (kind:Expr(24),false,M2)))) :: (kind:Stmt(2))) |
|
||||
| StructuralComparison.cs:28:12:28:12 | access to field y | (kind:Expr(16),true,y) |
|
||||
| StructuralComparison.cs:28:12:28:12 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:28:15:28:15 | access to field x | (kind:Expr(16),true,x) |
|
||||
| StructuralComparison.cs:28:15:28:15 | this access | (kind:Expr(12),false,Class) |
|
||||
| StructuralComparison.cs:41:5:45:5 | {...} | ((((kind:Expr(14),false,x3) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,x2) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,x1) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: (kind:Stmt(1))))) |
|
||||
| StructuralComparison.cs:42:9:42:28 | ... ...; | (((kind:Expr(14),false,x1) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:42:13:42:14 | access to local variable x1 | (kind:Expr(14),false,x1) |
|
||||
| StructuralComparison.cs:42:13:42:27 | Int32 x1 = ... | ((kind:Expr(14),false,x1) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:42:18:42:21 | base access | (kind:Expr(13),false,BaseClass) |
|
||||
| StructuralComparison.cs:42:18:42:27 | access to field Field | (kind:Expr(16),true,Field) |
|
||||
| StructuralComparison.cs:43:9:43:23 | ... ...; | (((kind:Expr(14),false,x2) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:43:13:43:14 | access to local variable x2 | (kind:Expr(14),false,x2) |
|
||||
| StructuralComparison.cs:43:13:43:22 | Int32 x2 = ... | ((kind:Expr(14),false,x2) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:43:18:43:22 | access to field Field | (kind:Expr(16),true,Field) |
|
||||
| StructuralComparison.cs:43:18:43:22 | this access | (kind:Expr(12),false,DerivedClass) |
|
||||
| StructuralComparison.cs:44:9:44:28 | ... ...; | (((kind:Expr(14),false,x3) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:44:13:44:14 | access to local variable x3 | (kind:Expr(14),false,x3) |
|
||||
| StructuralComparison.cs:44:13:44:27 | Int32 x3 = ... | ((kind:Expr(14),false,x3) :: ((kind:Expr(16),true,Field) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:44:18:44:21 | this access | (kind:Expr(12),false,DerivedClass) |
|
||||
| StructuralComparison.cs:44:18:44:27 | access to field Field | (kind:Expr(16),true,Field) |
|
||||
| StructuralComparison.cs:48:5:52:5 | {...} | ((((kind:Expr(14),false,y3) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,y2) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: ((((kind:Expr(14),false,y1) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) :: (kind:Stmt(1))))) |
|
||||
| StructuralComparison.cs:49:9:49:27 | ... ...; | (((kind:Expr(14),false,y1) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:49:13:49:14 | access to local variable y1 | (kind:Expr(14),false,y1) |
|
||||
| StructuralComparison.cs:49:13:49:26 | Object y1 = ... | ((kind:Expr(14),false,y1) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:49:18:49:21 | base access | (kind:Expr(13),false,BaseClass) |
|
||||
| StructuralComparison.cs:49:18:49:26 | access to property Prop | (kind:Expr(17),true,Prop) |
|
||||
| StructuralComparison.cs:50:9:50:22 | ... ...; | (((kind:Expr(14),false,y2) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:50:13:50:14 | access to local variable y2 | (kind:Expr(14),false,y2) |
|
||||
| StructuralComparison.cs:50:13:50:21 | Object y2 = ... | ((kind:Expr(14),false,y2) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:50:18:50:21 | access to property Prop | (kind:Expr(17),true,Prop) |
|
||||
| StructuralComparison.cs:50:18:50:21 | this access | (kind:Expr(12),false,DerivedClass) |
|
||||
| StructuralComparison.cs:51:9:51:27 | ... ...; | (((kind:Expr(14),false,y3) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) :: (kind:Stmt(22))) |
|
||||
| StructuralComparison.cs:51:13:51:14 | access to local variable y3 | (kind:Expr(14),false,y3) |
|
||||
| StructuralComparison.cs:51:13:51:26 | Object y3 = ... | ((kind:Expr(14),false,y3) :: ((kind:Expr(17),true,Prop) :: (kind:Expr(83)))) |
|
||||
| StructuralComparison.cs:51:18:51:21 | this access | (kind:Expr(12),false,DerivedClass) |
|
||||
| StructuralComparison.cs:51:18:51:26 | access to property Prop | (kind:Expr(17),true,Prop) |
|
||||
@@ -0,0 +1,34 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.commons.StructuralComparison
|
||||
|
||||
private class StructuralComparisonTest extends StructuralComparisonConfiguration {
|
||||
StructuralComparisonTest() { this = "StructuralComparisonTest" }
|
||||
|
||||
/**
|
||||
* All pairs of controls flow elements found in the source and within the same
|
||||
* enclosing callable excluding all instances of `ThisAccess` to reduce the size
|
||||
* of the output.
|
||||
*/
|
||||
override predicate candidate(ControlFlowElement e1, ControlFlowElement e2) {
|
||||
e1.fromSource() and
|
||||
e2.fromSource() and
|
||||
e1 != e2 and
|
||||
e1.getEnclosingCallable() = e2.getEnclosingCallable() and
|
||||
not e1 instanceof ThisAccess
|
||||
}
|
||||
}
|
||||
|
||||
query predicate same(ControlFlowElement e1, ControlFlowElement e2) {
|
||||
exists(StructuralComparisonTest sct, Location l1, Location l2 |
|
||||
sct.same(e1, e2) and
|
||||
l1 = e1.getLocation() and
|
||||
l2 = e2.getLocation() and
|
||||
(
|
||||
l1.getStartLine() < l2.getStartLine()
|
||||
or
|
||||
l1.getStartLine() = l2.getStartLine() and l1.getStartColumn() < l2.getStartColumn()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
query predicate gvn(ControlFlowElement e, Gvn gvn) { gvn = toGvn(e) and e.fromSource() }
|
||||
Reference in New Issue
Block a user