mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
C#: Generalize CFG entry/exit nodes to include field/property initializers
This commit is contained in:
@@ -19,7 +19,8 @@ private import semmle.code.csharp.metrics.Complexity
|
||||
* an anonymous function (`AnonymousFunctionExpr`), or a local function
|
||||
* (`LocalFunction`).
|
||||
*/
|
||||
class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @callable {
|
||||
class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, ControlFlowEntryElement,
|
||||
@callable {
|
||||
override Type getReturnType() { none() }
|
||||
|
||||
/** Gets the annotated return type of this callable. */
|
||||
|
||||
@@ -54,11 +54,11 @@ module Internal {
|
||||
getAChildExpr+(s) = e
|
||||
}
|
||||
|
||||
private predicate childExprOfCallable(Callable parent, Expr child) {
|
||||
private predicate childExprOfEntryElement(ControlFlowEntryElement parent, Expr child) {
|
||||
child = getAChildExpr(parent)
|
||||
or
|
||||
exists(Expr mid | childExprOfCallable(parent, mid) |
|
||||
not mid instanceof Callable and
|
||||
exists(Expr mid | childExprOfEntryElement(parent, mid) |
|
||||
not mid instanceof ControlFlowEntryElement and
|
||||
child = getAChildExpr(mid)
|
||||
)
|
||||
}
|
||||
@@ -66,18 +66,18 @@ module Internal {
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*
|
||||
* Holds if `c` is the enclosing callable of expression `e`.
|
||||
* Holds if `entry` is the enclosing entry element of expression `e`.
|
||||
*/
|
||||
cached
|
||||
predicate exprEnclosingCallable(Expr e, Callable c) {
|
||||
predicate exprEnclosingEntryElement(Expr e, ControlFlowEntryElement entry) {
|
||||
// Compute the enclosing callable of an expression. Note that expressions in
|
||||
// lambda functions should have the lambdas as enclosing callables, and their
|
||||
// enclosing statement may be the same as the enclosing statement of the
|
||||
// lambda; thus, it is *not* safe to go up to the enclosing statement and
|
||||
// take its own enclosing callable.
|
||||
childExprOfCallable(c, e)
|
||||
childExprOfEntryElement(entry, e)
|
||||
or
|
||||
not childExprOfCallable(_, e) and
|
||||
exists(Stmt s | enclosingStmt(e, s) | enclosingCallable(s, c))
|
||||
not childExprOfEntryElement(_, e) and
|
||||
exists(Stmt s | enclosingStmt(e, s) | enclosingCallable(s, entry))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import csharp
|
||||
* The `expr_parent_top_level()` relation extended to include a relation
|
||||
* between getters and expression bodies in properties such as `int P => 0`.
|
||||
*/
|
||||
predicate expr_parent_top_level_adjusted(Expr child, int i, @top_level_exprorstmt_parent parent) {
|
||||
predicate expr_parent_top_level_adjusted(Expr child, int i, ControlFlowEntryElement parent) {
|
||||
expr_parent_top_level(child, i, parent)
|
||||
or
|
||||
parent = any(Getter g | expr_parent_top_level(child, i, g.getDeclaration())) and
|
||||
@@ -108,7 +108,7 @@ class ExprOrStmtParent extends Element, @exprorstmt_parent {
|
||||
*
|
||||
* An element that can have a child top-level expression.
|
||||
*/
|
||||
class TopLevelExprParent extends Element, @top_level_expr_parent {
|
||||
class TopLevelExprParent extends ControlFlowEntryElement, @top_level_expr_parent {
|
||||
final override Expr getChild(int i) { result = this.getChildExpr(i) }
|
||||
|
||||
/** Gets the `i`th child expression of this element (zero-based). */
|
||||
|
||||
@@ -74,8 +74,13 @@ class BasicBlock extends TBasicBlockStart {
|
||||
/** Gets the last control flow node in this basic block. */
|
||||
ControlFlow::Node getLastNode() { result = getNode(length() - 1) }
|
||||
|
||||
/** Gets the callable that this basic block belongs to. */
|
||||
Callable getCallable() { result = this.getAPredecessor().getCallable() }
|
||||
/** Gets the callable that this basic block belongs to, if any. */
|
||||
final Callable getCallable() { result = this.getEntryElement() }
|
||||
|
||||
/** Gets the entry element that this basic block belongs to. */
|
||||
final ControlFlowEntryElement getEntryElement() {
|
||||
result = this.getFirstNode().getEnclosingElement()
|
||||
}
|
||||
|
||||
/** Gets the length of this basic block. */
|
||||
int length() { result = strictcount(getANode()) }
|
||||
@@ -342,12 +347,10 @@ private import Internal
|
||||
|
||||
/**
|
||||
* An entry basic block, that is, a basic block whose first node is
|
||||
* the entry node of a callable.
|
||||
* an entry node (`ControlFlow::Nodes::EntryNode`).
|
||||
*/
|
||||
class EntryBasicBlock extends BasicBlock {
|
||||
EntryBasicBlock() { entryBB(this) }
|
||||
|
||||
override Callable getCallable() { result.getEntryPoint() = this.getFirstNode() }
|
||||
}
|
||||
|
||||
/** Holds if `bb` is an entry basic block. */
|
||||
@@ -357,7 +360,7 @@ private predicate entryBB(BasicBlock bb) {
|
||||
|
||||
/**
|
||||
* An exit basic block, that is, a basic block whose last node is
|
||||
* the exit node of a callable.
|
||||
* an exit node (`ControlFlow::Nodes::ExitNode`).
|
||||
*/
|
||||
class ExitBasicBlock extends BasicBlock {
|
||||
ExitBasicBlock() { exitBB(this) }
|
||||
|
||||
@@ -7,6 +7,13 @@ private import ControlFlow::BasicBlocks
|
||||
private import SuccessorTypes
|
||||
private import semmle.code.csharp.Caching
|
||||
|
||||
/**
|
||||
* An element that contains a top-level statement or expression. Either a callable
|
||||
* (`Callable`), an attribute (`Attribute`), a field (`Field`), a property
|
||||
* (`Property`), an indexer (`Indexer`), or a parameter (`Parameter`).
|
||||
*/
|
||||
class ControlFlowEntryElement extends Element, @top_level_exprorstmt_parent { }
|
||||
|
||||
/**
|
||||
* A program element that can possess control flow. That is, either a statement or
|
||||
* an expression.
|
||||
|
||||
@@ -239,38 +239,55 @@ module ControlFlow {
|
||||
/** Holds if this node has more than one successor. */
|
||||
predicate isBranch() { strictcount(this.getASuccessor()) > 1 }
|
||||
|
||||
/** Gets the enclosing callable of this control flow node. */
|
||||
/** Gets the enclosing callable of this control flow node, if any. */
|
||||
Callable getEnclosingCallable() { none() }
|
||||
|
||||
/** Gets the enclosing entry element of this control flow node. */
|
||||
ControlFlowEntryElement getEnclosingElement() { none() }
|
||||
}
|
||||
|
||||
/** Provides different types of control flow nodes. */
|
||||
module Nodes {
|
||||
/** A node for a callable entry point. */
|
||||
private import semmle.code.csharp.Enclosing::Internal
|
||||
|
||||
/** An entry node, for example a callable or a field initializer. */
|
||||
class EntryNode extends Node, TEntryNode {
|
||||
/** Gets the callable that this entry applies to. */
|
||||
Callable getCallable() { this = TEntryNode(result) }
|
||||
private ControlFlowEntryElement e;
|
||||
|
||||
EntryNode() { this = TEntryNode(e) }
|
||||
|
||||
/** Gets the callable that this entry applies to, if any. */
|
||||
Callable getCallable() { result = e }
|
||||
|
||||
override BasicBlocks::EntryBlock getBasicBlock() { result = Node.super.getBasicBlock() }
|
||||
|
||||
override Callable getEnclosingCallable() { result = this.getCallable() }
|
||||
|
||||
override Location getLocation() { result = getCallable().getLocation() }
|
||||
override ControlFlowEntryElement getEnclosingElement() { result = e }
|
||||
|
||||
override string toString() { result = "enter " + getCallable().toString() }
|
||||
override Location getLocation() { result = this.getEnclosingElement().getLocation() }
|
||||
|
||||
override string toString() { result = "enter " + this.getEnclosingElement().toString() }
|
||||
}
|
||||
|
||||
/** A node for a callable exit point. */
|
||||
/** An exit node, for example a callable or a field initializer. */
|
||||
class ExitNode extends Node, TExitNode {
|
||||
/** Gets the callable that this exit applies to. */
|
||||
Callable getCallable() { this = TExitNode(result) }
|
||||
private ControlFlowEntryElement e;
|
||||
|
||||
ExitNode() { this = TExitNode(e) }
|
||||
|
||||
/** Gets the callable that this exit applies to, if any. */
|
||||
Callable getCallable() { result = e }
|
||||
|
||||
override BasicBlocks::ExitBlock getBasicBlock() { result = Node.super.getBasicBlock() }
|
||||
|
||||
override Callable getEnclosingCallable() { result = this.getCallable() }
|
||||
|
||||
override Location getLocation() { result = getCallable().getLocation() }
|
||||
override ControlFlowEntryElement getEnclosingElement() { result = e }
|
||||
|
||||
override string toString() { result = "exit " + getCallable().toString() }
|
||||
override Location getLocation() { result = this.getEnclosingElement().getLocation() }
|
||||
|
||||
override string toString() { result = "exit " + this.getEnclosingElement().toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,6 +306,10 @@ module ControlFlow {
|
||||
|
||||
override Callable getEnclosingCallable() { result = cfe.getEnclosingCallable() }
|
||||
|
||||
override ControlFlowEntryElement getEnclosingElement() {
|
||||
exprEnclosingEntryElement(cfe, result)
|
||||
}
|
||||
|
||||
override ControlFlowElement getElement() { result = cfe }
|
||||
|
||||
override string toString() {
|
||||
@@ -1824,27 +1845,32 @@ module ControlFlow {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the control flow element that is first executed when entering
|
||||
* callable `c`.
|
||||
* Gets the control flow element that is first executed when entering `e`.
|
||||
*/
|
||||
ControlFlowElement succEntry(@top_level_exprorstmt_parent p) {
|
||||
p = any(Callable c |
|
||||
ControlFlowElement succEntry(ControlFlowEntryElement e) {
|
||||
e = any(Callable c |
|
||||
if exists(c.(Constructor).getInitializer())
|
||||
then result = first(c.(Constructor).getInitializer())
|
||||
else result = first(c.getBody())
|
||||
)
|
||||
or
|
||||
expr_parent_top_level_adjusted(any(Expr e | result = first(e)), _, p) and
|
||||
not p instanceof Callable
|
||||
expr_parent_top_level_adjusted(any(Expr e0 | result = first(e0)), _, e) and
|
||||
not e instanceof Callable
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the callable that is exited when `cfe` finishes with completion `c`,
|
||||
* Gets the element that is exited when `cfe` finishes with completion `c`,
|
||||
* if any.
|
||||
*/
|
||||
Callable succExit(ControlFlowElement cfe, Completion c) {
|
||||
cfe = last(result.getBody(), c) and
|
||||
ControlFlowEntryElement succExit(ControlFlowElement cfe, Completion c) {
|
||||
cfe = last(result.(Callable).getBody(), c) and
|
||||
not c instanceof GotoCompletion
|
||||
or
|
||||
exists(Expr e |
|
||||
expr_parent_top_level_adjusted(e, _, result) and
|
||||
cfe = last(e, c) and
|
||||
not result instanceof Callable
|
||||
)
|
||||
}
|
||||
}
|
||||
import Successor
|
||||
@@ -1859,13 +1885,13 @@ module ControlFlow {
|
||||
*/
|
||||
cached
|
||||
newtype TNode =
|
||||
TEntryNode(Callable c) {
|
||||
TEntryNode(ControlFlowEntryElement e) {
|
||||
Stages::ControlFlowStage::forceCachingInSameStage() and
|
||||
succEntrySplits(c, _, _, _)
|
||||
succEntrySplits(e, _, _, _)
|
||||
} or
|
||||
TExitNode(Callable c) {
|
||||
TExitNode(ControlFlowEntryElement e) {
|
||||
exists(Reachability::SameSplitsBlock b | b.isReachable(_) |
|
||||
succExitSplits(b.getAnElement(), _, c, _)
|
||||
succExitSplits(b.getAnElement(), _, e, _)
|
||||
)
|
||||
} or
|
||||
TElementNode(ControlFlowElement cfe, Splits splits) {
|
||||
@@ -1875,18 +1901,20 @@ module ControlFlow {
|
||||
/** Gets a successor node of a given flow type, if any. */
|
||||
cached
|
||||
Node getASuccessorByType(Node pred, SuccessorType t) {
|
||||
// Callable entry node -> callable body
|
||||
exists(ControlFlowElement succElement, Splits succSplits |
|
||||
result = TElementNode(succElement, succSplits)
|
||||
|
|
||||
succEntrySplits(pred.(Nodes::EntryNode).getCallable(), succElement, succSplits, t)
|
||||
// Entry node -> body
|
||||
exists(ControlFlowElement succElement, Splits succSplits, ControlFlowEntryElement e |
|
||||
result = TElementNode(succElement, succSplits) and
|
||||
pred = TEntryNode(e) and
|
||||
succEntrySplits(e, succElement, succSplits, t)
|
||||
)
|
||||
or
|
||||
exists(ControlFlowElement predElement, Splits predSplits |
|
||||
pred = TElementNode(predElement, predSplits)
|
||||
|
|
||||
// Element node -> callable exit
|
||||
succExitSplits(predElement, predSplits, result.(Nodes::ExitNode).getCallable(), t)
|
||||
// Element node -> exit node
|
||||
exists(ControlFlowEntryElement e | result = TExitNode(e) |
|
||||
succExitSplits(predElement, predSplits, e, t)
|
||||
)
|
||||
or
|
||||
// Element node -> element node
|
||||
exists(ControlFlowElement succElement, Splits succSplits, Completion c |
|
||||
|
||||
@@ -836,7 +836,7 @@ class Splits extends TSplits {
|
||||
*/
|
||||
pragma[noinline]
|
||||
predicate succEntrySplits(
|
||||
@top_level_exprorstmt_parent pred, ControlFlowElement succ, Splits succSplits, SuccessorType t
|
||||
ControlFlowEntryElement pred, ControlFlowElement succ, Splits succSplits, SuccessorType t
|
||||
) {
|
||||
succ = succEntry(pred) and
|
||||
t instanceof NormalSuccessor and
|
||||
@@ -847,7 +847,9 @@ predicate succEntrySplits(
|
||||
* Holds if `pred` with splits `predSplits` can exit the enclosing callable
|
||||
* `succ` with type `t`.
|
||||
*/
|
||||
predicate succExitSplits(ControlFlowElement pred, Splits predSplits, Callable succ, SuccessorType t) {
|
||||
predicate succExitSplits(
|
||||
ControlFlowElement pred, Splits predSplits, ControlFlowEntryElement succ, SuccessorType t
|
||||
) {
|
||||
exists(Reachability::SameSplitsBlock b, Completion c | pred = b.getAnElement() |
|
||||
b.isReachable(predSplits) and
|
||||
t.matchesCompletion(c) and
|
||||
|
||||
@@ -59,7 +59,7 @@ class Expr extends DotNet::Expr, ControlFlowElement, @expr {
|
||||
final Stmt getEnclosingStmt() { enclosingStmt(this, result) }
|
||||
|
||||
/** Gets the enclosing callable of this expression, if any. */
|
||||
override Callable getEnclosingCallable() { exprEnclosingCallable(this, result) }
|
||||
override Callable getEnclosingCallable() { exprEnclosingEntryElement(this, result) }
|
||||
|
||||
/**
|
||||
* Holds if this expression is generated by the compiler and does not appear
|
||||
|
||||
@@ -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:3:9:3:9 | enter F | Initializers.cs:3:9:3:9 | exit F | 7 |
|
||||
| Initializers.cs:4:9:4:9 | enter G | Initializers.cs:4:9:4:9 | exit G | 8 |
|
||||
| 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:14:16:14:16 | enter H | Initializers.cs:14:16:14:16 | exit H | 4 |
|
||||
| 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 |
|
||||
|
||||
@@ -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:3:9:3:9 | enter F | Initializers.cs:3:9:3:9 | enter F |
|
||||
| post | Initializers.cs:4:9:4:9 | enter G | Initializers.cs:4:9:4:9 | enter G |
|
||||
| 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:14:16:14:16 | enter H | Initializers.cs:14:16:14:16 | enter H |
|
||||
| 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:3:9:3:9 | enter F | Initializers.cs:3:9:3:9 | enter F |
|
||||
| pre | Initializers.cs:4:9:4:9 | enter G | Initializers.cs:4:9:4:9 | enter G |
|
||||
| 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:14:16:14:16 | enter H | Initializers.cs:14:16:14:16 | enter H |
|
||||
| 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 |
|
||||
|
||||
@@ -1203,11 +1203,15 @@
|
||||
| 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 | exit F | Initializers.cs:3:9:3:17 | ... = ... |
|
||||
| post | Initializers.cs:3:9:3:9 | this access | Initializers.cs:3:9:3:9 | enter F |
|
||||
| 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: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:4:9:4:9 | access to property G | Initializers.cs:4:27:4:31 | ... + ... |
|
||||
| post | Initializers.cs:4:9:4:9 | exit G | Initializers.cs:4:25:4:31 | ... = ... |
|
||||
| post | Initializers.cs:4:9:4:9 | this access | Initializers.cs:4:9:4:9 | enter 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:31 | ... + ... | Initializers.cs:4:31:4:31 | 2 |
|
||||
@@ -1233,7 +1237,9 @@
|
||||
| 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:16 | exit H | Initializers.cs:14:16:14:20 | ... = ... |
|
||||
| post | Initializers.cs:14:16:14:20 | ... = ... | Initializers.cs:14:20:14:20 | 1 |
|
||||
| post | Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:16:14:16 | enter H |
|
||||
| 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 | ... ?? ... |
|
||||
@@ -3742,12 +3748,16 @@
|
||||
| pre | Foreach.cs:38:26:38:26 | String x | Foreach.cs:38:33:38:33 | Int32 y |
|
||||
| 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 | enter F | Initializers.cs:3:9:3:9 | this access |
|
||||
| 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:3:9:3:9 | exit F |
|
||||
| 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: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 | enter G | Initializers.cs:4:9:4:9 | this access |
|
||||
| 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:4:9:4:9 | exit G |
|
||||
| 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:31:4:31 | 2 | Initializers.cs:4:27:4:31 | ... + ... |
|
||||
@@ -3772,6 +3782,8 @@
|
||||
| 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:16:14:16 | enter H | Initializers.cs:14:20:14:20 | 1 |
|
||||
| pre | Initializers.cs:14:16:14:20 | ... = ... | Initializers.cs:14:16:14:16 | exit H |
|
||||
| pre | Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:16:14:20 | ... = ... |
|
||||
| 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 |
|
||||
|
||||
@@ -1357,12 +1357,16 @@
|
||||
| Foreach.cs:38:33:38:33 | Int32 y | Foreach.cs:38:18:38:34 | (..., ...) | semmle.label | successor |
|
||||
| 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 | enter F | Initializers.cs:3:9:3:9 | this access | 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:3:9:3:9 | exit F | 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 | enter G | Initializers.cs:4:9:4:9 | this access | 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:4:9:4:9 | exit G | 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 |
|
||||
@@ -1387,6 +1391,8 @@
|
||||
| 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:16:14:16 | enter H | Initializers.cs:14:20:14:20 | 1 | semmle.label | successor |
|
||||
| Initializers.cs:14:16:14:20 | ... = ... | Initializers.cs:14:16:14:16 | exit H | semmle.label | successor |
|
||||
| Initializers.cs:14:20:14:20 | 1 | Initializers.cs:14:16:14:20 | ... = ... | 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 |
|
||||
|
||||
Reference in New Issue
Block a user