C#: Add field initializers to CFG for constructors

This commit adds field initializers to the CFG for non-static constructors. For
example, in

```
class C
{
    int Field1 = 0;
    int Field2 = Field1 + 1;
    int Field3;

    public C()
    {
        Field3 = 2;
    }

    public C(int i)
    {
        Field3 = 3;
    }
}
```

the initializer expressions `Field1 = 0` and `Field2 = Field1 + 1` are added
to the two constructors, mimicking

```
public C()
{
    Field1 = 0;
    Field2 = Field1 + 1;
    Field3 = 2;
}
```

and

```
public C()
{
    Field1 = 0;
    Field2 = Field1 + 1;
    Field3 = 3;
}
```

respectively. This means that we no longer have to synthesize calls, callables,
parameters, and arguments in the data flow library, so much of the work from
d1755500e4 can be simplified.
This commit is contained in:
Tom Hvitved
2019-08-21 10:17:57 +02:00
parent eb97d7beaa
commit 5d140930d0
21 changed files with 4061 additions and 466 deletions

View File

@@ -75,7 +75,7 @@ class BasicBlock extends TBasicBlockStart {
ControlFlow::Node getLastNode() { result = getNode(length() - 1) }
/** Gets the callable that this basic block belongs to. */
Callable getCallable() { result = this.getAPredecessor().getCallable() }
final Callable getCallable() { result = this.getFirstNode().getEnclosingCallable() }
/** Gets the length of this basic block. */
int length() { result = strictcount(getANode()) }
@@ -346,8 +346,6 @@ private import Internal
*/
class EntryBasicBlock extends BasicBlock {
EntryBasicBlock() { entryBB(this) }
override Callable getCallable() { result.getEntryPoint() = this.getFirstNode() }
}
/** Holds if `bb` is an entry basic block. */

View File

@@ -287,7 +287,11 @@ module ControlFlow {
ElementNode() { this = TElementNode(cfe, splits) }
override Callable getEnclosingCallable() { result = cfe.getEnclosingCallable() }
override Callable getEnclosingCallable() {
result = cfe.getEnclosingCallable()
or
result = this.getASplit().(InitializerSplitting::InitializerSplitImpl).getConstructor()
}
override ControlFlowElement getElement() { result = cfe }
@@ -1756,6 +1760,22 @@ module ControlFlow {
result = first(ci.getConstructor().getBody())
)
or
exists(Constructor con, InitializerSplitting::InitializedInstanceMember m, int i |
cfe = last(m.getInitializer(), c) and
c instanceof NormalCompletion and
InitializerSplitting::constructorInitializeOrder(con, m, i)
|
// Flow from one member initializer to the next
exists(InitializerSplitting::InitializedInstanceMember next |
InitializerSplitting::constructorInitializeOrder(con, next, i + 1) and
result = first(next.getInitializer())
)
or
// Flow from last member initializer to constructor body
m = InitializerSplitting::lastConstructorInitializer(con) and
result = first(con.getBody())
)
or
// Flow from element with `goto` completion to first element of relevant
// target
c = any(GotoCompletion gc |
@@ -1831,11 +1851,18 @@ module ControlFlow {
p = any(Callable c |
if exists(c.(Constructor).getInitializer())
then result = first(c.(Constructor).getInitializer())
else result = first(c.getBody())
else
if InitializerSplitting::constructorInitializes(c, _)
then
result = first(any(InitializerSplitting::InitializedInstanceMember m |
InitializerSplitting::constructorInitializeOrder(c, m, 0)
).getInitializer())
else result = first(c.getBody())
)
or
expr_parent_top_level_adjusted(any(Expr e | result = first(e)), _, p) and
not p instanceof Callable
not p instanceof Callable and
not p instanceof InitializerSplitting::InitializedInstanceMember
}
/**
@@ -1845,6 +1872,12 @@ module ControlFlow {
Callable succExit(ControlFlowElement cfe, Completion c) {
cfe = last(result.getBody(), c) and
not c instanceof GotoCompletion
or
exists(InitializerSplitting::InitializedInstanceMember m |
m = InitializerSplitting::lastConstructorInitializer(result) and
cfe = last(m.getInitializer(), c) and
not result.hasBody()
)
}
}
import Successor

View File

@@ -6,10 +6,8 @@
import csharp
private import semmle.code.csharp.controlflow.internal.Completion
private import semmle.code.csharp.controlflow.internal.PreBasicBlocks
private import semmle.code.csharp.controlflow.internal.PreSsa as PreSsa
private import semmle.code.csharp.controlflow.ControlFlowGraph::ControlFlow::Internal::Successor
private import semmle.code.csharp.controlflow.Guards as Guards
private import ControlFlow
private import SuccessorTypes
@@ -28,12 +26,14 @@ private module Cached {
cached
newtype TSplitKind =
TInitializerSplitKind() or
TFinallySplitKind() or
TExceptionHandlerSplitKind() or
TBooleanSplitKind(BooleanSplitting::BooleanSplitSubKind kind) { kind.startsSplit(_) }
cached
newtype TSplit =
TInitializerSplit(Constructor c) { InitializerSplitting::constructorInitializes(c, _) } or
TFinallySplit(FinallySplitting::FinallySplitType type) or
TExceptionHandlerSplit(ExceptionClass ec) or
TBooleanSplit(BooleanSplitting::BooleanSplitSubKind kind, boolean branch) {
@@ -51,6 +51,8 @@ private module Cached {
case2aFromRank(pred, predSplits, succ, tail, c, rnk + 1) and
head = case2aSomeAtRank(pred, predSplits, succ, c, rnk)
)
or
succEntrySplitsCons(_, _, head, tail, _)
}
cached
@@ -118,11 +120,14 @@ abstract class SplitKind extends TSplitKind {
}
/**
* Holds if this split kind should be included when constructing the control
* flow graph for callable `c`. For performance reasons, the number of splits
* is restricted by the `maxSplits()` predicate.
* Holds if this split kind is enabled for control flow element `cfe`. For
* performance reasons, the number of splits is restricted by the `maxSplits()`
* predicate.
*/
private predicate isEnabled(Callable c) { this.getRank(c) <= maxSplits() }
predicate isEnabled(ControlFlowElement cfe) {
this.appliesTo(cfe) and
this.getRank(cfe.getEnclosingCallable()) <= maxSplits()
}
/**
* Gets the rank of this split kind among all the split kinds that apply to
@@ -130,8 +135,7 @@ abstract class SplitKind extends TSplitKind {
* `getListOrder()`.
*/
int getListRank(ControlFlowElement cfe) {
this.appliesTo(cfe) and
this.isEnabled(cfe.getEnclosingCallable()) and
this.isEnabled(cfe) and
this = rank[result](SplitKind sk | sk.appliesTo(cfe) | sk order by sk.getListOrder())
}
@@ -153,6 +157,14 @@ abstract class SplitInternal extends SplitImpl {
*/
abstract predicate hasEntry(ControlFlowElement pred, ControlFlowElement succ, Completion c);
/**
* Holds if this split is entered when control passes from `c` to the entry point
* `succ`.
*
* Invariant: `hasEntry(c, succ) implies succ = Successor::succEntry(c)`.
*/
abstract predicate hasEntry(Callable c, ControlFlowElement succ);
/**
* Holds if this split is left when control passes from `pred` to `succ` with
* completion `c`.
@@ -163,11 +175,11 @@ abstract class SplitInternal extends SplitImpl {
/**
* Holds if this split is left when control passes from `pred` out of the enclosing
* callable with completion `c`.
* callable `result` with completion `c`.
*
* Invariant: `hasExit(pred, c) implies pred.getEnclosingCallable() = Successor::succExit(pred, c)`
* Invariant: `succ = hasExit(pred, c) implies succ = Successor::succExit(pred, c)`
*/
abstract predicate hasExit(ControlFlowElement pred, Completion c);
abstract Callable hasExit(ControlFlowElement pred, Completion c);
/**
* Holds if this split is maintained when control passes from `pred` to `succ` with
@@ -181,10 +193,186 @@ abstract class SplitInternal extends SplitImpl {
final predicate appliesTo(ControlFlowElement cfe) {
this.hasEntry(_, cfe, _)
or
this.hasEntry(_, cfe)
or
exists(ControlFlowElement pred | this.appliesTo(pred) | this.hasSuccessor(pred, cfe, _))
}
}
module InitializerSplitting {
private import semmle.code.csharp.ExprOrStmtParent
/**
* A non-static member with an initializer, for example a field `int Field = 0`.
*/
class InitializedInstanceMember extends Member {
private AssignExpr ae;
InitializedInstanceMember() {
not this.isStatic() and
if this instanceof Property
then expr_parent_top_level_adjusted(ae, 1, this)
else expr_parent_top_level_adjusted(ae, 0, this)
}
/** Gets the initializer expression. */
AssignExpr getInitializer() { result = ae }
/**
* Gets a control flow element that is a syntactic descendant of the
* initializer expression.
*/
ControlFlowElement getAnInitializerDescendant() {
result = ae
or
result = this.getAnInitializerDescendant().getAChild()
}
}
/**
* Holds if `c` is a non-static constructor that performs the initialization
* of member `m`.
*/
predicate constructorInitializes(Constructor c, InitializedInstanceMember m) {
c = c.getSourceDeclaration() and
not c.hasInitializer() and
not c.isStatic() and
c.getDeclaringType().hasMember(m)
}
/**
* Holds if `m` is the `i`th member initialized by non-static constructor `c`.
*/
predicate constructorInitializeOrder(Constructor c, InitializedInstanceMember m, int i) {
constructorInitializes(c, m) and
m = rank[i + 1](InitializedInstanceMember m0 |
constructorInitializes(c, m0)
|
m0
order by
m0.getLocation().getStartLine(), m0.getLocation().getStartColumn(),
m0.getLocation().getFile().getAbsolutePath()
)
}
/** Gets the last member initialized by non-static constructor `c`. */
InitializedInstanceMember lastConstructorInitializer(Constructor c) {
exists(int i |
constructorInitializeOrder(c, result, i) and
not constructorInitializeOrder(c, _, i + 1)
)
}
/**
* A split for non-static member initializers belonging to a given non-static
* constructor. For example, in
*
* ```
* class C
* {
* int Field1 = 0;
* int Field2 = Field1 + 1;
* int Field3;
*
* public C()
* {
* Field3 = 2;
* }
*
* public C(int i)
* {
* Field3 = 3;
* }
* }
* ```
*
* the initializer expressions `Field1 = 0` and `Field2 = Field1 + 1` are split
* on the two constructors. This is in order to generate CFGs for the two
* constructors that mimic
*
* ```
* public C()
* {
* Field1 = 0;
* Field2 = Field1 + 1;
* Field3 = 2;
* }
* ```
*
* and
*
* ```
* public C()
* {
* Field1 = 0;
* Field2 = Field1 + 1;
* Field3 = 3;
* }
* ```
*
* respectively.
*/
class InitializerSplitImpl extends SplitImpl, TInitializerSplit {
private Constructor c;
InitializerSplitImpl() { this = TInitializerSplit(c) }
/** Gets the constructor. */
Constructor getConstructor() { result = c }
override string toString() { result = "" }
}
private class InitializerSplitKind extends SplitKind, TInitializerSplitKind {
override int getListOrder() { result = 0 }
override predicate isEnabled(ControlFlowElement cfe) { this.appliesTo(cfe) }
override string toString() { result = "Initializer" }
}
int getNextListOrder() { result = 1 }
private class InitializerSplitInternal extends SplitInternal, InitializerSplitImpl {
override InitializerSplitKind getKind() { any() }
override predicate hasEntry(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
none()
}
override predicate hasEntry(Callable c, ControlFlowElement succ) {
succ = succEntry(c) and
c = this.getConstructor() and
succ = any(InitializedInstanceMember m).getAnInitializerDescendant()
}
override predicate hasExit(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
this.appliesTo(pred) and
succ = succ(pred, c) and
not succ = any(InitializedInstanceMember m).getAnInitializerDescendant() and
succ.getEnclosingCallable() = this.getConstructor()
}
override Callable hasExit(ControlFlowElement pred, Completion c) {
this.appliesTo(pred) and
result = succExit(pred, c) and
result = this.getConstructor()
}
override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
this.appliesTo(pred) and
succ = succ(pred, c) and
succ = any(InitializedInstanceMember m).getAnInitializerDescendant()
}
}
}
pragma[noinline]
private ControlFlowElement getAChild(ControlFlowElement cfe, Callable c) {
result = cfe.getAChild() and
c = result.getEnclosingCallable()
}
module FinallySplitting {
/**
* The type of a split `finally` node.
@@ -208,12 +396,6 @@ module FinallySplitting {
}
}
pragma[noinline]
private ControlFlowElement getAChild(ControlFlowElement cfe, Callable c) {
result = cfe.getAChild() and
c = result.getEnclosingCallable()
}
/**
* Gets a descendant that belongs to the `finally` block of try statement
* `try`.
@@ -294,11 +476,13 @@ module FinallySplitting {
}
private class FinallySplitKind extends SplitKind, TFinallySplitKind {
override int getListOrder() { result = 0 }
override int getListOrder() { result = InitializerSplitting::getNextListOrder() }
override string toString() { result = "Finally" }
}
int getNextListOrder() { result = InitializerSplitting::getNextListOrder() + 1 }
private class FinallySplitInternal extends SplitInternal, FinallySplitImpl {
override FinallySplitKind getKind() { any() }
@@ -316,6 +500,8 @@ module FinallySplitting {
)
}
override predicate hasEntry(Callable c, ControlFlowElement succ) { none() }
/**
* Holds if this split applies to control flow element `pred`, where `pred`
* is a valid predecessor.
@@ -366,8 +552,8 @@ module FinallySplitting {
)
}
override predicate hasExit(ControlFlowElement pred, Completion c) {
exists(succExit(pred, c)) and
override Callable hasExit(ControlFlowElement pred, Completion c) {
result = succExit(pred, c) and
(
exit(pred, c)
or
@@ -445,11 +631,13 @@ module ExceptionHandlerSplitting {
}
private class ExceptionHandlerSplitKind extends SplitKind, TExceptionHandlerSplitKind {
override int getListOrder() { result = 1 }
override int getListOrder() { result = FinallySplitting::getNextListOrder() }
override string toString() { result = "ExceptionHandler" }
}
int getNextListOrder() { result = FinallySplitting::getNextListOrder() + 1 }
private class ExceptionHandlerSplitInternal extends SplitInternal, ExceptionHandlerSplitImpl {
override ExceptionHandlerSplitKind getKind() { any() }
@@ -461,6 +649,8 @@ module ExceptionHandlerSplitting {
)
}
override predicate hasEntry(Callable c, ControlFlowElement succ) { none() }
/**
* Holds if this split applies to catch clause `scc`. The parameter `match`
* indicates whether the catch clause `scc` may match the exception type of
@@ -539,10 +729,10 @@ module ExceptionHandlerSplitting {
)
}
override predicate hasExit(ControlFlowElement pred, Completion c) {
override Callable hasExit(ControlFlowElement pred, Completion c) {
// Exit out from last `catch` clause (no catch clauses match)
this.hasLastExit(pred, c) and
exists(succExit(pred, c))
result = succExit(pred, c)
}
override predicate hasSuccessor(ControlFlowElement pred, ControlFlowElement succ, Completion c) {
@@ -720,6 +910,27 @@ module BooleanSplitting {
}
}
private int getListOrder(BooleanSplitSubKind kind) {
exists(Callable c, int r | c = kind.getEnclosingCallable() |
result = r + ExceptionHandlerSplitting::getNextListOrder() - 1 and
kind = rank[r](BooleanSplitSubKind kind0 |
kind0.getEnclosingCallable() = c and
kind0.startsSplit(_)
|
kind0
order by
kind0.getLocation().getStartLine(), kind0.getLocation().getStartColumn(),
kind0.toString()
)
)
}
int getNextListOrder() {
result = max(int i |
i = getListOrder(_) + 1 or i = ExceptionHandlerSplitting::getNextListOrder()
)
}
private class BooleanSplitKind extends SplitKind, TBooleanSplitKind {
private BooleanSplitSubKind kind;
@@ -728,20 +939,7 @@ module BooleanSplitting {
/** Gets the sub kind of this Boolean split kind. */
BooleanSplitSubKind getSubKind() { result = kind }
override int getListOrder() {
exists(Callable c, int r | c = kind.getEnclosingCallable() |
result = r + 1 and // start the ordering from 2
kind = rank[r](BooleanSplitSubKind kind0 |
kind0.getEnclosingCallable() = c and
kind0.startsSplit(_)
|
kind0
order by
kind0.getLocation().getStartLine(), kind0.getLocation().getStartColumn(),
kind0.toString()
)
)
}
override int getListOrder() { result = getListOrder(kind) }
override string toString() { result = kind.toString() }
}
@@ -755,6 +953,8 @@ module BooleanSplitting {
this.getBranch() = c.getInnerCompletion().(BooleanCompletion).getValue()
}
override predicate hasEntry(Callable c, ControlFlowElement succ) { none() }
private ConditionBlock getACorrelatedCondition(boolean inverted) {
this.getSubKind().correlatesConditions(_, result, inverted)
}
@@ -787,10 +987,10 @@ module BooleanSplitting {
)
}
override predicate hasExit(ControlFlowElement pred, Completion c) {
override Callable hasExit(ControlFlowElement pred, Completion c) {
exists(PreBasicBlock bb | this.appliesToBlock(bb, c) |
pred = bb.getLastElement() and
exists(succExit(pred, c))
result = succExit(pred, c)
)
}
@@ -830,6 +1030,26 @@ class Splits extends TSplits {
}
}
private predicate succEntrySplitsFromRank(
@top_level_exprorstmt_parent pred, ControlFlowElement succ, Splits splits, int rnk
) {
splits = TSplitsNil() and
succ = succEntry(pred) and
rnk = 0
or
exists(SplitInternal head, Splits tail | succEntrySplitsCons(pred, succ, head, tail, rnk) |
splits = TSplitsCons(head, tail)
)
}
private predicate succEntrySplitsCons(
Callable pred, ControlFlowElement succ, SplitInternal head, Splits tail, int rnk
) {
succEntrySplitsFromRank(pred, succ, tail, rnk - 1) and
head.hasEntry(pred, succ) and
rnk = head.getKind().getListRank(succ)
}
/**
* Holds if `succ` with splits `succSplits` is the first element that is executed
* when entering callable `pred`.
@@ -838,9 +1058,16 @@ pragma[noinline]
predicate succEntrySplits(
@top_level_exprorstmt_parent pred, ControlFlowElement succ, Splits succSplits, SuccessorType t
) {
succ = succEntry(pred) and
t instanceof NormalSuccessor and
succSplits = TSplitsNil() // initially no splits
exists(int rnk |
succ = succEntry(pred) and
t instanceof NormalSuccessor and
succEntrySplitsFromRank(pred, succ, succSplits, rnk)
|
rnk = 0 and
not any(SplitInternal split).hasEntry(pred, succ)
or
rnk = max(SplitInternal split | split.hasEntry(pred, succ) | split.getKind().getListRank(succ))
)
}
/**
@@ -853,7 +1080,7 @@ predicate succExitSplits(ControlFlowElement pred, Splits predSplits, Callable su
t.matchesCompletion(c) and
succ = succExit(pred, c) and
forall(SplitInternal predSplit | predSplit = predSplits.getASplit() |
predSplit.hasExit(pred, c)
succ = predSplit.hasExit(pred, c)
)
)
}

View File

@@ -3,7 +3,6 @@ private import cil
private import dotnet
private import DataFlowPrivate
private import DelegateDataFlow
private import semmle.code.csharp.ExprOrStmtParent
private import semmle.code.csharp.dispatch.Dispatch
private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.frameworks.system.collections.Generic
@@ -87,14 +86,6 @@ private module Cached {
)
}
cached
newtype TDataFlowCallable =
TDotNetCallable(DotNet::Callable c) or
TSynthesizedCallable(ControlFlowEntryElement cfee) {
not cfee instanceof Callable and
expr_parent_top_level_adjusted(_, _, cfee)
}
cached
newtype TDataFlowCall =
TNonDelegateCall(ControlFlow::Nodes::ElementNode cfn, DispatchCall dc) {
@@ -112,15 +103,6 @@ private module Cached {
TCilCall(CIL::Call call) {
// No need to include calls that are compiled from source
not call.getImplementation().getMethod().compiledFromSource()
} or
TSynthesizedCall(Constructor c) {
not c.hasInitializer() and
not c.isStatic() and
exists(SynthesizedCallable sc, ControlFlowEntryElement cfee |
cfee = sc.getElement() and
not cfee.(Modifiable).isStatic() and
c.getDeclaringType().hasMember(cfee)
)
}
/** Gets a viable run-time target for the call `call`. */
@@ -148,8 +130,8 @@ private module Cached {
)
}
private DotNetCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
exists(ArgumentCallContext cc | result = TDotNetCallable(viableDelegateCallable(call, cc)) |
private DotNet::Callable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
exists(ArgumentCallContext cc | result = viableDelegateCallable(call, cc) |
cc.isArgument(ctx.getExpr(), _)
)
}
@@ -160,7 +142,7 @@ private module Cached {
* might make a difference.
*/
cached
DotNetCallable prunedViableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
DotNet::Callable prunedViableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
result = viableImplInCallContext(call, ctx) and
reducedViableImplInCallContext(call, _, ctx)
}
@@ -303,68 +285,7 @@ class ImplicitCapturedReturnKind extends ReturnKind, TImplicitCapturedReturnKind
override string toString() { result = "captured " + v }
}
/** A callable relevant for data flow. */
abstract class DataFlowCallable extends TDataFlowCallable {
/** Gets the underlying callable, if any. */
DotNet::Callable getCallable() { none() }
/** Gets the entry element that this callable represents, if any. */
abstract ControlFlowEntryElement getElement();
/** Gets the type in which this callable is declared. */
abstract DotNet::Type getDeclaringType();
/** Gets a textual representation of this callable. */
abstract string toString();
/** Gets the location of this callable. */
abstract Location getLocation();
}
/** An "actual" callable. */
class DotNetCallable extends DataFlowCallable, TDotNetCallable {
private DotNet::Callable c;
DotNetCallable() { this = TDotNetCallable(c) }
override Callable getElement() { result = c }
override DotNet::Callable getCallable() { result = c }
override DotNet::Type getDeclaringType() { result = c.getDeclaringType() }
override string toString() { result = c.toString() }
override Location getLocation() { result = c.getLocation() }
}
/**
* A synthesized callable. For example, in
*
* ```
* class C
* {
* int Field = 0;
* C() { }
* }
* ```
*
* we synthesize a callable for the initializer expression `Field = 0` (with an
* implicit `this` parameter), as well as a synthesized call from the constructor.
*/
class SynthesizedCallable extends DataFlowCallable, TSynthesizedCallable {
private ControlFlowEntryElement cfee;
SynthesizedCallable() { this = TSynthesizedCallable(cfee) }
override ControlFlowEntryElement getElement() { result = cfee }
override Type getDeclaringType() { result = cfee.(Declaration).getDeclaringType() }
override string toString() { result = "[synthesized] " + cfee.toString() }
override Location getLocation() { result = cfee.getLocation() }
}
class DataFlowCallable = DotNet::Callable;
/** A call relevant for data flow. */
abstract class DataFlowCall extends TDataFlowCall {
@@ -405,17 +326,15 @@ class NonDelegateDataFlowCall extends DataFlowCall, TNonDelegateCall {
NonDelegateDataFlowCall() { this = TNonDelegateCall(cfn, dc) }
override DotNetCallable getARuntimeTarget() {
result = TDotNetCallable(getCallableForDataFlow(dc.getADynamicTarget()))
override DotNet::Callable getARuntimeTarget() {
result = getCallableForDataFlow(dc.getADynamicTarget())
}
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
override DataFlow::ExprNode getNode() { result.getControlFlowNode() = cfn }
override DotNetCallable getEnclosingCallable() {
result.getCallable() = cfn.getEnclosingCallable()
}
override DotNet::Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override string toString() { result = cfn.toString() }
@@ -427,9 +346,7 @@ abstract class DelegateDataFlowCall extends DataFlowCall {
/** Gets a viable run-time target of this call requiring call context `cc`. */
abstract DotNet::Callable getARuntimeTarget(CallContext::CallContext cc);
override DotNetCallable getARuntimeTarget() {
result = TDotNetCallable(this.getARuntimeTarget(_))
}
override DotNet::Callable getARuntimeTarget() { result = this.getARuntimeTarget(_) }
}
/** An explicit delegate call relevant for data flow. */
@@ -448,9 +365,7 @@ class ExplicitDelegateDataFlowCall extends DelegateDataFlowCall, TExplicitDelega
override DataFlow::ExprNode getNode() { result.getControlFlowNode() = cfn }
override DotNetCallable getEnclosingCallable() {
result.getCallable() = cfn.getEnclosingCallable()
}
override DotNet::Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override string toString() { result = cfn.toString() }
@@ -489,9 +404,7 @@ class ImplicitDelegateDataFlowCall extends DelegateDataFlowCall, TImplicitDelega
override ImplicitDelegateOutNode getNode() { result.getControlFlowNode() = cfn }
override DotNetCallable getEnclosingCallable() {
result.getCallable() = cfn.getEnclosingCallable()
}
override DotNet::Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override string toString() { result = "[implicit call] " + cfn.toString() }
@@ -508,17 +421,13 @@ class TransitiveCapturedDataFlowCall extends DataFlowCall, TTransitiveCapturedCa
TransitiveCapturedDataFlowCall() { this = TTransitiveCapturedCall(cfn) }
override DotNetCallable getARuntimeTarget() {
transitiveCapturedCallTarget(cfn, result.getCallable())
}
override DotNet::Callable getARuntimeTarget() { transitiveCapturedCallTarget(cfn, result) }
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }
override DataFlow::ExprNode getNode() { none() }
override DotNetCallable getEnclosingCallable() {
result.getCallable() = cfn.getEnclosingCallable()
}
override DotNet::Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override string toString() { result = "[transitive] " + cfn.toString() }
@@ -531,58 +440,18 @@ class CilDataFlowCall extends DataFlowCall, TCilCall {
CilDataFlowCall() { this = TCilCall(call) }
override DotNetCallable getARuntimeTarget() {
override DotNet::Callable getARuntimeTarget() {
// There is no dispatch library for CIL, so do not consider overrides for now
result = TDotNetCallable(getCallableForDataFlow(call.getTarget()))
result = getCallableForDataFlow(call.getTarget())
}
override ControlFlow::Nodes::ElementNode getControlFlowNode() { none() }
override DataFlow::ExprNode getNode() { result.getExpr() = call }
override DotNetCallable getEnclosingCallable() {
result.getCallable() = call.getEnclosingCallable()
}
override DotNet::Callable getEnclosingCallable() { result = call.getEnclosingCallable() }
override string toString() { result = call.toString() }
override Location getLocation() { result = call.getLocation() }
}
/**
* A synthesized call. For example, in
*
* ```
* class C
* {
* int Field = 0;
* C() { }
* }
* ```
*
* we synthesize a call from the constructor `C` to the (synthesized) callable
* for the initializer expression `Field = 0`.
*/
class SynthesizedCall extends DataFlowCall, TSynthesizedCall {
private Constructor c;
SynthesizedCall() { this = TSynthesizedCall(c) }
/** Gets the constructor in which this call is synthesized. */
Constructor getConstructor() { result = c }
override SynthesizedCallable getARuntimeTarget() {
// "abuse" virtual dispatch to generate a call edge to each of the members
c.getDeclaringType().hasMember(result.getElement())
}
override ControlFlow::Nodes::ElementNode getControlFlowNode() { none() }
override DataFlow::Node getNode() { none() }
override DotNetCallable getEnclosingCallable() { result.getCallable() = c }
override string toString() { result = "[synthesized call] " + c }
override Location getLocation() { result = c.getLocation() }
}

View File

@@ -19,16 +19,11 @@ private module ThisFlow {
/** Holds if the `i`th node `n` of basic block `bb` is a `this` access. */
private predicate thisAccess(Node n, BasicBlock bb, int i) {
bb.getNode(i + 1) = any(ControlFlow::Nodes::EntryNode en |
n.(InstanceParameterNode).getCallable().getElement() = en.getEnclosingElement()
bb.getNode(i) = any(ControlFlow::Nodes::EntryNode en |
n.(InstanceParameterNode).getCallable() = en.getEnclosingCallable()
)
or
n.asExprAtNode(bb.getNode(i)) = any(Expr e | e instanceof ThisAccess or e instanceof BaseAccess)
or
bb = any(ControlFlow::BasicBlocks::EntryBlock eb |
eb.getCallable() = n.(SynthesizedThisArgumentNode).getEnclosingCallable().getCallable() and
i = 0
)
}
private predicate thisRank(Node n, BasicBlock bb, int rankix) {
@@ -284,11 +279,7 @@ private module Cached {
} or
TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or
TSsaDefinitionNode(Ssa::Definition def) or
TInstanceParameterNode(DataFlowCallable dfc) {
exists(Callable c | c = dfc.getCallable() | c.hasBody() and not c.(Modifiable).isStatic())
or
dfc = any(SynthesizedCallable c | not c.getElement().(Modifiable).isStatic())
} or
TInstanceParameterNode(Callable c) { c.hasBody() and not c.(Modifiable).isStatic() } or
TCilParameterNode(CIL::Parameter p) { p.getMethod().hasBody() } or
TTaintedParameterNode(Parameter p) { p.getCallable().hasBody() } or
TTaintedReturnNode(ControlFlow::Nodes::ElementNode cfn) {
@@ -306,8 +297,6 @@ private module Cached {
any(DelegateArgumentConfiguration x).hasExprPath(_, cfn, _, call)
} or
TMallocNode(ControlFlow::Nodes::ElementNode cfn) { cfn.getElement() instanceof ObjectCreation } or
TSynthesizedThisArgumentNode(SynthesizedCall sc) or
TSynthesizedThisArgumentPostCallNode(SynthesizedCall sc) or
TArgumentPostCallNode(ControlFlow::Nodes::ElementNode cfn) {
exists(Argument a, Type t |
a = cfn.getElement() and
@@ -429,9 +418,7 @@ class SsaDefinitionNode extends Node, TSsaDefinitionNode {
/** Gets the underlying SSA definition. */
Ssa::Definition getDefinition() { result = def }
override DotNetCallable getEnclosingCallable() {
result.getCallable() = def.getEnclosingCallable()
}
override Callable getEnclosingCallable() { result = def.getEnclosingCallable() }
override Type getType() { result = def.getSourceVariable().getType() }
@@ -470,13 +457,9 @@ private module ParameterNodes {
override DotNet::Parameter getParameter() { result = parameter }
override predicate isParameterOf(DataFlowCallable c, int i) {
c.getCallable().getParameter(i) = parameter
}
override predicate isParameterOf(DataFlowCallable c, int i) { c.getParameter(i) = parameter }
override DotNetCallable getEnclosingCallable() {
result.getCallable() = parameter.getCallable()
}
override DotNet::Callable getEnclosingCallable() { result = parameter.getCallable() }
override DotNet::Type getType() { result = parameter.getType() }
@@ -522,15 +505,13 @@ private module ParameterNodes {
// as that would otherwise enable tainted parameters to accidentally be
// used by users of the library
override predicate isParameterOf(DataFlowCallable c, int i) {
exists(DotNet::Callable dnc | dnc = c.getCallable() |
dnc = parameter.getCallable() and
// we model tainted parameters as if they had been extra parameters after
// the actual parameters
i = parameter.getPosition() + dnc.getNumberOfParameters()
)
c = parameter.getCallable() and
// we model tainted parameters as if they had been extra parameters after
// the actual parameters
i = parameter.getPosition() + c.getNumberOfParameters()
}
override DotNetCallable getEnclosingCallable() {
override DotNet::Callable getEnclosingCallable() {
result = this.getUnderlyingNode().getEnclosingCallable()
}
@@ -774,9 +755,7 @@ private module ArgumentNodes {
)
}
override DotNetCallable getEnclosingCallable() {
result.getCallable() = cfn.getEnclosingCallable()
}
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override Type getType() { result = v.getType() }
@@ -801,9 +780,7 @@ private module ArgumentNodes {
override ControlFlow::Node getControlFlowNode() { result = cfn }
override DotNetCallable getEnclosingCallable() {
result.getCallable() = cfn.getEnclosingCallable()
}
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override Type getType() { result = cfn.getElement().(Expr).getType() }
@@ -811,42 +788,6 @@ private module ArgumentNodes {
override string toString() { result = "malloc" }
}
/**
* A synthesized `this` argument in a synthesized call. For example, in
*
* ```
* class C
* {
* int Field = 0;
* C() { }
* }
* ```
*
* we synthesize a `this` argument for the synthesized call from the
* constructor `C` to the (synthesized) callable for the initializer
* expression `Field = 0`.
*/
class SynthesizedThisArgumentNode extends ArgumentNode, TSynthesizedThisArgumentNode {
private SynthesizedCall sc;
SynthesizedThisArgumentNode() { this = TSynthesizedThisArgumentNode(sc) }
override predicate argumentOf(DataFlowCall call, int pos) {
call = sc and
pos = -1
}
override ControlFlow::Node getControlFlowNode() { none() }
override DotNetCallable getEnclosingCallable() { result = sc.getEnclosingCallable() }
override Type getType() { result = sc.getConstructor().getDeclaringType() }
override Location getLocation() { result = sc.getLocation() }
override string toString() { result = "[implicit] this access" }
}
}
import ArgumentNodes
@@ -911,7 +852,7 @@ private module ReturnNodes {
override YieldReturnKind getKind() { any() }
override DotNetCallable getEnclosingCallable() {
override DotNet::Callable getEnclosingCallable() {
result = this.getUnderlyingNode().getEnclosingCallable()
}
@@ -1060,9 +1001,7 @@ private module OutNodes {
override ImplicitDelegateDataFlowCall getCall() { result.getNode() = this }
override DotNetCallable getEnclosingCallable() {
result.getCallable() = cfn.getEnclosingCallable()
}
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override Type getType() { result = cfn.getElement().(Expr).getType() }
@@ -1311,21 +1250,14 @@ private module PostUpdateNodes {
override MallocNode getPreUpdateNode() { this = TExprNode(result.getControlFlowNode()) }
}
/** A `PostUpdateNode` that is not an `ObjectCreation`. */
abstract private class ImplicitPostUpdateNode extends PostUpdateNode { }
private class ArgumentPostCallNode extends ImplicitPostUpdateNode, TArgumentPostCallNode {
private class ArgumentPostCallNode extends PostUpdateNode, TArgumentPostCallNode {
private ControlFlow::Nodes::ElementNode cfn;
ArgumentPostCallNode() { this = TArgumentPostCallNode(cfn) }
override ExprNode getPreUpdateNode() { cfn = result.getControlFlowNode() }
override DataFlowCallable getEnclosingCallable() {
result.(DotNetCallable).getCallable() = cfn.getEnclosingCallable()
or
result.(SynthesizedCallable).getElement() = cfn.getEnclosingElement()
}
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override Type getType() { result = cfn.getElement().(Expr).getType() }
@@ -1334,39 +1266,14 @@ private module PostUpdateNodes {
override string toString() { result = "[post] " + cfn.toString() }
}
private class SynthesizedThisArgumentPostCallNode extends PostUpdateNode,
TSynthesizedThisArgumentPostCallNode {
private SynthesizedCall sc;
SynthesizedThisArgumentPostCallNode() { this = TSynthesizedThisArgumentPostCallNode(sc) }
override SynthesizedThisArgumentNode getPreUpdateNode() {
result = TSynthesizedThisArgumentNode(sc)
}
override DataFlowCallable getEnclosingCallable() {
result = this.getPreUpdateNode().getEnclosingCallable()
}
override Type getType() { result = this.getPreUpdateNode().getType() }
override Location getLocation() { result = this.getPreUpdateNode().getLocation() }
override string toString() { result = "[post implicit] this access" }
}
private class StoreTargetNode extends ImplicitPostUpdateNode, TStoreTargetNode {
private class StoreTargetNode extends PostUpdateNode, TStoreTargetNode {
private ControlFlow::Nodes::ElementNode cfn;
StoreTargetNode() { this = TStoreTargetNode(cfn) }
override ExprNode getPreUpdateNode() { cfn = result.getControlFlowNode() }
override DataFlowCallable getEnclosingCallable() {
result.getCallable() = cfn.getEnclosingCallable()
or
result.(SynthesizedCallable).getElement() = cfn.getEnclosingElement()
}
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override Type getType() { result = cfn.getElement().(Expr).getType() }

View File

@@ -91,7 +91,7 @@ class ExprNode extends Node {
override DataFlowCallable getEnclosingCallable() {
Stages::DataFlowStage::forceCachingInSameStage() and
result.getCallable() = this.getExpr().getEnclosingCallable()
result = this.getExpr().getEnclosingCallable()
}
override ControlFlow::Nodes::ElementNode getControlFlowNode() {

View File

@@ -276,14 +276,14 @@ private predicate flowIntoDelegateCall(DelegateCall call, Callable c, Expr arg,
pragma[noinline]
private predicate flowOutOfNonDelegateCall(NonDelegateCall call, NormalReturnNode ret) {
call.getARuntimeTarget() = ret.getEnclosingCallable().getCallable()
call.getARuntimeTarget() = ret.getEnclosingCallable()
}
pragma[noinline]
private predicate flowOutOfDelegateCall(DelegateCall dc, NormalReturnNode ret, CallContext lastCall) {
exists(DelegateFlowSource dfs, DelegateCallExpr dce, Callable c |
flowsFrom(dce, dfs, _, lastCall) and
ret.getEnclosingCallable().getCallable() = c and
ret.getEnclosingCallable() = c and
c = dfs.getCallable() and
dc = dce.getDelegateCall()
)

View File

@@ -277,11 +277,11 @@
| Foreach.cs:36:10:36:11 | exit M6 | Foreach.cs:36:10:36:11 | exit M6 | 1 |
| Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | 1 |
| Foreach.cs:38:26:38:26 | String x | Foreach.cs:39:11:39:11 | ; | 4 |
| Initializers.cs:3:9:3:9 | this access | Initializers.cs:3:9:3:17 | ... = ... | 5 |
| Initializers.cs:4:9:4:9 | this access | Initializers.cs:4:25:4:31 | ... = ... | 6 |
| Initializers.cs:6:5:6:16 | enter Initializers | Initializers.cs:6:5:6:16 | exit Initializers | 3 |
| Initializers.cs:8:10:8:10 | enter M | Initializers.cs:8:10:8:10 | exit M | 20 |
| Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:16:14:20 | ... = ... | 2 |
| Initializers.cs:6:5:6:16 | enter Initializers | Initializers.cs:6:5:6:16 | exit Initializers | 14 |
| Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:8:5:8:16 | exit Initializers | 14 |
| Initializers.cs:10:10:10:10 | enter M | Initializers.cs:10:10:10:10 | exit M | 20 |
| Initializers.cs:16:20:16:20 | 1 | Initializers.cs:16:16:16:20 | ... = ... | 2 |
| Initializers.cs:18:11:18:23 | enter NoConstructor | Initializers.cs:18:11:18:23 | exit NoConstructor | 8 |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:23:3:23 | access to parameter i | 3 |
| NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:9:3:10 | exit M1 | 1 |
| NullCoalescing.cs:3:28:3:28 | 0 | NullCoalescing.cs:3:28:3:28 | 0 | 1 |

View File

@@ -564,11 +564,11 @@
| post | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... |
| post | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | Foreach.cs:38:26:38:26 | String x |
| post | Foreach.cs:38:26:38:26 | String x | Foreach.cs:38:26:38:26 | String x |
| post | Initializers.cs:3:9:3:9 | this access | Initializers.cs:3:9:3:9 | this access |
| post | Initializers.cs:4:9:4:9 | this access | Initializers.cs:4:9:4:9 | this access |
| post | Initializers.cs:6:5:6:16 | enter Initializers | Initializers.cs:6:5:6:16 | enter Initializers |
| post | Initializers.cs:8:10:8:10 | enter M | Initializers.cs:8:10:8:10 | enter M |
| post | Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:20:14:20 | 1 |
| post | Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:8:5:8:16 | enter Initializers |
| post | Initializers.cs:10:10:10:10 | enter M | Initializers.cs:10:10:10:10 | enter M |
| post | Initializers.cs:16:20:16:20 | 1 | Initializers.cs:16:20:16:20 | 1 |
| post | Initializers.cs:18:11:18:23 | enter NoConstructor | Initializers.cs:18:11:18:23 | enter NoConstructor |
| post | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | enter M1 |
| post | NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:9:3:10 | enter M1 |
| post | NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:9:3:10 | exit M1 |
@@ -2111,11 +2111,11 @@
| pre | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... |
| pre | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | Foreach.cs:38:26:38:26 | String x |
| pre | Foreach.cs:38:26:38:26 | String x | Foreach.cs:38:26:38:26 | String x |
| pre | Initializers.cs:3:9:3:9 | this access | Initializers.cs:3:9:3:9 | this access |
| pre | Initializers.cs:4:9:4:9 | this access | Initializers.cs:4:9:4:9 | this access |
| pre | Initializers.cs:6:5:6:16 | enter Initializers | Initializers.cs:6:5:6:16 | enter Initializers |
| pre | Initializers.cs:8:10:8:10 | enter M | Initializers.cs:8:10:8:10 | enter M |
| pre | Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:20:14:20 | 1 |
| pre | Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:8:5:8:16 | enter Initializers |
| pre | Initializers.cs:10:10:10:10 | enter M | Initializers.cs:10:10:10:10 | enter M |
| pre | Initializers.cs:16:20:16:20 | 1 | Initializers.cs:16:20:16:20 | 1 |
| pre | Initializers.cs:18:11:18:23 | enter NoConstructor | Initializers.cs:18:11:18:23 | enter NoConstructor |
| pre | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | enter M1 |
| pre | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:9:3:10 | exit M1 |
| pre | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:28:3:28 | 0 |

View File

@@ -1203,37 +1203,59 @@
| post | Foreach.cs:38:33:38:33 | Int32 y | Foreach.cs:38:26:38:26 | String x |
| post | Foreach.cs:38:39:38:42 | access to parameter args | Foreach.cs:37:5:40:5 | {...} |
| post | Foreach.cs:39:11:39:11 | ; | Foreach.cs:38:18:38:34 | (..., ...) |
| post | Initializers.cs:3:9:3:9 | this access | Initializers.cs:6:5:6:16 | enter Initializers |
| post | Initializers.cs:3:9:3:9 | this access | Initializers.cs:8:5:8:16 | enter Initializers |
| post | Initializers.cs:3:9:3:17 | ... = ... | Initializers.cs:3:13:3:17 | ... + ... |
| post | Initializers.cs:3:9:3:17 | ... = ... | Initializers.cs:3:13:3:17 | ... + ... |
| post | Initializers.cs:3:13:3:13 | access to field H | Initializers.cs:3:9:3:9 | this access |
| post | Initializers.cs:3:13:3:13 | access to field H | Initializers.cs:3:9:3:9 | this access |
| post | Initializers.cs:3:13:3:17 | ... + ... | Initializers.cs:3:17:3:17 | 1 |
| post | Initializers.cs:3:13:3:17 | ... + ... | Initializers.cs:3:17:3:17 | 1 |
| post | Initializers.cs:3:17:3:17 | 1 | Initializers.cs:3:13:3:13 | access to field H |
| post | Initializers.cs:3:17:3:17 | 1 | Initializers.cs:3:13:3:13 | access to field H |
| post | Initializers.cs:4:9:4:9 | access to property G | Initializers.cs:4:27:4:31 | ... + ... |
| post | Initializers.cs:4:9:4:9 | access to property G | Initializers.cs:4:27:4:31 | ... + ... |
| post | Initializers.cs:4:9:4:9 | this access | Initializers.cs:3:9:3:17 | ... = ... |
| post | Initializers.cs:4:9:4:9 | this access | Initializers.cs:3:9:3:17 | ... = ... |
| post | Initializers.cs:4:25:4:31 | ... = ... | Initializers.cs:4:9:4:9 | access to property G |
| post | Initializers.cs:4:25:4:31 | ... = ... | Initializers.cs:4:9:4:9 | access to property G |
| post | Initializers.cs:4:27:4:27 | access to field H | Initializers.cs:4:9:4:9 | this access |
| post | Initializers.cs:4:27:4:27 | access to field H | Initializers.cs:4:9:4:9 | this access |
| post | Initializers.cs:4:27:4:31 | ... + ... | Initializers.cs:4:31:4:31 | 2 |
| post | Initializers.cs:4:27:4:31 | ... + ... | Initializers.cs:4:31:4:31 | 2 |
| post | Initializers.cs:4:31:4:31 | 2 | Initializers.cs:4:27:4:27 | access to field H |
| post | Initializers.cs:6:5:6:16 | exit Initializers | Initializers.cs:6:28:6:30 | {...} |
| post | Initializers.cs:6:28:6:30 | {...} | Initializers.cs:6:5:6:16 | enter Initializers |
| post | Initializers.cs:8:10:8:10 | exit M | Initializers.cs:11:13:11:63 | Initializers[] iz = ... |
| post | Initializers.cs:9:5:12:5 | {...} | Initializers.cs:8:10:8:10 | enter M |
| post | Initializers.cs:10:9:10:54 | ... ...; | Initializers.cs:9:5:12:5 | {...} |
| post | Initializers.cs:10:13:10:53 | Initializers i = ... | Initializers.cs:10:38:10:53 | { ..., ... } |
| post | Initializers.cs:10:17:10:53 | object creation of type Initializers | Initializers.cs:10:34:10:35 | "" |
| post | Initializers.cs:10:34:10:35 | "" | Initializers.cs:10:9:10:54 | ... ...; |
| post | Initializers.cs:10:38:10:53 | { ..., ... } | Initializers.cs:10:47:10:51 | ... = ... |
| post | Initializers.cs:10:40:10:44 | ... = ... | Initializers.cs:10:44:10:44 | 0 |
| post | Initializers.cs:10:44:10:44 | 0 | Initializers.cs:10:17:10:53 | object creation of type Initializers |
| post | Initializers.cs:10:47:10:47 | access to property G | Initializers.cs:10:51:10:51 | 1 |
| post | Initializers.cs:10:47:10:51 | ... = ... | Initializers.cs:10:47:10:47 | access to property G |
| post | Initializers.cs:10:51:10:51 | 1 | Initializers.cs:10:40:10:44 | ... = ... |
| post | Initializers.cs:11:9:11:64 | ... ...; | Initializers.cs:10:13:10:53 | Initializers i = ... |
| post | Initializers.cs:11:13:11:63 | Initializers[] iz = ... | Initializers.cs:11:37:11:63 | { ..., ... } |
| post | Initializers.cs:11:18:11:63 | array creation of type Initializers[] | Initializers.cs:11:9:11:64 | ... ...; |
| post | Initializers.cs:11:37:11:63 | { ..., ... } | Initializers.cs:11:42:11:61 | object creation of type Initializers |
| post | Initializers.cs:11:39:11:39 | access to local variable i | Initializers.cs:11:18:11:63 | array creation of type Initializers[] |
| post | Initializers.cs:11:42:11:61 | object creation of type Initializers | Initializers.cs:11:59:11:60 | "" |
| post | Initializers.cs:11:59:11:60 | "" | Initializers.cs:11:39:11:39 | access to local variable i |
| post | Initializers.cs:14:16:14:20 | ... = ... | Initializers.cs:14:20:14:20 | 1 |
| post | Initializers.cs:4:31:4:31 | 2 | Initializers.cs:4:27:4:27 | access to field H |
| post | Initializers.cs:6:5:6:16 | exit Initializers | Initializers.cs:6:20:6:22 | {...} |
| post | Initializers.cs:6:20:6:22 | {...} | Initializers.cs:4:25:4:31 | ... = ... |
| post | Initializers.cs:8:5:8:16 | exit Initializers | Initializers.cs:8:28:8:30 | {...} |
| post | Initializers.cs:8:28:8:30 | {...} | Initializers.cs:4:25:4:31 | ... = ... |
| post | Initializers.cs:10:10:10:10 | exit M | Initializers.cs:13:13:13:63 | Initializers[] iz = ... |
| post | Initializers.cs:11:5:14:5 | {...} | Initializers.cs:10:10:10:10 | enter M |
| post | Initializers.cs:12:9:12:54 | ... ...; | Initializers.cs:11:5:14:5 | {...} |
| post | Initializers.cs:12:13:12:53 | Initializers i = ... | Initializers.cs:12:38:12:53 | { ..., ... } |
| post | Initializers.cs:12:17:12:53 | object creation of type Initializers | Initializers.cs:12:34:12:35 | "" |
| post | Initializers.cs:12:34:12:35 | "" | Initializers.cs:12:9:12:54 | ... ...; |
| post | Initializers.cs:12:38:12:53 | { ..., ... } | Initializers.cs:12:47:12:51 | ... = ... |
| post | Initializers.cs:12:40:12:44 | ... = ... | Initializers.cs:12:44:12:44 | 0 |
| post | Initializers.cs:12:44:12:44 | 0 | Initializers.cs:12:17:12:53 | object creation of type Initializers |
| post | Initializers.cs:12:47:12:47 | access to property G | Initializers.cs:12:51:12:51 | 1 |
| post | Initializers.cs:12:47:12:51 | ... = ... | Initializers.cs:12:47:12:47 | access to property G |
| post | Initializers.cs:12:51:12:51 | 1 | Initializers.cs:12:40:12:44 | ... = ... |
| post | Initializers.cs:13:9:13:64 | ... ...; | Initializers.cs:12:13:12:53 | Initializers i = ... |
| post | Initializers.cs:13:13:13:63 | Initializers[] iz = ... | Initializers.cs:13:37:13:63 | { ..., ... } |
| post | Initializers.cs:13:18:13:63 | array creation of type Initializers[] | Initializers.cs:13:9:13:64 | ... ...; |
| post | Initializers.cs:13:37:13:63 | { ..., ... } | Initializers.cs:13:42:13:61 | object creation of type Initializers |
| post | Initializers.cs:13:39:13:39 | access to local variable i | Initializers.cs:13:18:13:63 | array creation of type Initializers[] |
| post | Initializers.cs:13:42:13:61 | object creation of type Initializers | Initializers.cs:13:59:13:60 | "" |
| post | Initializers.cs:13:59:13:60 | "" | Initializers.cs:13:39:13:39 | access to local variable i |
| post | Initializers.cs:16:16:16:20 | ... = ... | Initializers.cs:16:20:16:20 | 1 |
| post | Initializers.cs:18:11:18:23 | exit NoConstructor | Initializers.cs:21:13:21:17 | ... = ... |
| post | Initializers.cs:20:13:20:13 | this access | Initializers.cs:18:11:18:23 | enter NoConstructor |
| post | Initializers.cs:20:13:20:17 | ... = ... | Initializers.cs:20:17:20:17 | 0 |
| post | Initializers.cs:20:17:20:17 | 0 | Initializers.cs:20:13:20:13 | this access |
| post | Initializers.cs:21:13:21:13 | this access | Initializers.cs:20:13:20:17 | ... = ... |
| post | Initializers.cs:21:13:21:17 | ... = ... | Initializers.cs:21:17:21:17 | 1 |
| post | Initializers.cs:21:17:21:17 | 1 | Initializers.cs:21:13:21:13 | this access |
| post | NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:23:3:23 | access to parameter i |
| post | NullCoalescing.cs:3:9:3:10 | exit M1 | NullCoalescing.cs:3:28:3:28 | 0 |
| post | NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:23:3:28 | ... ?? ... |
@@ -3743,36 +3765,58 @@
| pre | Foreach.cs:38:33:38:33 | Int32 y | Foreach.cs:38:18:38:34 | (..., ...) |
| pre | Foreach.cs:38:39:38:42 | access to parameter args | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... |
| pre | Initializers.cs:3:9:3:9 | this access | Initializers.cs:3:13:3:13 | access to field H |
| pre | Initializers.cs:3:9:3:9 | this access | Initializers.cs:3:13:3:13 | access to field H |
| pre | Initializers.cs:3:9:3:17 | ... = ... | Initializers.cs:4:9:4:9 | this access |
| pre | Initializers.cs:3:9:3:17 | ... = ... | Initializers.cs:4:9:4:9 | this access |
| pre | Initializers.cs:3:13:3:13 | access to field H | Initializers.cs:3:17:3:17 | 1 |
| pre | Initializers.cs:3:13:3:13 | access to field H | Initializers.cs:3:17:3:17 | 1 |
| pre | Initializers.cs:3:13:3:17 | ... + ... | Initializers.cs:3:9:3:17 | ... = ... |
| pre | Initializers.cs:3:13:3:17 | ... + ... | Initializers.cs:3:9:3:17 | ... = ... |
| pre | Initializers.cs:3:17:3:17 | 1 | Initializers.cs:3:13:3:17 | ... + ... |
| pre | Initializers.cs:3:17:3:17 | 1 | Initializers.cs:3:13:3:17 | ... + ... |
| pre | Initializers.cs:4:9:4:9 | access to property G | Initializers.cs:4:25:4:31 | ... = ... |
| pre | Initializers.cs:4:9:4:9 | access to property G | Initializers.cs:4:25:4:31 | ... = ... |
| pre | Initializers.cs:4:9:4:9 | this access | Initializers.cs:4:27:4:27 | access to field H |
| pre | Initializers.cs:4:9:4:9 | this access | Initializers.cs:4:27:4:27 | access to field H |
| pre | Initializers.cs:4:25:4:31 | ... = ... | Initializers.cs:6:20:6:22 | {...} |
| pre | Initializers.cs:4:25:4:31 | ... = ... | Initializers.cs:8:28:8:30 | {...} |
| pre | Initializers.cs:4:27:4:27 | access to field H | Initializers.cs:4:31:4:31 | 2 |
| pre | Initializers.cs:4:27:4:27 | access to field H | Initializers.cs:4:31:4:31 | 2 |
| pre | Initializers.cs:4:27:4:31 | ... + ... | Initializers.cs:4:9:4:9 | access to property G |
| pre | Initializers.cs:4:27:4:31 | ... + ... | Initializers.cs:4:9:4:9 | access to property G |
| pre | Initializers.cs:4:31:4:31 | 2 | Initializers.cs:4:27:4:31 | ... + ... |
| pre | Initializers.cs:6:5:6:16 | enter Initializers | Initializers.cs:6:28:6:30 | {...} |
| pre | Initializers.cs:6:28:6:30 | {...} | Initializers.cs:6:5:6:16 | exit Initializers |
| pre | Initializers.cs:8:10:8:10 | enter M | Initializers.cs:9:5:12:5 | {...} |
| pre | Initializers.cs:9:5:12:5 | {...} | Initializers.cs:10:9:10:54 | ... ...; |
| pre | Initializers.cs:10:9:10:54 | ... ...; | Initializers.cs:10:34:10:35 | "" |
| pre | Initializers.cs:10:13:10:53 | Initializers i = ... | Initializers.cs:11:9:11:64 | ... ...; |
| pre | Initializers.cs:10:17:10:53 | object creation of type Initializers | Initializers.cs:10:44:10:44 | 0 |
| pre | Initializers.cs:10:34:10:35 | "" | Initializers.cs:10:17:10:53 | object creation of type Initializers |
| pre | Initializers.cs:10:38:10:53 | { ..., ... } | Initializers.cs:10:13:10:53 | Initializers i = ... |
| pre | Initializers.cs:10:40:10:44 | ... = ... | Initializers.cs:10:51:10:51 | 1 |
| pre | Initializers.cs:10:44:10:44 | 0 | Initializers.cs:10:40:10:44 | ... = ... |
| pre | Initializers.cs:10:47:10:47 | access to property G | Initializers.cs:10:47:10:51 | ... = ... |
| pre | Initializers.cs:10:47:10:51 | ... = ... | Initializers.cs:10:38:10:53 | { ..., ... } |
| pre | Initializers.cs:10:51:10:51 | 1 | Initializers.cs:10:47:10:47 | access to property G |
| pre | Initializers.cs:11:9:11:64 | ... ...; | Initializers.cs:11:18:11:63 | array creation of type Initializers[] |
| pre | Initializers.cs:11:13:11:63 | Initializers[] iz = ... | Initializers.cs:8:10:8:10 | exit M |
| pre | Initializers.cs:11:18:11:63 | array creation of type Initializers[] | Initializers.cs:11:39:11:39 | access to local variable i |
| pre | Initializers.cs:11:37:11:63 | { ..., ... } | Initializers.cs:11:13:11:63 | Initializers[] iz = ... |
| pre | Initializers.cs:11:39:11:39 | access to local variable i | Initializers.cs:11:59:11:60 | "" |
| pre | Initializers.cs:11:42:11:61 | object creation of type Initializers | Initializers.cs:11:37:11:63 | { ..., ... } |
| pre | Initializers.cs:11:59:11:60 | "" | Initializers.cs:11:42:11:61 | object creation of type Initializers |
| pre | Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:16:14:20 | ... = ... |
| pre | Initializers.cs:4:31:4:31 | 2 | Initializers.cs:4:27:4:31 | ... + ... |
| pre | Initializers.cs:6:5:6:16 | enter Initializers | Initializers.cs:3:9:3:9 | this access |
| pre | Initializers.cs:6:20:6:22 | {...} | Initializers.cs:6:5:6:16 | exit Initializers |
| pre | Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:3:9:3:9 | this access |
| pre | Initializers.cs:8:28:8:30 | {...} | Initializers.cs:8:5:8:16 | exit Initializers |
| pre | Initializers.cs:10:10:10:10 | enter M | Initializers.cs:11:5:14:5 | {...} |
| pre | Initializers.cs:11:5:14:5 | {...} | Initializers.cs:12:9:12:54 | ... ...; |
| pre | Initializers.cs:12:9:12:54 | ... ...; | Initializers.cs:12:34:12:35 | "" |
| pre | Initializers.cs:12:13:12:53 | Initializers i = ... | Initializers.cs:13:9:13:64 | ... ...; |
| pre | Initializers.cs:12:17:12:53 | object creation of type Initializers | Initializers.cs:12:44:12:44 | 0 |
| pre | Initializers.cs:12:34:12:35 | "" | Initializers.cs:12:17:12:53 | object creation of type Initializers |
| pre | Initializers.cs:12:38:12:53 | { ..., ... } | Initializers.cs:12:13:12:53 | Initializers i = ... |
| pre | Initializers.cs:12:40:12:44 | ... = ... | Initializers.cs:12:51:12:51 | 1 |
| pre | Initializers.cs:12:44:12:44 | 0 | Initializers.cs:12:40:12:44 | ... = ... |
| pre | Initializers.cs:12:47:12:47 | access to property G | Initializers.cs:12:47:12:51 | ... = ... |
| pre | Initializers.cs:12:47:12:51 | ... = ... | Initializers.cs:12:38:12:53 | { ..., ... } |
| pre | Initializers.cs:12:51:12:51 | 1 | Initializers.cs:12:47:12:47 | access to property G |
| pre | Initializers.cs:13:9:13:64 | ... ...; | Initializers.cs:13:18:13:63 | array creation of type Initializers[] |
| pre | Initializers.cs:13:13:13:63 | Initializers[] iz = ... | Initializers.cs:10:10:10:10 | exit M |
| pre | Initializers.cs:13:18:13:63 | array creation of type Initializers[] | Initializers.cs:13:39:13:39 | access to local variable i |
| pre | Initializers.cs:13:37:13:63 | { ..., ... } | Initializers.cs:13:13:13:63 | Initializers[] iz = ... |
| pre | Initializers.cs:13:39:13:39 | access to local variable i | Initializers.cs:13:59:13:60 | "" |
| pre | Initializers.cs:13:42:13:61 | object creation of type Initializers | Initializers.cs:13:37:13:63 | { ..., ... } |
| pre | Initializers.cs:13:59:13:60 | "" | Initializers.cs:13:42:13:61 | object creation of type Initializers |
| pre | Initializers.cs:16:20:16:20 | 1 | Initializers.cs:16:16:16:20 | ... = ... |
| pre | Initializers.cs:18:11:18:23 | enter NoConstructor | Initializers.cs:20:13:20:13 | this access |
| pre | Initializers.cs:20:13:20:13 | this access | Initializers.cs:20:17:20:17 | 0 |
| pre | Initializers.cs:20:13:20:17 | ... = ... | Initializers.cs:21:13:21:13 | this access |
| pre | Initializers.cs:20:17:20:17 | 0 | Initializers.cs:20:13:20:17 | ... = ... |
| pre | Initializers.cs:21:13:21:13 | this access | Initializers.cs:21:17:21:17 | 1 |
| pre | Initializers.cs:21:13:21:17 | ... = ... | Initializers.cs:18:11:18:23 | exit NoConstructor |
| pre | Initializers.cs:21:17:21:17 | 1 | Initializers.cs:21:13:21:17 | ... = ... |
| pre | NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:23:3:28 | ... ?? ... |
| pre | NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:9:3:10 | exit M1 |
| pre | NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:28:3:28 | 0 |

View File

@@ -941,32 +941,40 @@
| Foreach.cs:38:39:38:42 | access to parameter args | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | semmle.label | successor |
| Foreach.cs:39:11:39:11 | ; | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | semmle.label | successor |
| Initializers.cs:3:9:3:9 | this access | Initializers.cs:3:13:3:13 | access to field H | semmle.label | successor |
| Initializers.cs:3:9:3:17 | ... = ... | Initializers.cs:4:9:4:9 | this access | semmle.label | successor |
| Initializers.cs:3:13:3:13 | access to field H | Initializers.cs:3:17:3:17 | 1 | semmle.label | successor |
| Initializers.cs:3:13:3:17 | ... + ... | Initializers.cs:3:9:3:17 | ... = ... | semmle.label | successor |
| Initializers.cs:3:17:3:17 | 1 | Initializers.cs:3:13:3:17 | ... + ... | semmle.label | successor |
| Initializers.cs:4:9:4:9 | access to property G | Initializers.cs:4:25:4:31 | ... = ... | semmle.label | successor |
| Initializers.cs:4:9:4:9 | this access | Initializers.cs:4:27:4:27 | access to field H | semmle.label | successor |
| Initializers.cs:4:25:4:31 | ... = ... | Initializers.cs:6:20:6:22 | {...} | semmle.label | successor |
| Initializers.cs:4:25:4:31 | ... = ... | Initializers.cs:8:28:8:30 | {...} | semmle.label | successor |
| Initializers.cs:4:27:4:27 | access to field H | Initializers.cs:4:31:4:31 | 2 | semmle.label | successor |
| Initializers.cs:4:27:4:31 | ... + ... | Initializers.cs:4:9:4:9 | access to property G | semmle.label | successor |
| Initializers.cs:4:31:4:31 | 2 | Initializers.cs:4:27:4:31 | ... + ... | semmle.label | successor |
| Initializers.cs:9:5:12:5 | {...} | Initializers.cs:10:9:10:54 | ... ...; | semmle.label | successor |
| Initializers.cs:10:9:10:54 | ... ...; | Initializers.cs:10:34:10:35 | "" | semmle.label | successor |
| Initializers.cs:10:13:10:53 | Initializers i = ... | Initializers.cs:11:9:11:64 | ... ...; | semmle.label | successor |
| Initializers.cs:10:17:10:53 | object creation of type Initializers | Initializers.cs:10:44:10:44 | 0 | semmle.label | successor |
| Initializers.cs:10:34:10:35 | "" | Initializers.cs:10:17:10:53 | object creation of type Initializers | semmle.label | successor |
| Initializers.cs:10:38:10:53 | { ..., ... } | Initializers.cs:10:13:10:53 | Initializers i = ... | semmle.label | successor |
| Initializers.cs:10:40:10:44 | ... = ... | Initializers.cs:10:51:10:51 | 1 | semmle.label | successor |
| Initializers.cs:10:44:10:44 | 0 | Initializers.cs:10:40:10:44 | ... = ... | semmle.label | successor |
| Initializers.cs:10:47:10:47 | access to property G | Initializers.cs:10:47:10:51 | ... = ... | semmle.label | successor |
| Initializers.cs:10:47:10:51 | ... = ... | Initializers.cs:10:38:10:53 | { ..., ... } | semmle.label | successor |
| Initializers.cs:10:51:10:51 | 1 | Initializers.cs:10:47:10:47 | access to property G | semmle.label | successor |
| Initializers.cs:11:9:11:64 | ... ...; | Initializers.cs:11:18:11:63 | array creation of type Initializers[] | semmle.label | successor |
| Initializers.cs:11:18:11:63 | array creation of type Initializers[] | Initializers.cs:11:39:11:39 | access to local variable i | semmle.label | successor |
| Initializers.cs:11:37:11:63 | { ..., ... } | Initializers.cs:11:13:11:63 | Initializers[] iz = ... | semmle.label | successor |
| Initializers.cs:11:39:11:39 | access to local variable i | Initializers.cs:11:59:11:60 | "" | semmle.label | successor |
| Initializers.cs:11:42:11:61 | object creation of type Initializers | Initializers.cs:11:37:11:63 | { ..., ... } | semmle.label | successor |
| Initializers.cs:11:59:11:60 | "" | Initializers.cs:11:42:11:61 | object creation of type Initializers | semmle.label | successor |
| Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:16:14:20 | ... = ... | semmle.label | successor |
| Initializers.cs:11:5:14:5 | {...} | Initializers.cs:12:9:12:54 | ... ...; | semmle.label | successor |
| Initializers.cs:12:9:12:54 | ... ...; | Initializers.cs:12:34:12:35 | "" | semmle.label | successor |
| Initializers.cs:12:13:12:53 | Initializers i = ... | Initializers.cs:13:9:13:64 | ... ...; | semmle.label | successor |
| Initializers.cs:12:17:12:53 | object creation of type Initializers | Initializers.cs:12:44:12:44 | 0 | semmle.label | successor |
| Initializers.cs:12:34:12:35 | "" | Initializers.cs:12:17:12:53 | object creation of type Initializers | semmle.label | successor |
| Initializers.cs:12:38:12:53 | { ..., ... } | Initializers.cs:12:13:12:53 | Initializers i = ... | semmle.label | successor |
| Initializers.cs:12:40:12:44 | ... = ... | Initializers.cs:12:51:12:51 | 1 | semmle.label | successor |
| Initializers.cs:12:44:12:44 | 0 | Initializers.cs:12:40:12:44 | ... = ... | semmle.label | successor |
| Initializers.cs:12:47:12:47 | access to property G | Initializers.cs:12:47:12:51 | ... = ... | semmle.label | successor |
| Initializers.cs:12:47:12:51 | ... = ... | Initializers.cs:12:38:12:53 | { ..., ... } | semmle.label | successor |
| Initializers.cs:12:51:12:51 | 1 | Initializers.cs:12:47:12:47 | access to property G | semmle.label | successor |
| Initializers.cs:13:9:13:64 | ... ...; | Initializers.cs:13:18:13:63 | array creation of type Initializers[] | semmle.label | successor |
| Initializers.cs:13:18:13:63 | array creation of type Initializers[] | Initializers.cs:13:39:13:39 | access to local variable i | semmle.label | successor |
| Initializers.cs:13:37:13:63 | { ..., ... } | Initializers.cs:13:13:13:63 | Initializers[] iz = ... | semmle.label | successor |
| Initializers.cs:13:39:13:39 | access to local variable i | Initializers.cs:13:59:13:60 | "" | semmle.label | successor |
| Initializers.cs:13:42:13:61 | object creation of type Initializers | Initializers.cs:13:37:13:63 | { ..., ... } | semmle.label | successor |
| Initializers.cs:13:59:13:60 | "" | Initializers.cs:13:42:13:61 | object creation of type Initializers | semmle.label | successor |
| Initializers.cs:16:20:16:20 | 1 | Initializers.cs:16:16:16:20 | ... = ... | semmle.label | successor |
| Initializers.cs:20:13:20:13 | this access | Initializers.cs:20:17:20:17 | 0 | semmle.label | successor |
| Initializers.cs:20:13:20:17 | ... = ... | Initializers.cs:21:13:21:13 | this access | semmle.label | successor |
| Initializers.cs:20:17:20:17 | 0 | Initializers.cs:20:13:20:17 | ... = ... | semmle.label | successor |
| Initializers.cs:21:13:21:13 | this access | Initializers.cs:21:17:21:17 | 1 | semmle.label | successor |
| Initializers.cs:21:17:21:17 | 1 | Initializers.cs:21:13:21:17 | ... = ... | semmle.label | successor |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:28:3:28 | 0 | semmle.label | null |
| NullCoalescing.cs:3:23:3:28 | ... ?? ... | NullCoalescing.cs:3:23:3:23 | access to parameter i | semmle.label | successor |
| NullCoalescing.cs:5:24:5:43 | ... ? ... : ... | NullCoalescing.cs:5:25:5:34 | ... ?? ... | semmle.label | successor |

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,8 @@
import csharp
import Common
query predicate nodeEnclosing(SourceControlFlowNode n, Callable c) { c = n.getEnclosingCallable() }
query predicate blockEnclosing(SourceBasicBlock bb, Callable c) {
c = bb.getCallable()
}

View File

@@ -1016,27 +1016,36 @@
| Initializers.cs:4:27:4:27 | access to field H | Initializers.cs:4:27:4:27 | access to field H |
| Initializers.cs:4:27:4:31 | ... + ... | Initializers.cs:4:27:4:27 | access to field H |
| Initializers.cs:4:31:4:31 | 2 | Initializers.cs:4:31:4:31 | 2 |
| Initializers.cs:6:28:6:30 | {...} | Initializers.cs:6:28:6:30 | {...} |
| Initializers.cs:9:5:12:5 | {...} | Initializers.cs:9:5:12:5 | {...} |
| Initializers.cs:10:9:10:54 | ... ...; | Initializers.cs:10:9:10:54 | ... ...; |
| Initializers.cs:10:13:10:53 | Initializers i = ... | Initializers.cs:10:34:10:35 | "" |
| Initializers.cs:10:17:10:53 | object creation of type Initializers | Initializers.cs:10:34:10:35 | "" |
| Initializers.cs:10:34:10:35 | "" | Initializers.cs:10:34:10:35 | "" |
| Initializers.cs:10:38:10:53 | { ..., ... } | Initializers.cs:10:44:10:44 | 0 |
| Initializers.cs:10:40:10:44 | ... = ... | Initializers.cs:10:44:10:44 | 0 |
| Initializers.cs:10:44:10:44 | 0 | Initializers.cs:10:44:10:44 | 0 |
| Initializers.cs:10:47:10:51 | ... = ... | Initializers.cs:10:51:10:51 | 1 |
| Initializers.cs:10:51:10:51 | 1 | Initializers.cs:10:51:10:51 | 1 |
| Initializers.cs:11:9:11:64 | ... ...; | Initializers.cs:11:9:11:64 | ... ...; |
| Initializers.cs:11:13:11:63 | Initializers[] iz = ... | Initializers.cs:11:18:11:63 | array creation of type Initializers[] |
| Initializers.cs:11:18:11:63 | 2 | Initializers.cs:11:18:11:63 | 2 |
| Initializers.cs:11:18:11:63 | array creation of type Initializers[] | Initializers.cs:11:18:11:63 | array creation of type Initializers[] |
| Initializers.cs:11:37:11:63 | { ..., ... } | Initializers.cs:11:39:11:39 | access to local variable i |
| Initializers.cs:11:39:11:39 | access to local variable i | Initializers.cs:11:39:11:39 | access to local variable i |
| Initializers.cs:11:42:11:61 | object creation of type Initializers | Initializers.cs:11:59:11:60 | "" |
| Initializers.cs:11:59:11:60 | "" | Initializers.cs:11:59:11:60 | "" |
| Initializers.cs:14:16:14:20 | ... = ... | Initializers.cs:14:20:14:20 | 1 |
| Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:20:14:20 | 1 |
| Initializers.cs:6:20:6:22 | {...} | Initializers.cs:6:20:6:22 | {...} |
| Initializers.cs:8:28:8:30 | {...} | Initializers.cs:8:28:8:30 | {...} |
| Initializers.cs:11:5:14:5 | {...} | Initializers.cs:11:5:14:5 | {...} |
| Initializers.cs:12:9:12:54 | ... ...; | Initializers.cs:12:9:12:54 | ... ...; |
| Initializers.cs:12:13:12:53 | Initializers i = ... | Initializers.cs:12:34:12:35 | "" |
| Initializers.cs:12:17:12:53 | object creation of type Initializers | Initializers.cs:12:34:12:35 | "" |
| Initializers.cs:12:34:12:35 | "" | Initializers.cs:12:34:12:35 | "" |
| Initializers.cs:12:38:12:53 | { ..., ... } | Initializers.cs:12:44:12:44 | 0 |
| Initializers.cs:12:40:12:44 | ... = ... | Initializers.cs:12:44:12:44 | 0 |
| Initializers.cs:12:44:12:44 | 0 | Initializers.cs:12:44:12:44 | 0 |
| Initializers.cs:12:47:12:51 | ... = ... | Initializers.cs:12:51:12:51 | 1 |
| Initializers.cs:12:51:12:51 | 1 | Initializers.cs:12:51:12:51 | 1 |
| Initializers.cs:13:9:13:64 | ... ...; | Initializers.cs:13:9:13:64 | ... ...; |
| Initializers.cs:13:13:13:63 | Initializers[] iz = ... | Initializers.cs:13:18:13:63 | array creation of type Initializers[] |
| Initializers.cs:13:18:13:63 | 2 | Initializers.cs:13:18:13:63 | 2 |
| Initializers.cs:13:18:13:63 | array creation of type Initializers[] | Initializers.cs:13:18:13:63 | array creation of type Initializers[] |
| Initializers.cs:13:37:13:63 | { ..., ... } | Initializers.cs:13:39:13:39 | access to local variable i |
| Initializers.cs:13:39:13:39 | access to local variable i | Initializers.cs:13:39:13:39 | access to local variable i |
| Initializers.cs:13:42:13:61 | object creation of type Initializers | Initializers.cs:13:59:13:60 | "" |
| Initializers.cs:13:59:13:60 | "" | Initializers.cs:13:59:13:60 | "" |
| Initializers.cs:16:16:16:20 | ... = ... | Initializers.cs:16:20:16:20 | 1 |
| Initializers.cs:16:20:16:20 | 1 | Initializers.cs:16:20:16:20 | 1 |
| Initializers.cs:20:13:20:13 | access to field F | Initializers.cs:20:13:20:13 | this access |
| Initializers.cs:20:13:20:13 | this access | Initializers.cs:20:13:20:13 | this access |
| Initializers.cs:20:13:20:17 | ... = ... | Initializers.cs:20:13:20:13 | this access |
| Initializers.cs:20:17:20:17 | 0 | Initializers.cs:20:17:20:17 | 0 |
| Initializers.cs:21:13:21:13 | access to field G | Initializers.cs:21:13:21:13 | this access |
| Initializers.cs:21:13:21:13 | this access | Initializers.cs:21:13:21:13 | this access |
| Initializers.cs:21:13:21:17 | ... = ... | Initializers.cs:21:13:21:13 | this access |
| Initializers.cs:21:17:21:17 | 1 | Initializers.cs:21:17:21:17 | 1 |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:23:3:23 | access to parameter i |
| NullCoalescing.cs:3:23:3:28 | ... ?? ... | NullCoalescing.cs:3:23:3:28 | ... ?? ... |
| NullCoalescing.cs:3:28:3:28 | 0 | NullCoalescing.cs:3:28:3:28 | 0 |

View File

@@ -79,8 +79,10 @@
| Foreach.cs:24:10:24:11 | M4 | Foreach.cs:25:5:28:5 | {...} |
| Foreach.cs:30:10:30:11 | M5 | Foreach.cs:31:5:34:5 | {...} |
| Foreach.cs:36:10:36:11 | M6 | Foreach.cs:37:5:40:5 | {...} |
| Initializers.cs:6:5:6:16 | Initializers | Initializers.cs:6:28:6:30 | {...} |
| Initializers.cs:8:10:8:10 | M | Initializers.cs:9:5:12:5 | {...} |
| Initializers.cs:6:5:6:16 | Initializers | Initializers.cs:3:9:3:9 | this access |
| Initializers.cs:8:5:8:16 | Initializers | Initializers.cs:3:9:3:9 | this access |
| Initializers.cs:10:10:10:10 | M | Initializers.cs:11:5:14:5 | {...} |
| Initializers.cs:18:11:18:23 | NoConstructor | Initializers.cs:20:13:20:13 | this access |
| NullCoalescing.cs:3:9:3:10 | M1 | NullCoalescing.cs:3:23:3:28 | ... ?? ... |
| NullCoalescing.cs:5:9:5:10 | M2 | NullCoalescing.cs:5:24:5:43 | ... ? ... : ... |
| NullCoalescing.cs:7:12:7:13 | M3 | NullCoalescing.cs:7:40:7:53 | ... ?? ... |

View File

@@ -1313,27 +1313,36 @@
| Initializers.cs:4:27:4:27 | access to field H | Initializers.cs:4:27:4:27 | access to field H | normal |
| Initializers.cs:4:27:4:31 | ... + ... | Initializers.cs:4:27:4:31 | ... + ... | normal |
| Initializers.cs:4:31:4:31 | 2 | Initializers.cs:4:31:4:31 | 2 | normal |
| Initializers.cs:6:28:6:30 | {...} | Initializers.cs:6:28:6:30 | {...} | normal |
| Initializers.cs:9:5:12:5 | {...} | Initializers.cs:11:13:11:63 | Initializers[] iz = ... | normal |
| Initializers.cs:10:9:10:54 | ... ...; | Initializers.cs:10:13:10:53 | Initializers i = ... | normal |
| Initializers.cs:10:13:10:53 | Initializers i = ... | Initializers.cs:10:13:10:53 | Initializers i = ... | normal |
| Initializers.cs:10:17:10:53 | object creation of type Initializers | Initializers.cs:10:38:10:53 | { ..., ... } | normal |
| Initializers.cs:10:34:10:35 | "" | Initializers.cs:10:34:10:35 | "" | normal |
| Initializers.cs:10:38:10:53 | { ..., ... } | Initializers.cs:10:38:10:53 | { ..., ... } | normal |
| Initializers.cs:10:40:10:44 | ... = ... | Initializers.cs:10:40:10:44 | ... = ... | normal |
| Initializers.cs:10:44:10:44 | 0 | Initializers.cs:10:44:10:44 | 0 | normal |
| Initializers.cs:10:47:10:51 | ... = ... | Initializers.cs:10:47:10:51 | ... = ... | normal |
| Initializers.cs:10:51:10:51 | 1 | Initializers.cs:10:51:10:51 | 1 | normal |
| Initializers.cs:11:9:11:64 | ... ...; | Initializers.cs:11:13:11:63 | Initializers[] iz = ... | normal |
| Initializers.cs:11:13:11:63 | Initializers[] iz = ... | Initializers.cs:11:13:11:63 | Initializers[] iz = ... | normal |
| Initializers.cs:11:18:11:63 | 2 | Initializers.cs:11:18:11:63 | 2 | normal |
| Initializers.cs:11:18:11:63 | array creation of type Initializers[] | Initializers.cs:11:37:11:63 | { ..., ... } | normal |
| Initializers.cs:11:37:11:63 | { ..., ... } | Initializers.cs:11:37:11:63 | { ..., ... } | normal |
| Initializers.cs:11:39:11:39 | access to local variable i | Initializers.cs:11:39:11:39 | access to local variable i | normal |
| Initializers.cs:11:42:11:61 | object creation of type Initializers | Initializers.cs:11:42:11:61 | object creation of type Initializers | normal |
| Initializers.cs:11:59:11:60 | "" | Initializers.cs:11:59:11:60 | "" | normal |
| Initializers.cs:14:16:14:20 | ... = ... | Initializers.cs:14:16:14:20 | ... = ... | normal |
| Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:20:14:20 | 1 | normal |
| Initializers.cs:6:20:6:22 | {...} | Initializers.cs:6:20:6:22 | {...} | normal |
| Initializers.cs:8:28:8:30 | {...} | Initializers.cs:8:28:8:30 | {...} | normal |
| Initializers.cs:11:5:14:5 | {...} | Initializers.cs:13:13:13:63 | Initializers[] iz = ... | normal |
| Initializers.cs:12:9:12:54 | ... ...; | Initializers.cs:12:13:12:53 | Initializers i = ... | normal |
| Initializers.cs:12:13:12:53 | Initializers i = ... | Initializers.cs:12:13:12:53 | Initializers i = ... | normal |
| Initializers.cs:12:17:12:53 | object creation of type Initializers | Initializers.cs:12:38:12:53 | { ..., ... } | normal |
| Initializers.cs:12:34:12:35 | "" | Initializers.cs:12:34:12:35 | "" | normal |
| Initializers.cs:12:38:12:53 | { ..., ... } | Initializers.cs:12:38:12:53 | { ..., ... } | normal |
| Initializers.cs:12:40:12:44 | ... = ... | Initializers.cs:12:40:12:44 | ... = ... | normal |
| Initializers.cs:12:44:12:44 | 0 | Initializers.cs:12:44:12:44 | 0 | normal |
| Initializers.cs:12:47:12:51 | ... = ... | Initializers.cs:12:47:12:51 | ... = ... | normal |
| Initializers.cs:12:51:12:51 | 1 | Initializers.cs:12:51:12:51 | 1 | normal |
| Initializers.cs:13:9:13:64 | ... ...; | Initializers.cs:13:13:13:63 | Initializers[] iz = ... | normal |
| Initializers.cs:13:13:13:63 | Initializers[] iz = ... | Initializers.cs:13:13:13:63 | Initializers[] iz = ... | normal |
| Initializers.cs:13:18:13:63 | 2 | Initializers.cs:13:18:13:63 | 2 | normal |
| Initializers.cs:13:18:13:63 | array creation of type Initializers[] | Initializers.cs:13:37:13:63 | { ..., ... } | normal |
| Initializers.cs:13:37:13:63 | { ..., ... } | Initializers.cs:13:37:13:63 | { ..., ... } | normal |
| Initializers.cs:13:39:13:39 | access to local variable i | Initializers.cs:13:39:13:39 | access to local variable i | normal |
| Initializers.cs:13:42:13:61 | object creation of type Initializers | Initializers.cs:13:42:13:61 | object creation of type Initializers | normal |
| Initializers.cs:13:59:13:60 | "" | Initializers.cs:13:59:13:60 | "" | normal |
| Initializers.cs:16:16:16:20 | ... = ... | Initializers.cs:16:16:16:20 | ... = ... | normal |
| Initializers.cs:16:20:16:20 | 1 | Initializers.cs:16:20:16:20 | 1 | normal |
| Initializers.cs:20:13:20:13 | access to field F | Initializers.cs:20:13:20:13 | this access | normal |
| Initializers.cs:20:13:20:13 | this access | Initializers.cs:20:13:20:13 | this access | normal |
| Initializers.cs:20:13:20:17 | ... = ... | Initializers.cs:20:13:20:17 | ... = ... | normal |
| Initializers.cs:20:17:20:17 | 0 | Initializers.cs:20:17:20:17 | 0 | normal |
| Initializers.cs:21:13:21:13 | access to field G | Initializers.cs:21:13:21:13 | this access | normal |
| Initializers.cs:21:13:21:13 | this access | Initializers.cs:21:13:21:13 | this access | normal |
| Initializers.cs:21:13:21:17 | ... = ... | Initializers.cs:21:13:21:17 | ... = ... | normal |
| Initializers.cs:21:17:21:17 | 1 | Initializers.cs:21:17:21:17 | 1 | normal |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:23:3:23 | access to parameter i | non-null |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:23:3:23 | access to parameter i | null |
| NullCoalescing.cs:3:23:3:28 | ... ?? ... | NullCoalescing.cs:3:23:3:23 | access to parameter i | non-null |

View File

@@ -3,6 +3,8 @@ class Initializers
int F = H + 1;
int G { get; set; } = H + 2;
Initializers() { }
Initializers(string s) { }
void M()
@@ -12,4 +14,10 @@ class Initializers
}
static int H = 1;
class NoConstructor
{
int F = 0;
int G = 1;
}
}

View File

@@ -1358,36 +1358,58 @@
| Foreach.cs:38:39:38:42 | access to parameter args | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | semmle.label | successor |
| Foreach.cs:39:11:39:11 | ; | Foreach.cs:38:9:39:11 | foreach (... ... in ...) ... | semmle.label | successor |
| Initializers.cs:3:9:3:9 | this access | Initializers.cs:3:13:3:13 | access to field H | semmle.label | successor |
| Initializers.cs:3:9:3:9 | this access | Initializers.cs:3:13:3:13 | access to field H | semmle.label | successor |
| Initializers.cs:3:9:3:17 | ... = ... | Initializers.cs:4:9:4:9 | this access | semmle.label | successor |
| Initializers.cs:3:9:3:17 | ... = ... | Initializers.cs:4:9:4:9 | this access | semmle.label | successor |
| Initializers.cs:3:13:3:13 | access to field H | Initializers.cs:3:17:3:17 | 1 | semmle.label | successor |
| Initializers.cs:3:13:3:13 | access to field H | Initializers.cs:3:17:3:17 | 1 | semmle.label | successor |
| Initializers.cs:3:13:3:17 | ... + ... | Initializers.cs:3:9:3:17 | ... = ... | semmle.label | successor |
| Initializers.cs:3:13:3:17 | ... + ... | Initializers.cs:3:9:3:17 | ... = ... | semmle.label | successor |
| Initializers.cs:3:17:3:17 | 1 | Initializers.cs:3:13:3:17 | ... + ... | semmle.label | successor |
| Initializers.cs:3:17:3:17 | 1 | Initializers.cs:3:13:3:17 | ... + ... | semmle.label | successor |
| Initializers.cs:4:9:4:9 | access to property G | Initializers.cs:4:25:4:31 | ... = ... | semmle.label | successor |
| Initializers.cs:4:9:4:9 | access to property G | Initializers.cs:4:25:4:31 | ... = ... | semmle.label | successor |
| Initializers.cs:4:9:4:9 | this access | Initializers.cs:4:27:4:27 | access to field H | semmle.label | successor |
| Initializers.cs:4:9:4:9 | this access | Initializers.cs:4:27:4:27 | access to field H | semmle.label | successor |
| Initializers.cs:4:25:4:31 | ... = ... | Initializers.cs:6:20:6:22 | {...} | semmle.label | successor |
| Initializers.cs:4:25:4:31 | ... = ... | Initializers.cs:8:28:8:30 | {...} | semmle.label | successor |
| Initializers.cs:4:27:4:27 | access to field H | Initializers.cs:4:31:4:31 | 2 | semmle.label | successor |
| Initializers.cs:4:27:4:27 | access to field H | Initializers.cs:4:31:4:31 | 2 | semmle.label | successor |
| Initializers.cs:4:27:4:31 | ... + ... | Initializers.cs:4:9:4:9 | access to property G | semmle.label | successor |
| Initializers.cs:4:27:4:31 | ... + ... | Initializers.cs:4:9:4:9 | access to property G | semmle.label | successor |
| Initializers.cs:4:31:4:31 | 2 | Initializers.cs:4:27:4:31 | ... + ... | semmle.label | successor |
| Initializers.cs:6:5:6:16 | enter Initializers | Initializers.cs:6:28:6:30 | {...} | semmle.label | successor |
| Initializers.cs:6:28:6:30 | {...} | Initializers.cs:6:5:6:16 | exit Initializers | semmle.label | successor |
| Initializers.cs:8:10:8:10 | enter M | Initializers.cs:9:5:12:5 | {...} | semmle.label | successor |
| Initializers.cs:9:5:12:5 | {...} | Initializers.cs:10:9:10:54 | ... ...; | semmle.label | successor |
| Initializers.cs:10:9:10:54 | ... ...; | Initializers.cs:10:34:10:35 | "" | semmle.label | successor |
| Initializers.cs:10:13:10:53 | Initializers i = ... | Initializers.cs:11:9:11:64 | ... ...; | semmle.label | successor |
| Initializers.cs:10:17:10:53 | object creation of type Initializers | Initializers.cs:10:44:10:44 | 0 | semmle.label | successor |
| Initializers.cs:10:34:10:35 | "" | Initializers.cs:10:17:10:53 | object creation of type Initializers | semmle.label | successor |
| Initializers.cs:10:38:10:53 | { ..., ... } | Initializers.cs:10:13:10:53 | Initializers i = ... | semmle.label | successor |
| Initializers.cs:10:40:10:44 | ... = ... | Initializers.cs:10:51:10:51 | 1 | semmle.label | successor |
| Initializers.cs:10:44:10:44 | 0 | Initializers.cs:10:40:10:44 | ... = ... | semmle.label | successor |
| Initializers.cs:10:47:10:47 | access to property G | Initializers.cs:10:47:10:51 | ... = ... | semmle.label | successor |
| Initializers.cs:10:47:10:51 | ... = ... | Initializers.cs:10:38:10:53 | { ..., ... } | semmle.label | successor |
| Initializers.cs:10:51:10:51 | 1 | Initializers.cs:10:47:10:47 | access to property G | semmle.label | successor |
| Initializers.cs:11:9:11:64 | ... ...; | Initializers.cs:11:18:11:63 | array creation of type Initializers[] | semmle.label | successor |
| Initializers.cs:11:13:11:63 | Initializers[] iz = ... | Initializers.cs:8:10:8:10 | exit M | semmle.label | successor |
| Initializers.cs:11:18:11:63 | array creation of type Initializers[] | Initializers.cs:11:39:11:39 | access to local variable i | semmle.label | successor |
| Initializers.cs:11:37:11:63 | { ..., ... } | Initializers.cs:11:13:11:63 | Initializers[] iz = ... | semmle.label | successor |
| Initializers.cs:11:39:11:39 | access to local variable i | Initializers.cs:11:59:11:60 | "" | semmle.label | successor |
| Initializers.cs:11:42:11:61 | object creation of type Initializers | Initializers.cs:11:37:11:63 | { ..., ... } | semmle.label | successor |
| Initializers.cs:11:59:11:60 | "" | Initializers.cs:11:42:11:61 | object creation of type Initializers | semmle.label | successor |
| Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:16:14:20 | ... = ... | semmle.label | successor |
| Initializers.cs:4:31:4:31 | 2 | Initializers.cs:4:27:4:31 | ... + ... | semmle.label | successor |
| Initializers.cs:6:5:6:16 | enter Initializers | Initializers.cs:3:9:3:9 | this access | semmle.label | successor |
| Initializers.cs:6:20:6:22 | {...} | Initializers.cs:6:5:6:16 | exit Initializers | semmle.label | successor |
| Initializers.cs:8:5:8:16 | enter Initializers | Initializers.cs:3:9:3:9 | this access | semmle.label | successor |
| Initializers.cs:8:28:8:30 | {...} | Initializers.cs:8:5:8:16 | exit Initializers | semmle.label | successor |
| Initializers.cs:10:10:10:10 | enter M | Initializers.cs:11:5:14:5 | {...} | semmle.label | successor |
| Initializers.cs:11:5:14:5 | {...} | Initializers.cs:12:9:12:54 | ... ...; | semmle.label | successor |
| Initializers.cs:12:9:12:54 | ... ...; | Initializers.cs:12:34:12:35 | "" | semmle.label | successor |
| Initializers.cs:12:13:12:53 | Initializers i = ... | Initializers.cs:13:9:13:64 | ... ...; | semmle.label | successor |
| Initializers.cs:12:17:12:53 | object creation of type Initializers | Initializers.cs:12:44:12:44 | 0 | semmle.label | successor |
| Initializers.cs:12:34:12:35 | "" | Initializers.cs:12:17:12:53 | object creation of type Initializers | semmle.label | successor |
| Initializers.cs:12:38:12:53 | { ..., ... } | Initializers.cs:12:13:12:53 | Initializers i = ... | semmle.label | successor |
| Initializers.cs:12:40:12:44 | ... = ... | Initializers.cs:12:51:12:51 | 1 | semmle.label | successor |
| Initializers.cs:12:44:12:44 | 0 | Initializers.cs:12:40:12:44 | ... = ... | semmle.label | successor |
| Initializers.cs:12:47:12:47 | access to property G | Initializers.cs:12:47:12:51 | ... = ... | semmle.label | successor |
| Initializers.cs:12:47:12:51 | ... = ... | Initializers.cs:12:38:12:53 | { ..., ... } | semmle.label | successor |
| Initializers.cs:12:51:12:51 | 1 | Initializers.cs:12:47:12:47 | access to property G | semmle.label | successor |
| Initializers.cs:13:9:13:64 | ... ...; | Initializers.cs:13:18:13:63 | array creation of type Initializers[] | semmle.label | successor |
| Initializers.cs:13:13:13:63 | Initializers[] iz = ... | Initializers.cs:10:10:10:10 | exit M | semmle.label | successor |
| Initializers.cs:13:18:13:63 | array creation of type Initializers[] | Initializers.cs:13:39:13:39 | access to local variable i | semmle.label | successor |
| Initializers.cs:13:37:13:63 | { ..., ... } | Initializers.cs:13:13:13:63 | Initializers[] iz = ... | semmle.label | successor |
| Initializers.cs:13:39:13:39 | access to local variable i | Initializers.cs:13:59:13:60 | "" | semmle.label | successor |
| Initializers.cs:13:42:13:61 | object creation of type Initializers | Initializers.cs:13:37:13:63 | { ..., ... } | semmle.label | successor |
| Initializers.cs:13:59:13:60 | "" | Initializers.cs:13:42:13:61 | object creation of type Initializers | semmle.label | successor |
| Initializers.cs:16:20:16:20 | 1 | Initializers.cs:16:16:16:20 | ... = ... | semmle.label | successor |
| Initializers.cs:18:11:18:23 | enter NoConstructor | Initializers.cs:20:13:20:13 | this access | semmle.label | successor |
| Initializers.cs:20:13:20:13 | this access | Initializers.cs:20:17:20:17 | 0 | semmle.label | successor |
| Initializers.cs:20:13:20:17 | ... = ... | Initializers.cs:21:13:21:13 | this access | semmle.label | successor |
| Initializers.cs:20:17:20:17 | 0 | Initializers.cs:20:13:20:17 | ... = ... | semmle.label | successor |
| Initializers.cs:21:13:21:13 | this access | Initializers.cs:21:17:21:17 | 1 | semmle.label | successor |
| Initializers.cs:21:13:21:17 | ... = ... | Initializers.cs:18:11:18:23 | exit NoConstructor | semmle.label | successor |
| Initializers.cs:21:17:21:17 | 1 | Initializers.cs:21:13:21:17 | ... = ... | semmle.label | successor |
| NullCoalescing.cs:3:9:3:10 | enter M1 | NullCoalescing.cs:3:23:3:28 | ... ?? ... | semmle.label | successor |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:9:3:10 | exit M1 | semmle.label | non-null |
| NullCoalescing.cs:3:23:3:23 | access to parameter i | NullCoalescing.cs:3:28:3:28 | 0 | semmle.label | null |

View File

@@ -1,15 +1,15 @@
| CSharp7.cs:9:9:9:9 | this | CSharp7.cs:9:9:9:9 | this access |
| CSharp7.cs:10:9:10:9 | this | CSharp7.cs:10:9:10:9 | this access |
| CSharp7.cs:11:9:11:9 | this | CSharp7.cs:11:9:11:9 | this access |
| CSharp7.cs:16:9:16:13 | this | CSharp7.cs:16:9:16:13 | this access |
| CSharp7.cs:9:9:9:9 | [post] this access | CSharp7.cs:10:9:10:9 | this access |
| CSharp7.cs:9:9:9:9 | this access | CSharp7.cs:10:9:10:9 | this access |
| CSharp7.cs:10:9:10:9 | [post] this access | CSharp7.cs:11:9:11:9 | this access |
| CSharp7.cs:10:9:10:9 | this access | CSharp7.cs:11:9:11:9 | this access |
| CSharp7.cs:16:9:16:13 | [post] this access | CSharp7.cs:25:39:25:43 | this access |
| CSharp7.cs:16:9:16:13 | this access | CSharp7.cs:25:39:25:43 | this access |
| CSharp7.cs:17:9:17:11 | this | CSharp7.cs:17:18:17:22 | this access |
| CSharp7.cs:21:9:21:11 | this | CSharp7.cs:21:16:21:20 | this access |
| CSharp7.cs:22:9:22:11 | this | CSharp7.cs:22:16:22:20 | this access |
| CSharp7.cs:22:9:22:11 | value | CSharp7.cs:22:9:22:11 | value |
| CSharp7.cs:22:9:22:11 | value | CSharp7.cs:22:24:22:28 | access to parameter value |
| CSharp7.cs:25:5:25:27 | [implicit] this access | CSharp7.cs:25:39:25:43 | this access |
| CSharp7.cs:25:5:25:27 | [post implicit] this access | CSharp7.cs:25:39:25:43 | this access |
| CSharp7.cs:25:5:25:27 | this | CSharp7.cs:25:5:25:27 | [implicit] this access |
| CSharp7.cs:25:5:25:27 | this | CSharp7.cs:16:9:16:13 | this access |
| CSharp7.cs:26:6:26:28 | this | CSharp7.cs:26:35:26:39 | this access |
| CSharp7.cs:31:19:31:19 | i | CSharp7.cs:31:19:31:19 | i |
| CSharp7.cs:31:19:31:19 | i | CSharp7.cs:33:16:33:16 | access to parameter i |

View File

@@ -6,7 +6,7 @@ query predicate suppressNullableWarnings(SuppressNullableWarningExpr e, Expr op)
}
query predicate nullableDataFlow(DataFlow::Node src, DataFlow::Node sink) {
src.getEnclosingCallable().getCallable().hasName("TestSuppressNullableWarningExpr") and
src.getEnclosingCallable().hasName("TestSuppressNullableWarningExpr") and
DataFlow::localFlowStep(src, sink)
}

View File

@@ -90,13 +90,13 @@ edges
| B.cs:17:14:17:20 | access to field box1 [elem2, ... (1)] | B.cs:18:14:18:20 | access to field box1 [elem2, ... (1)] |
| B.cs:18:14:18:15 | access to local variable b2 [box1, ... (2)] | B.cs:18:14:18:20 | access to field box1 [elem2, ... (1)] |
| B.cs:18:14:18:20 | access to field box1 [elem2, ... (1)] | B.cs:18:14:18:26 | access to field elem2 |
| C.cs:3:18:3:19 | [post] this access [s1, ... (1)] | C.cs:16:13:16:13 | [post implicit] this access [s1, ... (1)] |
| C.cs:3:18:3:19 | [post] this access [s1, ... (1)] | C.cs:12:15:12:21 | object creation of type C [s1, ... (1)] |
| C.cs:3:23:3:32 | object creation of type Elem | C.cs:3:18:3:19 | [post] this access [s1, ... (1)] |
| C.cs:4:27:4:28 | [post] this access [s2, ... (1)] | C.cs:16:13:16:13 | [post implicit] this access [s2, ... (1)] |
| C.cs:4:27:4:28 | [post] this access [s2, ... (1)] | C.cs:12:15:12:21 | object creation of type C [s2, ... (1)] |
| C.cs:4:32:4:41 | object creation of type Elem | C.cs:4:27:4:28 | [post] this access [s2, ... (1)] |
| C.cs:6:30:6:39 | object creation of type Elem | C.cs:26:14:26:15 | access to field s4 |
| C.cs:7:18:7:19 | [post] this access [s5, ... (1)] | C.cs:16:13:16:13 | [post implicit] this access [s5, ... (1)] |
| C.cs:7:18:7:19 | [post] this access [s5, ... (1)] | C.cs:16:13:16:13 | [post implicit] this access [s5, ... (1)] |
| C.cs:7:18:7:19 | [post] this access [s5, ... (1)] | C.cs:12:15:12:21 | object creation of type C [s5, ... (1)] |
| C.cs:7:18:7:19 | [post] this access [s5, ... (1)] | C.cs:12:15:12:21 | object creation of type C [s5, ... (1)] |
| C.cs:7:37:7:46 | object creation of type Elem | C.cs:7:18:7:19 | [post] this access [s5, ... (1)] |
| C.cs:7:37:7:46 | object creation of type Elem | C.cs:7:18:7:19 | [post] this access [s5, ... (1)] |
| C.cs:8:30:8:39 | object creation of type Elem | C.cs:28:14:28:15 | access to property s6 |
@@ -108,9 +108,6 @@ edges
| C.cs:13:9:13:9 | access to local variable c [s2, ... (1)] | C.cs:21:17:21:18 | this [s2, ... (1)] |
| C.cs:13:9:13:9 | access to local variable c [s3, ... (1)] | C.cs:21:17:21:18 | this [s3, ... (1)] |
| C.cs:13:9:13:9 | access to local variable c [s5, ... (1)] | C.cs:21:17:21:18 | this [s5, ... (1)] |
| C.cs:16:13:16:13 | [post implicit] this access [s1, ... (1)] | C.cs:12:15:12:21 | object creation of type C [s1, ... (1)] |
| C.cs:16:13:16:13 | [post implicit] this access [s2, ... (1)] | C.cs:12:15:12:21 | object creation of type C [s2, ... (1)] |
| C.cs:16:13:16:13 | [post implicit] this access [s5, ... (1)] | C.cs:12:15:12:21 | object creation of type C [s5, ... (1)] |
| C.cs:18:9:18:12 | [post] this access [s3, ... (1)] | C.cs:12:15:12:21 | object creation of type C [s3, ... (1)] |
| C.cs:18:19:18:28 | object creation of type Elem | C.cs:18:9:18:12 | [post] this access [s3, ... (1)] |
| C.cs:21:17:21:18 | this [s1, ... (1)] | C.cs:23:14:23:15 | this access [s1, ... (1)] |