Merge pull request #22035 from github/copilot/update-switch-stmt-usage

Fix Go expression-switch CFG migration to shared library
This commit is contained in:
Owen Mansel-Chan
2026-06-24 11:23:29 +01:00
committed by GitHub
11 changed files with 523 additions and 526 deletions

View File

@@ -361,9 +361,16 @@ module ControlFlow {
}
/**
* Holds if `pred` is the node for the case `testExpr` in an expression
* switch statement which is switching on `switchExpr`, and `succ` is the
* node to be executed next if the case test succeeds.
* Holds if `pred` is the node reached when a case of the expression switch
* statement switching on `switchExpr` matches, `testExpr` is one of that
* case's test expressions, and `succ` is the node to be executed next when
* the case matches.
*
* In the control-flow graph the individual case test expressions of a case
* clause all funnel into a single "matched" node for the clause, from which
* control transfers to the case body. Hence `pred` is that shared matched
* node, and the same `(pred, succ)` pair is reported once per test
* expression `testExpr` of the clause.
*/
predicate isSwitchCaseTestPassingEdge(
ControlFlow::Node pred, ControlFlow::Node succ, Expr switchExpr, Expr testExpr
@@ -372,7 +379,7 @@ module ControlFlow {
ess.getExpr() = switchExpr and
cc = ess.getACase() and
testExpr = cc.getExpr(i) and
pred.isAfter(testExpr) and
pred.isAfter(cc) and
succ.isFirstNodeOf(cc.getStmt(0))
)
}

View File

@@ -67,13 +67,42 @@ module GoCfg {
e = any(Go::ImportSpec is).getPathExpr()
or
e.getParent*() = any(Go::ArrayTypeExpr ate).getLength()
or
// The body block of a switch (expression or type) is transparent: the
// shared switch model wires control flow directly from the switch to its
// case clauses (in control-flow order) and between cases, so the
// enclosing block must not introduce its own nodes or default
// left-to-right sequencing of the case clauses.
e = any(Go::SwitchStmt sw).getBody()
or
// The test statement of a type switch (`y := x.(type)` or the bare
// `x.(type)` expression statement) is transparent: the shared switch
// model evaluates the underlying type-assertion expression directly as
// the switch expression (see `Switch.getExpr`), so the wrapping
// statement must not introduce its own assignment or expression nodes.
e = any(Go::TypeSwitchStmt ts).getTest()
}
AstNode getChild(AstNode n, int index) {
not n instanceof Go::FuncDef and
not skipCfg(n) and
not skipCfg(result) and
result = n.getChild(index)
(
not n instanceof Go::FuncDef and
not skipCfg(n) and
result = n.getChild(index)
or
// The body block of a switch (expression or type) is transparent (see
// `skipCfg`), so it is not itself a child and contributes no children.
// Expose the case clauses directly as children of the switch instead,
// so that the AST child chain stays connected for abrupt-completion
// propagation (e.g. a panicking call in a case body reaching the
// enclosing function's exceptional exit).
result = n.(Go::SwitchStmt).getBody().getChild(index)
or
// The type-switch test statement is transparent (see `skipCfg`), so
// expose the underlying type-assertion expression directly as a child
// of the type switch, keeping the AST child chain connected.
result = n.(Go::TypeSwitchStmt).getExpr() and index = 1
) and
not skipCfg(result)
}
class Callable extends AstNode {
@@ -124,7 +153,17 @@ module GoCfg {
}
}
class ExprStmt = Go::ExprStmt;
class ExprStmt extends Stmt instanceof Go::ExprStmt {
// The `x.(type)` test statement of a type switch is transparent (see
// `skipCfg`): the shared switch model evaluates the underlying
// type-assertion expression directly as the switch expression. It must
// therefore not be treated as an ordinary expression statement, whose
// value would otherwise be propagated from the expression to the
// statement (creating a spurious flow into the transparent wrapper).
ExprStmt() { not this = any(Go::TypeSwitchStmt ts).getTest() }
Expr getExpr() { result = Go::ExprStmt.super.getExpr() }
}
class IfStmt extends Stmt {
IfStmt() { this instanceof Go::IfStmt }
@@ -217,19 +256,39 @@ module GoCfg {
}
class Switch extends AstNode {
Switch() { none() }
Switch() { this instanceof Go::SwitchStmt }
Expr getExpr() { none() }
Expr getExpr() {
result = this.(Go::ExpressionSwitchStmt).getExpr()
or
// For a type switch the "switch expression" is the type-assertion
// expression `x.(type)`; evaluating it directly (rather than the
// wrapping `y := x.(type)` statement) lets the shared switch model
// drive the per-case type tests.
result = this.(Go::TypeSwitchStmt).getExpr()
}
Case getCase(int index) { none() }
Case getCase(int index) { result = this.(Go::SwitchStmt).getCase(index) }
Stmt getStmt(int index) { none() }
Stmt getStmt(int index) {
// Go nests each case clause's body statements under the clause rather
// than in a flat list, so we expose a flattened view in which every
// case clause is immediately followed by its own body statements. This
// lets the shared library compute the body of a case as the statements
// between it and the next clause.
result =
rank[index + 1](Go::Stmt s, int caseIdx, int inner |
switchFlatItem(this, s, caseIdx, inner)
|
s order by caseIdx, inner
)
}
}
class Case extends AstNode {
Case() { none() }
Case() { this = any(Go::SwitchStmt sw).getACase() }
AstNode getPattern(int index) { none() }
AstNode getPattern(int index) { result = this.(Go::CaseClause).getExpr(index) }
Expr getGuard() { none() }
@@ -237,7 +296,34 @@ module GoCfg {
}
class DefaultCase extends Case {
DefaultCase() { none() }
DefaultCase() { not exists(this.(Go::CaseClause).getExpr(_)) }
}
/** Gets the initializer of `switch` statement `switch`, if any. */
AstNode getSwitchInit(Switch switch) { result = switch.(Go::SwitchStmt).getInit() }
/**
* Go has no implicit fall-through between case clauses; a case that runs to
* the end of its body breaks out of the switch. Fall-through only happens
* when the case body ends with an explicit `fallthrough` statement, in
* which case control transfers to the next case clause's body (in source
* order). The shared library models this by chaining the body of such a
* case to the body of the following case.
*/
predicate fallsThrough(Case c) {
c.(Go::CaseClause).getStmt(max(int i | exists(c.(Go::CaseClause).getStmt(i)))) instanceof
Go::FallthroughStmt
}
/**
* Holds if `s` is the flattened body element at position (`caseIdx`,
* `inner`) of switch `sw`: either the `caseIdx`-th case clause itself (with
* `inner` = -1) or its `inner`-th body statement.
*/
private predicate switchFlatItem(Go::SwitchStmt sw, Go::Stmt s, int caseIdx, int inner) {
s = sw.getCase(caseIdx) and inner = -1
or
s = sw.getCase(caseIdx).getStmt(inner)
}
class ConditionalExpr extends Expr {
@@ -315,16 +401,10 @@ module GoCfg {
class CallableContext = Void;
private newtype TLabel =
TGoLabel(string l) { exists(Go::LabeledStmt ls | l = ls.getLabel()) } or
TFallthrough()
private newtype TLabel = TGoLabel(string l) { exists(Go::LabeledStmt ls | l = ls.getLabel()) }
class Label extends TLabel {
string toString() {
exists(string l | this = TGoLabel(l) and result = l)
or
this = TFallthrough() and result = "fallthrough"
}
string toString() { exists(string l | this = TGoLabel(l) and result = l) }
}
private Label getLabelOfStmt(Go::Stmt s) {
@@ -339,19 +419,11 @@ module GoCfg {
l = TGoLabel(n.(Go::BreakStmt).getLabel())
or
l = TGoLabel(n.(Go::ContinueStmt).getLabel())
or
l = TFallthrough() and n instanceof Go::FallthroughStmt
}
predicate inConditionalContext(Ast::AstNode n, ConditionKind kind) {
kind.isBoolean() and
(
n = any(Go::ForStmt fs).getCond()
or
exists(Go::ExpressionSwitchStmt ess |
not exists(ess.getExpr()) and n = ess.getACase().(Go::CaseClause).getExpr(_)
)
)
n = any(Go::ForStmt fs).getCond()
}
predicate preOrderExpr(Ast::Expr e) {
@@ -425,6 +497,11 @@ module GoCfg {
or
notBlankIdent(n.(Go::RangeStmt).getValue()) and i = 1
) and
// The `y := x.(type)` test statement of a type switch is transparent
// (see `skipCfg`): the per-case implicit variables are written at the
// case match nodes (see `IR::TypeSwitchImplicitVariableInstruction`),
// so the guard itself emits no assignment write node.
not n = any(Go::TypeSwitchStmt ts).getTest() and
tag = "assign:" + i.toString()
)
or
@@ -515,25 +592,6 @@ module GoCfg {
not exists(n.(Go::SliceExpr).getMax()) and
tag = "implicit-max"
or
// Implicit true in tagless switch
n instanceof Go::ExpressionSwitchStmt and
not exists(n.(Go::ExpressionSwitchStmt).getExpr()) and
tag = "implicit-true"
or
// Case check nodes
exists(int i |
exists(n.(Go::CaseClause).getExpr(i)) and
tag = "case-check:" + i.toString()
)
or
// Type switch implicit variable
exists(Go::TypeSwitchStmt ts, Go::DefineStmt ds |
ds = ts.getAssign() and
n.(Go::CaseClause) = ts.getACase() and
exists(n.(Go::CaseClause).getImplicitlyDeclaredVariable()) and
tag = "type-switch-var"
)
or
// Literal element initialization
n = any(Go::CompositeLit lit).getAnElement() and
tag = "lit-init"
@@ -709,12 +767,6 @@ module GoCfg {
c.asSimpleAbruptCompletion() instanceof ExceptionSuccessor and
always = false
or
ast instanceof Go::FallthroughStmt and
n.injects(ast) and
c.getSuccessorType() instanceof BreakSuccessor and
c.hasLabel(TFallthrough()) and
always = true
or
ast instanceof Go::GotoStmt and
n.injects(ast) and
c.getSuccessorType() instanceof GotoSuccessor and
@@ -916,7 +968,6 @@ module GoCfg {
predicate step(PreControlFlowNode n1, PreControlFlowNode n2) {
rangeLoop(n1, n2) or
switchStmt(n1, n2) or
selectStmt(n1, n2) or
deferStmt(n1, n2) or
goStmtStep(n1, n2) or
@@ -980,7 +1031,12 @@ module GoCfg {
assgn instanceof Go::Assignment and not assgn instanceof Go::RecvStmt
or
assgn instanceof Go::ValueSpec
)
) and
// The `y := x.(type)` test statement of a type switch is transparent
// (see `skipCfg`); the shared switch model evaluates the underlying
// type-assertion expression directly, so this statement has no
// assignment flow of its own.
not assgn = any(Go::TypeSwitchStmt ts).getTest()
|
// Route through children (LHS names, RHS expressions)
childSequenceStep(assgn, n1, n2)
@@ -1402,187 +1458,6 @@ module GoCfg {
)
}
private predicate switchStmt(PreControlFlowNode n1, PreControlFlowNode n2) {
exprSwitch(n1, n2) or typeSwitch(n1, n2) or caseClause(n1, n2)
}
private predicate switchCasesStartOrAfter(Go::SwitchStmt sw, PreControlFlowNode n) {
n.isBefore(sw.getNonDefaultCase(0))
or
not exists(sw.getANonDefaultCase()) and n.isBefore(sw.getDefault())
or
not exists(sw.getACase()) and n.isAfter(sw)
}
private predicate exprSwitch(PreControlFlowNode n1, PreControlFlowNode n2) {
exists(Go::ExpressionSwitchStmt sw |
n1.isBefore(sw) and
(
n2.isBefore(sw.getInit())
or
not exists(sw.getInit()) and
(
n2.isBefore(sw.getExpr())
or
not exists(sw.getExpr()) and switchCasesStartOrAfter(sw, n2)
)
)
or
n1.isAfter(sw.getInit()) and
(
n2.isBefore(sw.getExpr())
or
not exists(sw.getExpr()) and switchCasesStartOrAfter(sw, n2)
)
or
n1.isAfter(sw.getExpr()) and switchCasesStartOrAfter(sw, n2)
)
}
private predicate typeSwitch(PreControlFlowNode n1, PreControlFlowNode n2) {
exists(Go::TypeSwitchStmt sw |
n1.isBefore(sw) and
(
n2.isBefore(sw.getInit())
or
not exists(sw.getInit()) and n2.isBefore(sw.getTest())
)
or
n1.isAfter(sw.getInit()) and n2.isBefore(sw.getTest())
or
n1.isAfter(sw.getTest()) and switchCasesStartOrAfter(sw, n2)
)
}
/**
* Holds if `sw` is a tagless expression switch, in which case the case
* expressions are themselves the boolean conditions being tested and are
* therefore in a boolean conditional context.
*/
private predicate isBooleanSwitch(Go::SwitchStmt sw) {
sw instanceof Go::ExpressionSwitchStmt and
not exists(sw.(Go::ExpressionSwitchStmt).getExpr())
}
/**
* Holds if `n` is the control-flow node immediately after evaluating case
* expression `caseExpr` of switch `sw` on the branch where `caseExpr`
* matches.
*/
private predicate afterCaseExprMatch(Go::SwitchStmt sw, Go::Expr caseExpr, PreControlFlowNode n) {
caseExpr = sw.getACase().(Go::CaseClause).getAnExpr() and
(
isBooleanSwitch(sw) and n.isAfterTrue(caseExpr)
or
not isBooleanSwitch(sw) and n.isAfter(caseExpr)
)
}
/**
* Holds if `n` is the control-flow node immediately after evaluating case
* expression `caseExpr` of switch `sw` on the branch where `caseExpr`
* does not match.
*/
private predicate afterCaseExprNoMatch(
Go::SwitchStmt sw, Go::Expr caseExpr, PreControlFlowNode n
) {
caseExpr = sw.getACase().(Go::CaseClause).getAnExpr() and
(
isBooleanSwitch(sw) and n.isAfterFalse(caseExpr)
or
not isBooleanSwitch(sw) and n.isAfter(caseExpr)
)
}
/**
* Holds if `cc` is a case clause of a type switch with an assignment that
* implicitly declares a variable whose type narrows to the case type. In
* this situation the CFG inserts a `type-switch-var` additional node
* between the case test and the case body, on which the IR layer
* materialises the implicit assignment to that variable.
*/
private predicate hasTypeSwitchVar(Go::CaseClause cc) {
exists(Go::TypeSwitchStmt ts |
ts.getACase() = cc and
exists(ts.getAssign()) and
exists(cc.getImplicitlyDeclaredVariable())
)
}
private predicate caseClause(PreControlFlowNode n1, PreControlFlowNode n2) {
exists(Go::SwitchStmt sw, Go::CaseClause cc, int i | cc = sw.getNonDefaultCase(i) |
n1.isBefore(cc) and n2.isBefore(cc.getExpr(0))
or
// For a tagless expression switch the case expressions are themselves
// booleans in a conditional context, so we only fall through to the
// next case expression on the false branch.
exists(int j |
afterCaseExprNoMatch(sw, cc.getExpr(j), n1) and n2.isBefore(cc.getExpr(j + 1))
)
or
exists(int last | last = max(int j | exists(cc.getExpr(j))) |
afterCaseExprMatch(sw, cc.getExpr(last), n1) and
(
hasTypeSwitchVar(cc) and n2.isAdditional(cc, "type-switch-var")
or
not hasTypeSwitchVar(cc) and
(
n2.isBefore(cc.getStmt(0))
or
not exists(cc.getStmt(0)) and n2.isAfter(sw)
)
)
or
afterCaseExprNoMatch(sw, cc.getExpr(last), n1) and
(
n2.isBefore(sw.getNonDefaultCase(i + 1))
or
not exists(sw.getNonDefaultCase(i + 1)) and n2.isBefore(sw.getDefault())
or
not exists(sw.getNonDefaultCase(i + 1)) and
not exists(sw.getDefault()) and
n2.isAfter(sw)
)
)
)
or
exists(Go::SwitchStmt sw, Go::CaseClause def | def = sw.getDefault() |
n1.isBefore(def) and
(
hasTypeSwitchVar(def) and n2.isAdditional(def, "type-switch-var")
or
not hasTypeSwitchVar(def) and
(
n2.isBefore(def.getStmt(0))
or
not exists(def.getStmt(0)) and n2.isAfter(sw)
)
)
)
or
exists(Go::SwitchStmt sw, Go::CaseClause cc |
sw.getACase() = cc and
hasTypeSwitchVar(cc) and
n1.isAdditional(cc, "type-switch-var") and
(
n2.isBefore(cc.getStmt(0))
or
not exists(cc.getStmt(0)) and n2.isAfter(sw)
)
)
or
exists(Go::CaseClause cc |
exists(int j | n1.isAfter(cc.getStmt(j)) and n2.isBefore(cc.getStmt(j + 1)))
or
exists(Go::SwitchStmt sw, int last |
sw.getACase() = cc and
last = max(int j | exists(cc.getStmt(j))) and
n1.isAfter(cc.getStmt(last)) and
n2.isAfter(sw)
)
)
}
private predicate commClauseBodyStart(
Go::SelectStmt sel, Go::CommClause cc, PreControlFlowNode n
) {

View File

@@ -14,6 +14,7 @@ module;
import go
private import ControlFlowGraphShared
private import codeql.controlflow.SuccessorType
/** Provides predicates and classes for working with IR constructs. */
module IR {
@@ -43,6 +44,20 @@ module IR {
e = any(ParenExpr pe | isInBooleanCondContext(pe)).getExpr()
}
/**
* Holds if `n` is the control-flow node representing a successful match of
* the type-switch case clause `cc` that implicitly declares a variable.
*
* This node dominates the case body and is where the implicit per-case
* variable declaration/assignment is materialised (see
* `TypeSwitchImplicitVariableInstruction`).
*/
private predicate typeSwitchCaseMatch(ControlFlow::Node n, CaseClause cc) {
cc = any(TypeSwitchStmt ts).getACase() and
exists(cc.getImplicitlyDeclaredVariable()) and
n.isAfterValue(cc, any(MatchingSuccessor t | t.getValue() = true))
}
/**
* An IR instruction.
*/
@@ -56,6 +71,11 @@ module IR {
or
this.isAfterFalse(_)
or
// The successful-match node of a type-switch case that binds an implicit
// variable hosts that variable's declaration/assignment (see
// `TypeSwitchImplicitVariableInstruction`).
typeSwitchCaseMatch(this, _)
or
// `NotExpr` and `LogicalBinaryExpr` are not in `postOrInOrder`, so they
// have no `isIn` node. When such an expression is not in a conditional
// context (so it has a single combined after-node rather than per-branch
@@ -1182,7 +1202,7 @@ module IR {
class TypeSwitchImplicitVariableInstruction extends Instruction {
CaseClause cc;
TypeSwitchImplicitVariableInstruction() { this.isAdditional(cc, "type-switch-var") }
TypeSwitchImplicitVariableInstruction() { typeSwitchCaseMatch(this, cc) }
override predicate writes(ValueEntity v, Instruction rhs) {
v = cc.getImplicitlyDeclaredVariable() and

View File

@@ -341,10 +341,22 @@ private ControlFlow::Node getANonTestPassingPredecessor(
) {
isPossibleInputNode(inputNode, succ.getRoot()) and
result = succ.getAPredecessor() and
not exists(Expr testExpr, DataFlow::Node switchExprNode |
not exists(DataFlow::Node switchExprNode |
flowsToSwitchExpression(inputNode, switchExprNode) and
ControlFlow::isSwitchCaseTestPassingEdge(result, succ, switchExprNode.asExpr(), testExpr) and
testExpr.isConst()
// The case body is reachable only by matching a constant: at least one of
// the case's test expressions is constant, and none of them is
// non-constant. (All test expressions of a case share the same matched
// edge `result -> succ`, so a case mixing constant and non-constant tests
// must not be treated as a constant-only match.)
exists(Expr testExpr |
ControlFlow::isSwitchCaseTestPassingEdge(result, succ, switchExprNode.asExpr(), testExpr) and
testExpr.isConst()
) and
not exists(Expr nonConstTestExpr |
ControlFlow::isSwitchCaseTestPassingEdge(result, succ, switchExprNode.asExpr(),
nonConstTestExpr) and
not nonConstTestExpr.isConst()
)
)
}

View File

@@ -14,14 +14,16 @@
| DuplicateSwitchCase.go:3:29:12:1 | param-init:0 block statement | DuplicateSwitchCase.go:4:2:11:2 | expression-switch statement |
| DuplicateSwitchCase.go:4:2:11:2 | After expression-switch statement | DuplicateSwitchCase.go:3:29:12:1 | After block statement |
| DuplicateSwitchCase.go:4:2:11:2 | expression-switch statement | DuplicateSwitchCase.go:5:2:6:9 | case clause |
| DuplicateSwitchCase.go:5:2:6:9 | After case clause [match] | DuplicateSwitchCase.go:6:3:6:9 | expression statement |
| DuplicateSwitchCase.go:5:2:6:9 | After case clause [no-match] | DuplicateSwitchCase.go:7:2:8:8 | case clause |
| DuplicateSwitchCase.go:5:2:6:9 | case clause | DuplicateSwitchCase.go:5:7:5:20 | Before ...==... |
| DuplicateSwitchCase.go:5:7:5:9 | After msg | DuplicateSwitchCase.go:5:14:5:20 | Before "start" |
| DuplicateSwitchCase.go:5:7:5:9 | Before msg | DuplicateSwitchCase.go:5:7:5:9 | msg |
| DuplicateSwitchCase.go:5:7:5:9 | msg | DuplicateSwitchCase.go:5:7:5:9 | After msg |
| DuplicateSwitchCase.go:5:7:5:20 | ...==... | DuplicateSwitchCase.go:5:7:5:20 | After ...==... [false] |
| DuplicateSwitchCase.go:5:7:5:20 | ...==... | DuplicateSwitchCase.go:5:7:5:20 | After ...==... [true] |
| DuplicateSwitchCase.go:5:7:5:20 | After ...==... [false] | DuplicateSwitchCase.go:7:2:8:8 | case clause |
| DuplicateSwitchCase.go:5:7:5:20 | After ...==... [true] | DuplicateSwitchCase.go:6:3:6:9 | expression statement |
| DuplicateSwitchCase.go:5:7:5:20 | ...==... | DuplicateSwitchCase.go:5:7:5:20 | After ...==... [match] |
| DuplicateSwitchCase.go:5:7:5:20 | ...==... | DuplicateSwitchCase.go:5:7:5:20 | After ...==... [no-match] |
| DuplicateSwitchCase.go:5:7:5:20 | After ...==... [match] | DuplicateSwitchCase.go:5:2:6:9 | After case clause [match] |
| DuplicateSwitchCase.go:5:7:5:20 | After ...==... [no-match] | DuplicateSwitchCase.go:5:2:6:9 | After case clause [no-match] |
| DuplicateSwitchCase.go:5:7:5:20 | Before ...==... | DuplicateSwitchCase.go:5:7:5:9 | Before msg |
| DuplicateSwitchCase.go:5:14:5:20 | "start" | DuplicateSwitchCase.go:5:14:5:20 | After "start" |
| DuplicateSwitchCase.go:5:14:5:20 | After "start" | DuplicateSwitchCase.go:5:7:5:20 | ...==... |
@@ -35,14 +37,16 @@
| DuplicateSwitchCase.go:6:3:6:9 | call to start | DuplicateSwitchCase.go:3:1:12:1 | Exceptional Exit |
| DuplicateSwitchCase.go:6:3:6:9 | call to start | DuplicateSwitchCase.go:6:3:6:9 | After call to start |
| DuplicateSwitchCase.go:6:3:6:9 | expression statement | DuplicateSwitchCase.go:6:3:6:9 | Before call to start |
| DuplicateSwitchCase.go:7:2:8:8 | After case clause [match] | DuplicateSwitchCase.go:8:3:8:8 | expression statement |
| DuplicateSwitchCase.go:7:2:8:8 | After case clause [no-match] | DuplicateSwitchCase.go:9:2:10:34 | case clause |
| DuplicateSwitchCase.go:7:2:8:8 | case clause | DuplicateSwitchCase.go:7:7:7:20 | Before ...==... |
| DuplicateSwitchCase.go:7:7:7:9 | After msg | DuplicateSwitchCase.go:7:14:7:20 | Before "start" |
| DuplicateSwitchCase.go:7:7:7:9 | Before msg | DuplicateSwitchCase.go:7:7:7:9 | msg |
| DuplicateSwitchCase.go:7:7:7:9 | msg | DuplicateSwitchCase.go:7:7:7:9 | After msg |
| DuplicateSwitchCase.go:7:7:7:20 | ...==... | DuplicateSwitchCase.go:7:7:7:20 | After ...==... [false] |
| DuplicateSwitchCase.go:7:7:7:20 | ...==... | DuplicateSwitchCase.go:7:7:7:20 | After ...==... [true] |
| DuplicateSwitchCase.go:7:7:7:20 | After ...==... [false] | DuplicateSwitchCase.go:9:2:10:34 | case clause |
| DuplicateSwitchCase.go:7:7:7:20 | After ...==... [true] | DuplicateSwitchCase.go:8:3:8:8 | expression statement |
| DuplicateSwitchCase.go:7:7:7:20 | ...==... | DuplicateSwitchCase.go:7:7:7:20 | After ...==... [match] |
| DuplicateSwitchCase.go:7:7:7:20 | ...==... | DuplicateSwitchCase.go:7:7:7:20 | After ...==... [no-match] |
| DuplicateSwitchCase.go:7:7:7:20 | After ...==... [match] | DuplicateSwitchCase.go:7:2:8:8 | After case clause [match] |
| DuplicateSwitchCase.go:7:7:7:20 | After ...==... [no-match] | DuplicateSwitchCase.go:7:2:8:8 | After case clause [no-match] |
| DuplicateSwitchCase.go:7:7:7:20 | Before ...==... | DuplicateSwitchCase.go:7:7:7:9 | Before msg |
| DuplicateSwitchCase.go:7:14:7:20 | "start" | DuplicateSwitchCase.go:7:14:7:20 | After "start" |
| DuplicateSwitchCase.go:7:14:7:20 | After "start" | DuplicateSwitchCase.go:7:7:7:20 | ...==... |
@@ -56,7 +60,8 @@
| DuplicateSwitchCase.go:8:3:8:8 | call to stop | DuplicateSwitchCase.go:3:1:12:1 | Exceptional Exit |
| DuplicateSwitchCase.go:8:3:8:8 | call to stop | DuplicateSwitchCase.go:8:3:8:8 | After call to stop |
| DuplicateSwitchCase.go:8:3:8:8 | expression statement | DuplicateSwitchCase.go:8:3:8:8 | Before call to stop |
| DuplicateSwitchCase.go:9:2:10:34 | case clause | DuplicateSwitchCase.go:10:3:10:34 | expression statement |
| DuplicateSwitchCase.go:9:2:10:34 | After case clause [match] | DuplicateSwitchCase.go:10:3:10:34 | expression statement |
| DuplicateSwitchCase.go:9:2:10:34 | case clause | DuplicateSwitchCase.go:9:2:10:34 | After case clause [match] |
| DuplicateSwitchCase.go:10:3:10:7 | After panic | DuplicateSwitchCase.go:10:9:10:33 | Before "Message not understood." |
| DuplicateSwitchCase.go:10:3:10:7 | Before panic | DuplicateSwitchCase.go:10:3:10:7 | panic |
| DuplicateSwitchCase.go:10:3:10:7 | panic | DuplicateSwitchCase.go:10:3:10:7 | After panic |
@@ -3618,7 +3623,8 @@
| stmts.go:79:21:79:22 | 19 | stmts.go:79:21:79:22 | After 19 |
| stmts.go:79:21:79:22 | After 19 | stmts.go:79:17:79:22 | ...-... |
| stmts.go:79:21:79:22 | Before 19 | stmts.go:79:21:79:22 | 19 |
| stmts.go:80:2:81:14 | case clause | stmts.go:81:3:81:14 | expression statement |
| stmts.go:80:2:81:14 | After case clause [match] | stmts.go:81:3:81:14 | expression statement |
| stmts.go:80:2:81:14 | case clause | stmts.go:80:2:81:14 | After case clause [match] |
| stmts.go:81:3:81:7 | After test5 | stmts.go:81:9:81:13 | Before false |
| stmts.go:81:3:81:7 | Before test5 | stmts.go:81:3:81:7 | test5 |
| stmts.go:81:3:81:7 | test5 | stmts.go:81:3:81:7 | After test5 |
@@ -3636,18 +3642,26 @@
| stmts.go:84:9:84:9 | After x | stmts.go:85:2:85:8 | case clause |
| stmts.go:84:9:84:9 | Before x | stmts.go:84:9:84:9 | x |
| stmts.go:84:9:84:9 | x | stmts.go:84:9:84:9 | After x |
| stmts.go:85:2:85:8 | After case clause [match] | stmts.go:84:2:88:2 | After expression-switch statement |
| stmts.go:85:2:85:8 | After case clause [no-match] | stmts.go:86:2:87:13 | case clause |
| stmts.go:85:2:85:8 | case clause | stmts.go:85:7:85:7 | Before 1 |
| stmts.go:85:7:85:7 | 1 | stmts.go:85:7:85:7 | After 1 |
| stmts.go:85:7:85:7 | After 1 | stmts.go:84:2:88:2 | After expression-switch statement |
| stmts.go:85:7:85:7 | After 1 | stmts.go:86:2:87:13 | case clause |
| stmts.go:85:7:85:7 | 1 | stmts.go:85:7:85:7 | After 1 [match] |
| stmts.go:85:7:85:7 | 1 | stmts.go:85:7:85:7 | After 1 [no-match] |
| stmts.go:85:7:85:7 | After 1 [match] | stmts.go:85:2:85:8 | After case clause [match] |
| stmts.go:85:7:85:7 | After 1 [no-match] | stmts.go:85:2:85:8 | After case clause [no-match] |
| stmts.go:85:7:85:7 | Before 1 | stmts.go:85:7:85:7 | 1 |
| stmts.go:86:2:87:13 | After case clause [match] | stmts.go:87:3:87:13 | expression statement |
| stmts.go:86:2:87:13 | After case clause [no-match] | stmts.go:84:2:88:2 | After expression-switch statement |
| stmts.go:86:2:87:13 | case clause | stmts.go:86:7:86:7 | Before 2 |
| stmts.go:86:7:86:7 | 2 | stmts.go:86:7:86:7 | After 2 |
| stmts.go:86:7:86:7 | After 2 | stmts.go:86:10:86:10 | Before 3 |
| stmts.go:86:7:86:7 | 2 | stmts.go:86:7:86:7 | After 2 [match] |
| stmts.go:86:7:86:7 | 2 | stmts.go:86:7:86:7 | After 2 [no-match] |
| stmts.go:86:7:86:7 | After 2 [match] | stmts.go:86:2:87:13 | After case clause [match] |
| stmts.go:86:7:86:7 | After 2 [no-match] | stmts.go:86:10:86:10 | Before 3 |
| stmts.go:86:7:86:7 | Before 2 | stmts.go:86:7:86:7 | 2 |
| stmts.go:86:10:86:10 | 3 | stmts.go:86:10:86:10 | After 3 |
| stmts.go:86:10:86:10 | After 3 | stmts.go:84:2:88:2 | After expression-switch statement |
| stmts.go:86:10:86:10 | After 3 | stmts.go:87:3:87:13 | expression statement |
| stmts.go:86:10:86:10 | 3 | stmts.go:86:10:86:10 | After 3 [match] |
| stmts.go:86:10:86:10 | 3 | stmts.go:86:10:86:10 | After 3 [no-match] |
| stmts.go:86:10:86:10 | After 3 [match] | stmts.go:86:2:87:13 | After case clause [match] |
| stmts.go:86:10:86:10 | After 3 [no-match] | stmts.go:86:2:87:13 | After case clause [no-match] |
| stmts.go:86:10:86:10 | Before 3 | stmts.go:86:10:86:10 | 3 |
| stmts.go:87:3:87:7 | After test5 | stmts.go:87:9:87:12 | Before true |
| stmts.go:87:3:87:7 | Before test5 | stmts.go:87:3:87:7 | test5 |
@@ -3666,10 +3680,13 @@
| stmts.go:90:9:90:9 | After x | stmts.go:91:2:93:13 | case clause |
| stmts.go:90:9:90:9 | Before x | stmts.go:90:9:90:9 | x |
| stmts.go:90:9:90:9 | x | stmts.go:90:9:90:9 | After x |
| stmts.go:91:2:93:13 | After case clause [match] | stmts.go:92:3:92:14 | expression statement |
| stmts.go:91:2:93:13 | After case clause [no-match] | stmts.go:94:2:95:13 | case clause |
| stmts.go:91:2:93:13 | case clause | stmts.go:91:7:91:7 | Before 1 |
| stmts.go:91:7:91:7 | 1 | stmts.go:91:7:91:7 | After 1 |
| stmts.go:91:7:91:7 | After 1 | stmts.go:92:3:92:14 | expression statement |
| stmts.go:91:7:91:7 | After 1 | stmts.go:94:2:95:13 | case clause |
| stmts.go:91:7:91:7 | 1 | stmts.go:91:7:91:7 | After 1 [match] |
| stmts.go:91:7:91:7 | 1 | stmts.go:91:7:91:7 | After 1 [no-match] |
| stmts.go:91:7:91:7 | After 1 [match] | stmts.go:91:2:93:13 | After case clause [match] |
| stmts.go:91:7:91:7 | After 1 [no-match] | stmts.go:91:2:93:13 | After case clause [no-match] |
| stmts.go:91:7:91:7 | Before 1 | stmts.go:91:7:91:7 | 1 |
| stmts.go:92:3:92:7 | After test5 | stmts.go:92:9:92:13 | Before false |
| stmts.go:92:3:92:7 | Before test5 | stmts.go:92:3:92:7 | test5 |
@@ -3683,14 +3700,17 @@
| stmts.go:92:9:92:13 | After false | stmts.go:92:3:92:14 | call to test5 |
| stmts.go:92:9:92:13 | Before false | stmts.go:92:9:92:13 | false |
| stmts.go:92:9:92:13 | false | stmts.go:92:9:92:13 | After false |
| stmts.go:93:3:93:13 | fallthrough statement | stmts.go:90:2:96:2 | After expression-switch statement |
| stmts.go:93:3:93:13 | fallthrough statement | stmts.go:95:3:95:13 | expression statement |
| stmts.go:94:2:95:13 | After case clause [match] | stmts.go:95:3:95:13 | expression statement |
| stmts.go:94:2:95:13 | After case clause [no-match] | stmts.go:90:2:96:2 | After expression-switch statement |
| stmts.go:94:2:95:13 | case clause | stmts.go:94:7:94:11 | Before ...-... |
| stmts.go:94:7:94:7 | 2 | stmts.go:94:7:94:7 | After 2 |
| stmts.go:94:7:94:7 | After 2 | stmts.go:94:11:94:11 | Before 5 |
| stmts.go:94:7:94:7 | Before 2 | stmts.go:94:7:94:7 | 2 |
| stmts.go:94:7:94:11 | ...-... | stmts.go:94:7:94:11 | After ...-... |
| stmts.go:94:7:94:11 | After ...-... | stmts.go:90:2:96:2 | After expression-switch statement |
| stmts.go:94:7:94:11 | After ...-... | stmts.go:95:3:95:13 | expression statement |
| stmts.go:94:7:94:11 | ...-... | stmts.go:94:7:94:11 | After ...-... [match] |
| stmts.go:94:7:94:11 | ...-... | stmts.go:94:7:94:11 | After ...-... [no-match] |
| stmts.go:94:7:94:11 | After ...-... [match] | stmts.go:94:2:95:13 | After case clause [match] |
| stmts.go:94:7:94:11 | After ...-... [no-match] | stmts.go:94:2:95:13 | After case clause [no-match] |
| stmts.go:94:7:94:11 | Before ...-... | stmts.go:94:7:94:7 | Before 2 |
| stmts.go:94:11:94:11 | 5 | stmts.go:94:11:94:11 | After 5 |
| stmts.go:94:11:94:11 | After 5 | stmts.go:94:7:94:11 | ...-... |
@@ -3712,12 +3732,15 @@
| stmts.go:98:9:98:9 | After x | stmts.go:100:2:101:13 | case clause |
| stmts.go:98:9:98:9 | Before x | stmts.go:98:9:98:9 | x |
| stmts.go:98:9:98:9 | x | stmts.go:98:9:98:9 | After x |
| stmts.go:99:2:99:9 | case clause | stmts.go:98:2:102:2 | After expression-switch statement |
| stmts.go:99:2:99:9 | case clause | stmts.go:100:2:101:13 | case clause |
| stmts.go:99:2:99:9 | After case clause [match] | stmts.go:98:2:102:2 | After expression-switch statement |
| stmts.go:99:2:99:9 | case clause | stmts.go:99:2:99:9 | After case clause [match] |
| stmts.go:100:2:101:13 | After case clause [match] | stmts.go:101:3:101:13 | expression statement |
| stmts.go:100:2:101:13 | After case clause [no-match] | stmts.go:99:2:99:9 | case clause |
| stmts.go:100:2:101:13 | case clause | stmts.go:100:7:100:7 | Before 2 |
| stmts.go:100:7:100:7 | 2 | stmts.go:100:7:100:7 | After 2 |
| stmts.go:100:7:100:7 | After 2 | stmts.go:99:2:99:9 | case clause |
| stmts.go:100:7:100:7 | After 2 | stmts.go:101:3:101:13 | expression statement |
| stmts.go:100:7:100:7 | 2 | stmts.go:100:7:100:7 | After 2 [match] |
| stmts.go:100:7:100:7 | 2 | stmts.go:100:7:100:7 | After 2 [no-match] |
| stmts.go:100:7:100:7 | After 2 [match] | stmts.go:100:2:101:13 | After case clause [match] |
| stmts.go:100:7:100:7 | After 2 [no-match] | stmts.go:100:2:101:13 | After case clause [no-match] |
| stmts.go:100:7:100:7 | Before 2 | stmts.go:100:7:100:7 | 2 |
| stmts.go:101:3:101:7 | After test5 | stmts.go:101:9:101:12 | Before true |
| stmts.go:101:3:101:7 | Before test5 | stmts.go:101:3:101:7 | test5 |
@@ -3733,10 +3756,18 @@
| stmts.go:101:9:101:12 | true | stmts.go:101:9:101:12 | After true |
| stmts.go:104:2:108:2 | After expression-switch statement | stmts.go:75:19:109:1 | After block statement |
| stmts.go:104:2:108:2 | expression-switch statement | stmts.go:107:2:107:11 | case clause |
| stmts.go:105:2:106:7 | After case clause [match] | stmts.go:106:3:106:7 | Before break statement |
| stmts.go:105:2:106:7 | case clause | stmts.go:105:2:106:7 | After case clause [match] |
| stmts.go:106:3:106:7 | Before break statement | stmts.go:106:3:106:7 | break statement |
| stmts.go:106:3:106:7 | break statement | stmts.go:104:2:108:2 | After expression-switch statement |
| stmts.go:107:2:107:11 | After case clause [match] | stmts.go:104:2:108:2 | After expression-switch statement |
| stmts.go:107:2:107:11 | After case clause [no-match] | stmts.go:105:2:106:7 | case clause |
| stmts.go:107:2:107:11 | case clause | stmts.go:107:7:107:10 | Before true |
| stmts.go:107:7:107:10 | After true [true] | stmts.go:104:2:108:2 | After expression-switch statement |
| stmts.go:107:7:107:10 | After true [match] | stmts.go:107:2:107:11 | After case clause [match] |
| stmts.go:107:7:107:10 | After true [no-match] | stmts.go:107:2:107:11 | After case clause [no-match] |
| stmts.go:107:7:107:10 | Before true | stmts.go:107:7:107:10 | true |
| stmts.go:107:7:107:10 | true | stmts.go:107:7:107:10 | After true [true] |
| stmts.go:107:7:107:10 | true | stmts.go:107:7:107:10 | After true [match] |
| stmts.go:107:7:107:10 | true | stmts.go:107:7:107:10 | After true [no-match] |
| stmts.go:112:1:137:1 | After function declaration | stmts.go:140:1:142:1 | Before function declaration |
| stmts.go:112:1:137:1 | Before function declaration | stmts.go:112:1:137:1 | function declaration |
| stmts.go:112:1:137:1 | Entry | stmts.go:112:27:137:1 | block statement |
@@ -3748,21 +3779,24 @@
| stmts.go:112:27:137:1 | block statement | stmts.go:112:27:137:1 | arg:0 block statement |
| stmts.go:112:27:137:1 | param-init:0 block statement | stmts.go:113:2:121:2 | type-switch statement |
| stmts.go:113:2:121:2 | After type-switch statement | stmts.go:123:2:131:2 | type-switch statement |
| stmts.go:113:2:121:2 | type-switch statement | stmts.go:113:9:113:21 | ... := ... |
| stmts.go:113:9:113:21 | ... := ... | stmts.go:113:14:113:21 | Before type assertion |
| stmts.go:113:9:113:21 | After ... := ... | stmts.go:114:2:115:16 | case clause |
| stmts.go:113:9:113:21 | assign:0 ... := ... | stmts.go:113:9:113:21 | After ... := ... |
| stmts.go:113:2:121:2 | type-switch statement | stmts.go:113:14:113:21 | Before type assertion |
| stmts.go:113:14:113:14 | After x | stmts.go:113:14:113:21 | type assertion |
| stmts.go:113:14:113:14 | Before x | stmts.go:113:14:113:14 | x |
| stmts.go:113:14:113:14 | x | stmts.go:113:14:113:14 | After x |
| stmts.go:113:14:113:21 | After type assertion | stmts.go:113:9:113:21 | assign:0 ... := ... |
| stmts.go:113:14:113:21 | After type assertion | stmts.go:114:2:115:16 | case clause |
| stmts.go:113:14:113:21 | Before type assertion | stmts.go:113:14:113:14 | Before x |
| stmts.go:113:14:113:21 | type assertion | stmts.go:113:14:113:21 | After type assertion |
| stmts.go:114:2:115:16 | After case clause [match] | stmts.go:115:3:115:16 | expression statement |
| stmts.go:114:2:115:16 | After case clause [no-match] | stmts.go:116:2:118:14 | case clause |
| stmts.go:114:2:115:16 | case clause | stmts.go:114:7:114:11 | error |
| stmts.go:114:2:115:16 | type-switch-var case clause | stmts.go:115:3:115:16 | expression statement |
| stmts.go:114:7:114:11 | error | stmts.go:114:14:114:19 | string |
| stmts.go:114:14:114:19 | string | stmts.go:114:2:115:16 | type-switch-var case clause |
| stmts.go:114:14:114:19 | string | stmts.go:116:2:118:14 | case clause |
| stmts.go:114:7:114:11 | After error [match] | stmts.go:114:2:115:16 | After case clause [match] |
| stmts.go:114:7:114:11 | After error [no-match] | stmts.go:114:14:114:19 | string |
| stmts.go:114:7:114:11 | error | stmts.go:114:7:114:11 | After error [match] |
| stmts.go:114:7:114:11 | error | stmts.go:114:7:114:11 | After error [no-match] |
| stmts.go:114:14:114:19 | After string [match] | stmts.go:114:2:115:16 | After case clause [match] |
| stmts.go:114:14:114:19 | After string [no-match] | stmts.go:114:2:115:16 | After case clause [no-match] |
| stmts.go:114:14:114:19 | string | stmts.go:114:14:114:19 | After string [match] |
| stmts.go:114:14:114:19 | string | stmts.go:114:14:114:19 | After string [no-match] |
| stmts.go:115:3:115:13 | After selection of Println | stmts.go:115:15:115:15 | Before y |
| stmts.go:115:3:115:13 | Before selection of Println | stmts.go:115:3:115:13 | selection of Println |
| stmts.go:115:3:115:13 | selection of Println | stmts.go:115:3:115:13 | After selection of Println |
@@ -3775,10 +3809,13 @@
| stmts.go:115:15:115:15 | After y | stmts.go:115:3:115:16 | call to Println |
| stmts.go:115:15:115:15 | Before y | stmts.go:115:15:115:15 | y |
| stmts.go:115:15:115:15 | y | stmts.go:115:15:115:15 | After y |
| stmts.go:116:2:118:14 | After case clause [match] | stmts.go:117:3:117:13 | expression statement |
| stmts.go:116:2:118:14 | After case clause [no-match] | stmts.go:119:2:120:7 | case clause |
| stmts.go:116:2:118:14 | case clause | stmts.go:116:7:116:13 | float32 |
| stmts.go:116:2:118:14 | type-switch-var case clause | stmts.go:117:3:117:13 | expression statement |
| stmts.go:116:7:116:13 | float32 | stmts.go:116:2:118:14 | type-switch-var case clause |
| stmts.go:116:7:116:13 | float32 | stmts.go:119:2:120:7 | case clause |
| stmts.go:116:7:116:13 | After float32 [match] | stmts.go:116:2:118:14 | After case clause [match] |
| stmts.go:116:7:116:13 | After float32 [no-match] | stmts.go:116:2:118:14 | After case clause [no-match] |
| stmts.go:116:7:116:13 | float32 | stmts.go:116:7:116:13 | After float32 [match] |
| stmts.go:116:7:116:13 | float32 | stmts.go:116:7:116:13 | After float32 [no-match] |
| stmts.go:117:3:117:7 | After test5 | stmts.go:117:9:117:12 | Before true |
| stmts.go:117:3:117:7 | Before test5 | stmts.go:117:3:117:7 | test5 |
| stmts.go:117:3:117:7 | test5 | stmts.go:117:3:117:7 | After test5 |
@@ -3803,8 +3840,8 @@
| stmts.go:118:9:118:13 | After false | stmts.go:118:3:118:14 | call to test5 |
| stmts.go:118:9:118:13 | Before false | stmts.go:118:9:118:13 | false |
| stmts.go:118:9:118:13 | false | stmts.go:118:9:118:13 | After false |
| stmts.go:119:2:120:7 | case clause | stmts.go:119:2:120:7 | type-switch-var case clause |
| stmts.go:119:2:120:7 | type-switch-var case clause | stmts.go:120:3:120:7 | ... = ... |
| stmts.go:119:2:120:7 | After case clause [match] | stmts.go:120:3:120:7 | ... = ... |
| stmts.go:119:2:120:7 | case clause | stmts.go:119:2:120:7 | After case clause [match] |
| stmts.go:120:3:120:7 | ... = ... | stmts.go:120:7:120:7 | Before y |
| stmts.go:120:3:120:7 | After ... = ... | stmts.go:113:2:121:2 | After type-switch statement |
| stmts.go:120:7:120:7 | After y | stmts.go:120:3:120:7 | After ... = ... |
@@ -3813,7 +3850,7 @@
| stmts.go:123:2:131:2 | After type-switch statement | stmts.go:133:2:136:2 | type-switch statement |
| stmts.go:123:2:131:2 | type-switch statement | stmts.go:123:9:123:14 | ... := ... |
| stmts.go:123:9:123:14 | ... := ... | stmts.go:123:14:123:14 | Before x |
| stmts.go:123:9:123:14 | After ... := ... | stmts.go:123:17:123:24 | expression statement |
| stmts.go:123:9:123:14 | After ... := ... | stmts.go:123:17:123:24 | Before type assertion |
| stmts.go:123:9:123:14 | assign:0 ... := ... | stmts.go:123:9:123:14 | After ... := ... |
| stmts.go:123:14:123:14 | After x | stmts.go:123:9:123:14 | assign:0 ... := ... |
| stmts.go:123:14:123:14 | Before x | stmts.go:123:14:123:14 | x |
@@ -3821,15 +3858,20 @@
| stmts.go:123:17:123:17 | After y | stmts.go:123:17:123:24 | type assertion |
| stmts.go:123:17:123:17 | Before y | stmts.go:123:17:123:17 | y |
| stmts.go:123:17:123:17 | y | stmts.go:123:17:123:17 | After y |
| stmts.go:123:17:123:24 | After expression statement | stmts.go:124:2:125:16 | case clause |
| stmts.go:123:17:123:24 | After type assertion | stmts.go:123:17:123:24 | After expression statement |
| stmts.go:123:17:123:24 | After type assertion | stmts.go:124:2:125:16 | case clause |
| stmts.go:123:17:123:24 | Before type assertion | stmts.go:123:17:123:17 | Before y |
| stmts.go:123:17:123:24 | expression statement | stmts.go:123:17:123:24 | Before type assertion |
| stmts.go:123:17:123:24 | type assertion | stmts.go:123:17:123:24 | After type assertion |
| stmts.go:124:2:125:16 | After case clause [match] | stmts.go:125:3:125:16 | expression statement |
| stmts.go:124:2:125:16 | After case clause [no-match] | stmts.go:126:2:128:14 | case clause |
| stmts.go:124:2:125:16 | case clause | stmts.go:124:7:124:11 | error |
| stmts.go:124:7:124:11 | error | stmts.go:124:14:124:19 | string |
| stmts.go:124:14:124:19 | string | stmts.go:125:3:125:16 | expression statement |
| stmts.go:124:14:124:19 | string | stmts.go:126:2:128:14 | case clause |
| stmts.go:124:7:124:11 | After error [match] | stmts.go:124:2:125:16 | After case clause [match] |
| stmts.go:124:7:124:11 | After error [no-match] | stmts.go:124:14:124:19 | string |
| stmts.go:124:7:124:11 | error | stmts.go:124:7:124:11 | After error [match] |
| stmts.go:124:7:124:11 | error | stmts.go:124:7:124:11 | After error [no-match] |
| stmts.go:124:14:124:19 | After string [match] | stmts.go:124:2:125:16 | After case clause [match] |
| stmts.go:124:14:124:19 | After string [no-match] | stmts.go:124:2:125:16 | After case clause [no-match] |
| stmts.go:124:14:124:19 | string | stmts.go:124:14:124:19 | After string [match] |
| stmts.go:124:14:124:19 | string | stmts.go:124:14:124:19 | After string [no-match] |
| stmts.go:125:3:125:13 | After selection of Println | stmts.go:125:15:125:15 | Before y |
| stmts.go:125:3:125:13 | Before selection of Println | stmts.go:125:3:125:13 | selection of Println |
| stmts.go:125:3:125:13 | selection of Println | stmts.go:125:3:125:13 | After selection of Println |
@@ -3842,9 +3884,13 @@
| stmts.go:125:15:125:15 | After y | stmts.go:125:3:125:16 | call to Println |
| stmts.go:125:15:125:15 | Before y | stmts.go:125:15:125:15 | y |
| stmts.go:125:15:125:15 | y | stmts.go:125:15:125:15 | After y |
| stmts.go:126:2:128:14 | After case clause [match] | stmts.go:127:3:127:13 | expression statement |
| stmts.go:126:2:128:14 | After case clause [no-match] | stmts.go:129:2:130:7 | case clause |
| stmts.go:126:2:128:14 | case clause | stmts.go:126:7:126:13 | float32 |
| stmts.go:126:7:126:13 | float32 | stmts.go:127:3:127:13 | expression statement |
| stmts.go:126:7:126:13 | float32 | stmts.go:129:2:130:7 | case clause |
| stmts.go:126:7:126:13 | After float32 [match] | stmts.go:126:2:128:14 | After case clause [match] |
| stmts.go:126:7:126:13 | After float32 [no-match] | stmts.go:126:2:128:14 | After case clause [no-match] |
| stmts.go:126:7:126:13 | float32 | stmts.go:126:7:126:13 | After float32 [match] |
| stmts.go:126:7:126:13 | float32 | stmts.go:126:7:126:13 | After float32 [no-match] |
| stmts.go:127:3:127:7 | After test5 | stmts.go:127:9:127:12 | Before true |
| stmts.go:127:3:127:7 | Before test5 | stmts.go:127:3:127:7 | test5 |
| stmts.go:127:3:127:7 | test5 | stmts.go:127:3:127:7 | After test5 |
@@ -3869,7 +3915,8 @@
| stmts.go:128:9:128:13 | After false | stmts.go:128:3:128:14 | call to test5 |
| stmts.go:128:9:128:13 | Before false | stmts.go:128:9:128:13 | false |
| stmts.go:128:9:128:13 | false | stmts.go:128:9:128:13 | After false |
| stmts.go:129:2:130:7 | case clause | stmts.go:130:3:130:7 | ... = ... |
| stmts.go:129:2:130:7 | After case clause [match] | stmts.go:130:3:130:7 | ... = ... |
| stmts.go:129:2:130:7 | case clause | stmts.go:129:2:130:7 | After case clause [match] |
| stmts.go:130:3:130:7 | ... = ... | stmts.go:130:7:130:7 | Before y |
| stmts.go:130:3:130:7 | After ... = ... | stmts.go:123:2:131:2 | After type-switch statement |
| stmts.go:130:7:130:7 | After y | stmts.go:130:3:130:7 | After ... = ... |
@@ -3878,7 +3925,7 @@
| stmts.go:133:2:136:2 | After type-switch statement | stmts.go:112:27:137:1 | After block statement |
| stmts.go:133:2:136:2 | type-switch statement | stmts.go:133:9:133:14 | ... := ... |
| stmts.go:133:9:133:14 | ... := ... | stmts.go:133:14:133:14 | Before x |
| stmts.go:133:9:133:14 | After ... := ... | stmts.go:133:17:133:24 | expression statement |
| stmts.go:133:9:133:14 | After ... := ... | stmts.go:133:17:133:24 | Before type assertion |
| stmts.go:133:9:133:14 | assign:0 ... := ... | stmts.go:133:9:133:14 | After ... := ... |
| stmts.go:133:14:133:14 | After x | stmts.go:133:9:133:14 | assign:0 ... := ... |
| stmts.go:133:14:133:14 | Before x | stmts.go:133:14:133:14 | x |
@@ -3886,12 +3933,11 @@
| stmts.go:133:17:133:17 | After y | stmts.go:133:17:133:24 | type assertion |
| stmts.go:133:17:133:17 | Before y | stmts.go:133:17:133:17 | y |
| stmts.go:133:17:133:17 | y | stmts.go:133:17:133:17 | After y |
| stmts.go:133:17:133:24 | After expression statement | stmts.go:134:2:135:14 | case clause |
| stmts.go:133:17:133:24 | After type assertion | stmts.go:133:17:133:24 | After expression statement |
| stmts.go:133:17:133:24 | After type assertion | stmts.go:134:2:135:14 | case clause |
| stmts.go:133:17:133:24 | Before type assertion | stmts.go:133:17:133:17 | Before y |
| stmts.go:133:17:133:24 | expression statement | stmts.go:133:17:133:24 | Before type assertion |
| stmts.go:133:17:133:24 | type assertion | stmts.go:133:17:133:24 | After type assertion |
| stmts.go:134:2:135:14 | case clause | stmts.go:135:3:135:14 | expression statement |
| stmts.go:134:2:135:14 | After case clause [match] | stmts.go:135:3:135:14 | expression statement |
| stmts.go:134:2:135:14 | case clause | stmts.go:134:2:135:14 | After case clause [match] |
| stmts.go:135:3:135:7 | After test5 | stmts.go:135:9:135:13 | Before false |
| stmts.go:135:3:135:7 | Before test5 | stmts.go:135:3:135:7 | test5 |
| stmts.go:135:3:135:7 | test5 | stmts.go:135:3:135:7 | After test5 |
@@ -4027,38 +4073,44 @@
| tst.go:3:19:12:1 | param-init:0 block statement | tst.go:4:2:11:2 | expression-switch statement |
| tst.go:4:2:11:2 | After expression-switch statement | tst.go:3:19:12:1 | After block statement |
| tst.go:4:2:11:2 | expression-switch statement | tst.go:5:2:5:13 | case clause |
| tst.go:5:2:5:13 | After case clause [match] | tst.go:4:2:11:2 | After expression-switch statement |
| tst.go:5:2:5:13 | After case clause [no-match] | tst.go:7:2:7:13 | case clause |
| tst.go:5:2:5:13 | case clause | tst.go:5:7:5:12 | Before ...<... |
| tst.go:5:7:5:7 | After x | tst.go:5:11:5:12 | Before 23 |
| tst.go:5:7:5:7 | Before x | tst.go:5:7:5:7 | x |
| tst.go:5:7:5:7 | x | tst.go:5:7:5:7 | After x |
| tst.go:5:7:5:12 | ...<... | tst.go:5:7:5:12 | After ...<... [false] |
| tst.go:5:7:5:12 | ...<... | tst.go:5:7:5:12 | After ...<... [true] |
| tst.go:5:7:5:12 | After ...<... [false] | tst.go:7:2:7:13 | case clause |
| tst.go:5:7:5:12 | After ...<... [true] | tst.go:4:2:11:2 | After expression-switch statement |
| tst.go:5:7:5:12 | ...<... | tst.go:5:7:5:12 | After ...<... [match] |
| tst.go:5:7:5:12 | ...<... | tst.go:5:7:5:12 | After ...<... [no-match] |
| tst.go:5:7:5:12 | After ...<... [match] | tst.go:5:2:5:13 | After case clause [match] |
| tst.go:5:7:5:12 | After ...<... [no-match] | tst.go:5:2:5:13 | After case clause [no-match] |
| tst.go:5:7:5:12 | Before ...<... | tst.go:5:7:5:7 | Before x |
| tst.go:5:11:5:12 | 23 | tst.go:5:11:5:12 | After 23 |
| tst.go:5:11:5:12 | After 23 | tst.go:5:7:5:12 | ...<... |
| tst.go:5:11:5:12 | Before 23 | tst.go:5:11:5:12 | 23 |
| tst.go:7:2:7:13 | After case clause [match] | tst.go:4:2:11:2 | After expression-switch statement |
| tst.go:7:2:7:13 | After case clause [no-match] | tst.go:9:2:9:13 | case clause |
| tst.go:7:2:7:13 | case clause | tst.go:7:7:7:12 | Before ...<... |
| tst.go:7:7:7:7 | After x | tst.go:7:11:7:12 | Before 42 |
| tst.go:7:7:7:7 | Before x | tst.go:7:7:7:7 | x |
| tst.go:7:7:7:7 | x | tst.go:7:7:7:7 | After x |
| tst.go:7:7:7:12 | ...<... | tst.go:7:7:7:12 | After ...<... [false] |
| tst.go:7:7:7:12 | ...<... | tst.go:7:7:7:12 | After ...<... [true] |
| tst.go:7:7:7:12 | After ...<... [false] | tst.go:9:2:9:13 | case clause |
| tst.go:7:7:7:12 | After ...<... [true] | tst.go:4:2:11:2 | After expression-switch statement |
| tst.go:7:7:7:12 | ...<... | tst.go:7:7:7:12 | After ...<... [match] |
| tst.go:7:7:7:12 | ...<... | tst.go:7:7:7:12 | After ...<... [no-match] |
| tst.go:7:7:7:12 | After ...<... [match] | tst.go:7:2:7:13 | After case clause [match] |
| tst.go:7:7:7:12 | After ...<... [no-match] | tst.go:7:2:7:13 | After case clause [no-match] |
| tst.go:7:7:7:12 | Before ...<... | tst.go:7:7:7:7 | Before x |
| tst.go:7:11:7:12 | 42 | tst.go:7:11:7:12 | After 42 |
| tst.go:7:11:7:12 | After 42 | tst.go:7:7:7:12 | ...<... |
| tst.go:7:11:7:12 | Before 42 | tst.go:7:11:7:12 | 42 |
| tst.go:9:2:9:13 | After case clause [match] | tst.go:4:2:11:2 | After expression-switch statement |
| tst.go:9:2:9:13 | After case clause [no-match] | tst.go:4:2:11:2 | After expression-switch statement |
| tst.go:9:2:9:13 | case clause | tst.go:9:7:9:12 | Before ...<... |
| tst.go:9:7:9:7 | After x | tst.go:9:11:9:12 | Before 23 |
| tst.go:9:7:9:7 | Before x | tst.go:9:7:9:7 | x |
| tst.go:9:7:9:7 | x | tst.go:9:7:9:7 | After x |
| tst.go:9:7:9:12 | ...<... | tst.go:9:7:9:12 | After ...<... [false] |
| tst.go:9:7:9:12 | ...<... | tst.go:9:7:9:12 | After ...<... [true] |
| tst.go:9:7:9:12 | After ...<... [false] | tst.go:4:2:11:2 | After expression-switch statement |
| tst.go:9:7:9:12 | After ...<... [true] | tst.go:4:2:11:2 | After expression-switch statement |
| tst.go:9:7:9:12 | ...<... | tst.go:9:7:9:12 | After ...<... [match] |
| tst.go:9:7:9:12 | ...<... | tst.go:9:7:9:12 | After ...<... [no-match] |
| tst.go:9:7:9:12 | After ...<... [match] | tst.go:9:2:9:13 | After case clause [match] |
| tst.go:9:7:9:12 | After ...<... [no-match] | tst.go:9:2:9:13 | After case clause [no-match] |
| tst.go:9:7:9:12 | Before ...<... | tst.go:9:7:9:7 | Before x |
| tst.go:9:11:9:12 | 23 | tst.go:9:11:9:12 | After 23 |
| tst.go:9:11:9:12 | After 23 | tst.go:9:7:9:12 | ...<... |
@@ -4074,14 +4126,16 @@
| tst.go:14:26:21:1 | param-init:0 block statement | tst.go:15:2:20:2 | expression-switch statement |
| tst.go:15:2:20:2 | After expression-switch statement | tst.go:14:26:21:1 | After block statement |
| tst.go:15:2:20:2 | expression-switch statement | tst.go:16:2:16:34 | case clause |
| tst.go:16:2:16:34 | After case clause [match] | tst.go:15:2:20:2 | After expression-switch statement |
| tst.go:16:2:16:34 | After case clause [no-match] | tst.go:18:2:18:39 | case clause |
| tst.go:16:2:16:34 | case clause | tst.go:16:7:16:33 | Before ...<... |
| tst.go:16:7:16:11 | After value | tst.go:16:15:16:33 | Before ...*... |
| tst.go:16:7:16:11 | Before value | tst.go:16:7:16:11 | value |
| tst.go:16:7:16:11 | value | tst.go:16:7:16:11 | After value |
| tst.go:16:7:16:33 | ...<... | tst.go:16:7:16:33 | After ...<... [false] |
| tst.go:16:7:16:33 | ...<... | tst.go:16:7:16:33 | After ...<... [true] |
| tst.go:16:7:16:33 | After ...<... [false] | tst.go:18:2:18:39 | case clause |
| tst.go:16:7:16:33 | After ...<... [true] | tst.go:15:2:20:2 | After expression-switch statement |
| tst.go:16:7:16:33 | ...<... | tst.go:16:7:16:33 | After ...<... [match] |
| tst.go:16:7:16:33 | ...<... | tst.go:16:7:16:33 | After ...<... [no-match] |
| tst.go:16:7:16:33 | After ...<... [match] | tst.go:16:2:16:34 | After case clause [match] |
| tst.go:16:7:16:33 | After ...<... [no-match] | tst.go:16:2:16:34 | After case clause [no-match] |
| tst.go:16:7:16:33 | Before ...<... | tst.go:16:7:16:11 | Before value |
| tst.go:16:15:16:18 | 1024 | tst.go:16:15:16:18 | After 1024 |
| tst.go:16:15:16:18 | After 1024 | tst.go:16:20:16:23 | Before 1024 |
@@ -4104,14 +4158,16 @@
| tst.go:16:30:16:33 | 1024 | tst.go:16:30:16:33 | After 1024 |
| tst.go:16:30:16:33 | After 1024 | tst.go:16:15:16:33 | ...*... |
| tst.go:16:30:16:33 | Before 1024 | tst.go:16:30:16:33 | 1024 |
| tst.go:18:2:18:39 | After case clause [match] | tst.go:15:2:20:2 | After expression-switch statement |
| tst.go:18:2:18:39 | After case clause [no-match] | tst.go:15:2:20:2 | After expression-switch statement |
| tst.go:18:2:18:39 | case clause | tst.go:18:7:18:38 | Before ...<... |
| tst.go:18:7:18:11 | After value | tst.go:18:15:18:38 | Before ...*... |
| tst.go:18:7:18:11 | Before value | tst.go:18:7:18:11 | value |
| tst.go:18:7:18:11 | value | tst.go:18:7:18:11 | After value |
| tst.go:18:7:18:38 | ...<... | tst.go:18:7:18:38 | After ...<... [false] |
| tst.go:18:7:18:38 | ...<... | tst.go:18:7:18:38 | After ...<... [true] |
| tst.go:18:7:18:38 | After ...<... [false] | tst.go:15:2:20:2 | After expression-switch statement |
| tst.go:18:7:18:38 | After ...<... [true] | tst.go:15:2:20:2 | After expression-switch statement |
| tst.go:18:7:18:38 | ...<... | tst.go:18:7:18:38 | After ...<... [match] |
| tst.go:18:7:18:38 | ...<... | tst.go:18:7:18:38 | After ...<... [no-match] |
| tst.go:18:7:18:38 | After ...<... [match] | tst.go:18:2:18:39 | After case clause [match] |
| tst.go:18:7:18:38 | After ...<... [no-match] | tst.go:18:2:18:39 | After case clause [no-match] |
| tst.go:18:7:18:38 | Before ...<... | tst.go:18:7:18:11 | Before value |
| tst.go:18:15:18:18 | 1024 | tst.go:18:15:18:18 | After 1024 |
| tst.go:18:15:18:18 | After 1024 | tst.go:18:20:18:23 | Before 1024 |
@@ -4158,5 +4214,5 @@
| tst.go:28:15:32:1 | block statement | tst.go:29:2:31:2 | expression-switch statement |
| tst.go:29:2:31:2 | After expression-switch statement | tst.go:28:15:32:1 | After block statement |
| tst.go:29:2:31:2 | expression-switch statement | tst.go:30:2:30:9 | case clause |
| tst.go:30:2:30:9 | case clause | tst.go:29:2:31:2 | After expression-switch statement |
| tst.go:30:2:30:9 | case clause | tst.go:29:9:31:2 | After block statement |
| tst.go:30:2:30:9 | After case clause [match] | tst.go:29:2:31:2 | After expression-switch statement |
| tst.go:30:2:30:9 | case clause | tst.go:30:2:30:9 | After case clause [match] |

View File

@@ -1,42 +1,42 @@
| main.go:15:12:15:12 | x | main.go:13:6:13:6 | SSA def(x) | main.go:13:6:13:6 | x |
| main.go:15:15:15:15 | y | main.go:14:2:14:2 | SSA def(y) | main.go:14:2:14:2 | y |
| main.go:17:3:17:3 | y | main.go:14:2:14:2 | SSA def(y) | main.go:14:2:14:2 | y |
| main.go:19:12:19:12 | x | main.go:13:6:13:6 | SSA def(x) | main.go:13:6:13:6 | x |
| main.go:19:15:19:15 | y | main.go:19:2:19:10 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:21:7:21:7 | y | main.go:19:2:19:10 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:23:12:23:12 | x | main.go:23:2:23:10 | SSA phi(x) | main.go:13:6:13:6 | x |
| main.go:23:15:23:15 | y | main.go:19:2:19:10 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:27:10:27:10 | x | main.go:26:10:26:10 | SSA def(x) | main.go:26:10:26:10 | x |
| main.go:29:10:29:10 | b | main.go:27:5:27:5 | SSA def(b) | main.go:27:5:27:5 | b |
| main.go:29:13:29:13 | a | main.go:27:2:27:2 | SSA def(a) | main.go:27:2:27:2 | a |
| main.go:31:9:31:9 | a | main.go:31:9:31:9 | SSA phi(a) | main.go:27:2:27:2 | a |
| main.go:31:12:31:12 | b | main.go:31:9:31:9 | SSA phi(b) | main.go:27:5:27:5 | b |
| main.go:35:3:35:3 | x | main.go:34:11:34:11 | SSA def(x) | main.go:34:11:34:11 | x |
| main.go:40:10:40:10 | x | main.go:39:2:39:2 | SSA def(x) | main.go:39:2:39:2 | x |
| main.go:42:8:42:10 | ptr | main.go:40:2:40:4 | SSA def(ptr) | main.go:40:2:40:4 | ptr |
| main.go:44:12:44:12 | x | main.go:39:2:39:2 | SSA def(x) | main.go:39:2:39:2 | x |
| main.go:47:13:47:18 | implicit read of result | main.go:48:2:48:7 | SSA def(result) | main.go:47:13:47:18 | result |
| main.go:52:14:52:19 | implicit read of result | main.go:52:14:52:19 | SSA def(result) | main.go:52:14:52:19 | result |
| main.go:61:12:61:12 | x | main.go:58:6:58:9 | SSA phi(x) | main.go:57:6:57:6 | x |
| main.go:64:16:64:16 | i | main.go:65:6:65:9 | SSA phi(i) | main.go:64:6:64:6 | i |
| main.go:70:12:70:12 | y | main.go:65:6:65:9 | SSA phi(y) | main.go:63:2:63:2 | y |
| main.go:73:16:73:16 | i | main.go:74:3:74:3 | SSA phi(i) | main.go:73:6:73:6 | i |
| main.go:79:12:79:12 | z | main.go:74:3:74:3 | SSA def(z) | main.go:72:2:72:2 | z |
| main.go:82:18:82:18 | implicit read of a | main.go:84:5:84:5 | SSA def(a) | main.go:82:18:82:18 | a |
| main.go:82:25:82:25 | implicit read of b | main.go:82:25:82:25 | SSA def(b) | main.go:82:25:82:25 | b |
| main.go:84:9:84:9 | x | main.go:83:2:83:2 | SSA def(x) | main.go:83:2:83:2 | x |
| main.go:84:15:84:15 | x | main.go:83:2:83:2 | SSA def(x) | main.go:83:2:83:2 | x |
| main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | SSA def(wrapper) | main.go:95:22:95:28 | wrapper |
| main.go:15:12:15:12 | x | main.go:13:6:13:10 | SSA def(x) | main.go:13:6:13:6 | x |
| main.go:15:15:15:15 | y | main.go:14:2:14:8 | SSA def(y) | main.go:14:2:14:2 | y |
| main.go:17:3:17:3 | y | main.go:14:2:14:8 | SSA def(y) | main.go:14:2:14:2 | y |
| main.go:19:12:19:12 | x | main.go:13:6:13:10 | SSA def(x) | main.go:13:6:13:6 | x |
| main.go:19:15:19:15 | y | main.go:16:2:18:2 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:21:7:21:7 | y | main.go:16:2:18:2 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:23:12:23:12 | x | main.go:20:2:22:2 | SSA phi(x) | main.go:13:6:13:6 | x |
| main.go:23:15:23:15 | y | main.go:16:2:18:2 | SSA phi(y) | main.go:14:2:14:2 | y |
| main.go:27:10:27:10 | x | main.go:26:28:32:1 | SSA def(x) | main.go:26:10:26:10 | x |
| main.go:29:10:29:10 | b | main.go:27:2:27:13 | SSA def(b) | main.go:27:5:27:5 | b |
| main.go:29:13:29:13 | a | main.go:27:2:27:13 | SSA def(a) | main.go:27:2:27:2 | a |
| main.go:31:9:31:9 | a | main.go:28:2:30:2 | SSA phi(a) | main.go:27:2:27:2 | a |
| main.go:31:12:31:12 | b | main.go:28:2:30:2 | SSA phi(b) | main.go:27:5:27:5 | b |
| main.go:35:3:35:3 | x | main.go:34:19:36:1 | SSA def(x) | main.go:34:11:34:11 | x |
| main.go:40:10:40:10 | x | main.go:39:2:39:8 | SSA def(x) | main.go:39:2:39:2 | x |
| main.go:42:8:42:10 | ptr | main.go:40:2:40:10 | SSA def(ptr) | main.go:40:2:40:4 | ptr |
| main.go:44:12:44:12 | x | main.go:39:2:39:8 | SSA def(x) | main.go:39:2:39:2 | x |
| main.go:47:25:50:1 | result-read:0 block statement | main.go:48:2:48:12 | SSA def(result) | main.go:47:13:47:18 | result |
| main.go:52:26:54:1 | result-read:0 block statement | main.go:52:26:54:1 | SSA def(result) | main.go:52:14:52:19 | result |
| main.go:61:12:61:12 | x | main.go:58:6:58:11 | SSA phi(x) | main.go:57:6:57:6 | x |
| main.go:64:16:64:16 | i | main.go:64:20:69:2 | SSA phi(i) | main.go:64:6:64:6 | i |
| main.go:70:12:70:12 | y | main.go:64:20:69:2 | SSA phi(y) | main.go:63:2:63:2 | y |
| main.go:73:16:73:16 | i | main.go:73:20:78:2 | SSA phi(i) | main.go:73:6:73:6 | i |
| main.go:79:12:79:12 | z | main.go:74:3:74:7 | SSA def(z) | main.go:72:2:72:2 | z |
| main.go:82:36:86:1 | result-read:0 block statement | main.go:84:2:84:15 | SSA def(a) | main.go:82:18:82:18 | a |
| main.go:82:36:86:1 | result-read:1 block statement | main.go:82:36:86:1 | SSA def(b) | main.go:82:25:82:25 | b |
| main.go:84:9:84:9 | x | main.go:83:2:83:8 | SSA def(x) | main.go:83:2:83:2 | x |
| main.go:84:15:84:15 | x | main.go:83:2:83:8 | SSA def(x) | main.go:83:2:83:2 | x |
| main.go:97:2:97:8 | wrapper | main.go:95:47:101:1 | SSA def(wrapper) | main.go:95:22:95:28 | wrapper |
| main.go:100:9:100:9 | x | main.go:97:2:99:3 | SSA def(x) | main.go:96:2:96:2 | x |
| main.go:105:2:105:8 | wrapper | main.go:103:20:103:26 | SSA def(wrapper) | main.go:103:20:103:26 | wrapper |
| main.go:105:2:105:8 | wrapper | main.go:103:45:110:1 | SSA def(wrapper) | main.go:103:20:103:26 | wrapper |
| main.go:106:8:106:8 | x | main.go:105:16:108:2 | SSA def(x) | main.go:104:2:104:2 | x |
| main.go:107:7:107:7 | y | main.go:106:3:106:3 | SSA def(y) | main.go:106:3:106:3 | y |
| main.go:109:9:109:9 | x | main.go:104:2:104:2 | SSA def(x) | main.go:104:2:104:2 | x |
| main.go:114:2:114:8 | wrapper | main.go:112:29:112:35 | SSA def(wrapper) | main.go:112:29:112:35 | wrapper |
| main.go:107:7:107:7 | y | main.go:106:3:106:8 | SSA def(y) | main.go:106:3:106:3 | y |
| main.go:109:9:109:9 | x | main.go:104:2:104:7 | SSA def(x) | main.go:104:2:104:2 | x |
| main.go:114:2:114:8 | wrapper | main.go:112:54:119:1 | SSA def(wrapper) | main.go:112:29:112:35 | wrapper |
| main.go:115:8:115:8 | x | main.go:114:16:117:2 | SSA def(x) | main.go:113:2:113:2 | x |
| main.go:116:7:116:7 | y | main.go:115:3:115:3 | SSA def(y) | main.go:115:3:115:3 | y |
| main.go:116:7:116:7 | y | main.go:115:3:115:12 | SSA def(y) | main.go:115:3:115:3 | y |
| main.go:118:9:118:9 | x | main.go:114:2:117:3 | SSA def(x) | main.go:113:2:113:2 | x |
| main.go:135:2:135:2 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:12:137:12 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:17:137:17 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:24:137:24 | p | main.go:135:2:135:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:135:2:135:2 | p | main.go:129:2:133:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:12:137:12 | p | main.go:129:2:133:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:17:137:17 | p | main.go:129:2:133:2 | SSA phi(p) | main.go:128:6:128:6 | p |
| main.go:137:24:137:24 | p | main.go:129:2:133:2 | SSA phi(p) | main.go:128:6:128:6 | p |

View File

@@ -1,51 +1,51 @@
| main.go:13:6:13:6 | SSA def(x) |
| main.go:14:2:14:2 | SSA def(y) |
| main.go:17:3:17:3 | SSA def(y) |
| main.go:19:2:19:10 | SSA phi(y) |
| main.go:21:3:21:3 | SSA def(x) |
| main.go:23:2:23:10 | SSA phi(x) |
| main.go:26:10:26:10 | SSA def(x) |
| main.go:27:2:27:2 | SSA def(a) |
| main.go:27:5:27:5 | SSA def(b) |
| main.go:29:3:29:3 | SSA def(a) |
| main.go:29:6:29:6 | SSA def(b) |
| main.go:31:9:31:9 | SSA phi(a) |
| main.go:31:9:31:9 | SSA phi(b) |
| main.go:34:11:34:11 | SSA def(x) |
| main.go:39:2:39:2 | SSA def(x) |
| main.go:40:2:40:4 | SSA def(ptr) |
| main.go:48:2:48:7 | SSA def(result) |
| main.go:52:14:52:19 | SSA def(result) |
| main.go:57:6:57:6 | SSA def(x) |
| main.go:58:6:58:9 | SSA phi(x) |
| main.go:59:3:59:3 | SSA def(x) |
| main.go:63:2:63:2 | SSA def(y) |
| main.go:64:6:64:6 | SSA def(i) |
| main.go:13:6:13:10 | SSA def(x) |
| main.go:14:2:14:8 | SSA def(y) |
| main.go:16:2:18:2 | SSA phi(y) |
| main.go:17:3:17:9 | SSA def(y) |
| main.go:20:2:22:2 | SSA phi(x) |
| main.go:21:3:21:7 | SSA def(x) |
| main.go:26:28:32:1 | SSA def(x) |
| main.go:27:2:27:13 | SSA def(a) |
| main.go:27:2:27:13 | SSA def(b) |
| main.go:28:2:30:2 | SSA phi(a) |
| main.go:28:2:30:2 | SSA phi(b) |
| main.go:29:3:29:13 | SSA def(a) |
| main.go:29:3:29:13 | SSA def(b) |
| main.go:34:19:36:1 | SSA def(x) |
| main.go:39:2:39:8 | SSA def(x) |
| main.go:40:2:40:10 | SSA def(ptr) |
| main.go:48:2:48:12 | SSA def(result) |
| main.go:52:26:54:1 | SSA def(result) |
| main.go:57:6:57:10 | SSA def(x) |
| main.go:58:6:58:11 | SSA phi(x) |
| main.go:59:3:59:7 | SSA def(x) |
| main.go:63:2:63:7 | SSA def(y) |
| main.go:64:6:64:11 | SSA def(i) |
| main.go:64:16:64:18 | SSA def(i) |
| main.go:65:6:65:9 | SSA phi(i) |
| main.go:65:6:65:9 | SSA phi(y) |
| main.go:68:3:68:3 | SSA def(y) |
| main.go:73:6:73:6 | SSA def(i) |
| main.go:64:20:69:2 | SSA phi(i) |
| main.go:64:20:69:2 | SSA phi(y) |
| main.go:68:3:68:7 | SSA def(y) |
| main.go:73:6:73:11 | SSA def(i) |
| main.go:73:16:73:18 | SSA def(i) |
| main.go:74:3:74:3 | SSA def(z) |
| main.go:74:3:74:3 | SSA phi(i) |
| main.go:82:25:82:25 | SSA def(b) |
| main.go:83:2:83:2 | SSA def(x) |
| main.go:84:5:84:5 | SSA def(a) |
| main.go:95:22:95:28 | SSA def(wrapper) |
| main.go:96:2:96:2 | SSA def(x) |
| main.go:73:20:78:2 | SSA phi(i) |
| main.go:74:3:74:7 | SSA def(z) |
| main.go:82:36:86:1 | SSA def(b) |
| main.go:83:2:83:8 | SSA def(x) |
| main.go:84:2:84:15 | SSA def(a) |
| main.go:95:47:101:1 | SSA def(wrapper) |
| main.go:96:2:96:7 | SSA def(x) |
| main.go:97:2:99:3 | SSA def(x) |
| main.go:98:3:98:3 | SSA def(x) |
| main.go:103:20:103:26 | SSA def(wrapper) |
| main.go:104:2:104:2 | SSA def(x) |
| main.go:98:3:98:7 | SSA def(x) |
| main.go:103:45:110:1 | SSA def(wrapper) |
| main.go:104:2:104:7 | SSA def(x) |
| main.go:105:16:108:2 | SSA def(x) |
| main.go:106:3:106:3 | SSA def(y) |
| main.go:112:29:112:35 | SSA def(wrapper) |
| main.go:113:2:113:2 | SSA def(x) |
| main.go:106:3:106:8 | SSA def(y) |
| main.go:112:54:119:1 | SSA def(wrapper) |
| main.go:113:2:113:7 | SSA def(x) |
| main.go:114:2:117:3 | SSA def(x) |
| main.go:114:16:117:2 | SSA def(x) |
| main.go:115:3:115:3 | SSA def(y) |
| main.go:116:3:116:3 | SSA def(x) |
| main.go:130:3:130:3 | SSA def(p) |
| main.go:132:3:132:3 | SSA def(p) |
| main.go:135:2:135:2 | SSA phi(p) |
| main.go:115:3:115:12 | SSA def(y) |
| main.go:116:3:116:7 | SSA def(x) |
| main.go:129:2:133:2 | SSA phi(p) |
| main.go:130:3:130:24 | SSA def(p) |
| main.go:132:3:132:24 | SSA def(p) |

View File

@@ -1,58 +1,58 @@
| main.go:13:6:13:6 | (SSA def(x)) | x |
| main.go:14:2:14:2 | (SSA def(y)) | y |
| main.go:17:3:17:3 | (SSA def(y)) | y |
| main.go:19:2:19:10 | (SSA phi(y)) | y |
| main.go:21:3:21:3 | (SSA def(x)) | x |
| main.go:23:2:23:10 | (SSA phi(x)) | x |
| main.go:26:10:26:10 | (SSA def(x)) | x |
| main.go:27:2:27:2 | (SSA def(a)) | a |
| main.go:27:5:27:5 | (SSA def(b)) | b |
| main.go:29:3:29:3 | (SSA def(a)) | a |
| main.go:29:6:29:6 | (SSA def(b)) | b |
| main.go:31:9:31:9 | (SSA phi(a)) | a |
| main.go:31:9:31:9 | (SSA phi(b)) | b |
| main.go:34:11:34:11 | (SSA def(x)) | x |
| main.go:39:2:39:2 | (SSA def(x)) | x |
| main.go:40:2:40:4 | (SSA def(ptr)) | ptr |
| main.go:48:2:48:7 | (SSA def(result)) | result |
| main.go:52:14:52:19 | (SSA def(result)) | result |
| main.go:57:6:57:6 | (SSA def(x)) | x |
| main.go:58:6:58:9 | (SSA phi(x)) | x |
| main.go:59:3:59:3 | (SSA def(x)) | x |
| main.go:63:2:63:2 | (SSA def(y)) | y |
| main.go:64:6:64:6 | (SSA def(i)) | i |
| main.go:13:6:13:10 | (SSA def(x)) | x |
| main.go:14:2:14:8 | (SSA def(y)) | y |
| main.go:16:2:18:2 | (SSA phi(y)) | y |
| main.go:17:3:17:9 | (SSA def(y)) | y |
| main.go:20:2:22:2 | (SSA phi(x)) | x |
| main.go:21:3:21:7 | (SSA def(x)) | x |
| main.go:26:28:32:1 | (SSA def(x)) | x |
| main.go:27:2:27:13 | (SSA def(a)) | a |
| main.go:27:2:27:13 | (SSA def(b)) | b |
| main.go:28:2:30:2 | (SSA phi(a)) | a |
| main.go:28:2:30:2 | (SSA phi(b)) | b |
| main.go:29:3:29:13 | (SSA def(a)) | a |
| main.go:29:3:29:13 | (SSA def(b)) | b |
| main.go:34:19:36:1 | (SSA def(x)) | x |
| main.go:39:2:39:8 | (SSA def(x)) | x |
| main.go:40:2:40:10 | (SSA def(ptr)) | ptr |
| main.go:48:2:48:12 | (SSA def(result)) | result |
| main.go:52:26:54:1 | (SSA def(result)) | result |
| main.go:57:6:57:10 | (SSA def(x)) | x |
| main.go:58:6:58:11 | (SSA phi(x)) | x |
| main.go:59:3:59:7 | (SSA def(x)) | x |
| main.go:63:2:63:7 | (SSA def(y)) | y |
| main.go:64:6:64:11 | (SSA def(i)) | i |
| main.go:64:16:64:18 | (SSA def(i)) | i |
| main.go:65:6:65:9 | (SSA phi(i)) | i |
| main.go:65:6:65:9 | (SSA phi(y)) | y |
| main.go:68:3:68:3 | (SSA def(y)) | y |
| main.go:73:6:73:6 | (SSA def(i)) | i |
| main.go:64:20:69:2 | (SSA phi(i)) | i |
| main.go:64:20:69:2 | (SSA phi(y)) | y |
| main.go:68:3:68:7 | (SSA def(y)) | y |
| main.go:73:6:73:11 | (SSA def(i)) | i |
| main.go:73:16:73:18 | (SSA def(i)) | i |
| main.go:74:3:74:3 | (SSA def(z)) | z |
| main.go:74:3:74:3 | (SSA phi(i)) | i |
| main.go:82:25:82:25 | (SSA def(b)) | b |
| main.go:83:2:83:2 | (SSA def(x)) | x |
| main.go:84:5:84:5 | (SSA def(a)) | a |
| main.go:95:22:95:28 | (SSA def(wrapper)) | wrapper |
| main.go:95:22:95:28 | (SSA def(wrapper)).s | wrapper.s |
| main.go:96:2:96:2 | (SSA def(x)) | x |
| main.go:73:20:78:2 | (SSA phi(i)) | i |
| main.go:74:3:74:7 | (SSA def(z)) | z |
| main.go:82:36:86:1 | (SSA def(b)) | b |
| main.go:83:2:83:8 | (SSA def(x)) | x |
| main.go:84:2:84:15 | (SSA def(a)) | a |
| main.go:95:47:101:1 | (SSA def(wrapper)) | wrapper |
| main.go:95:47:101:1 | (SSA def(wrapper)).s | wrapper.s |
| main.go:96:2:96:7 | (SSA def(x)) | x |
| main.go:97:2:99:3 | (SSA def(x)) | x |
| main.go:98:3:98:3 | (SSA def(x)) | x |
| main.go:103:20:103:26 | (SSA def(wrapper)) | wrapper |
| main.go:103:20:103:26 | (SSA def(wrapper)).s | wrapper.s |
| main.go:104:2:104:2 | (SSA def(x)) | x |
| main.go:98:3:98:7 | (SSA def(x)) | x |
| main.go:103:45:110:1 | (SSA def(wrapper)) | wrapper |
| main.go:103:45:110:1 | (SSA def(wrapper)).s | wrapper.s |
| main.go:104:2:104:7 | (SSA def(x)) | x |
| main.go:105:16:108:2 | (SSA def(x)) | x |
| main.go:106:3:106:3 | (SSA def(y)) | y |
| main.go:112:29:112:35 | (SSA def(wrapper)) | wrapper |
| main.go:112:29:112:35 | (SSA def(wrapper)).s | wrapper.s |
| main.go:113:2:113:2 | (SSA def(x)) | x |
| main.go:106:3:106:8 | (SSA def(y)) | y |
| main.go:112:54:119:1 | (SSA def(wrapper)) | wrapper |
| main.go:112:54:119:1 | (SSA def(wrapper)).s | wrapper.s |
| main.go:113:2:113:7 | (SSA def(x)) | x |
| main.go:114:2:117:3 | (SSA def(x)) | x |
| main.go:114:16:117:2 | (SSA def(x)) | x |
| main.go:115:3:115:3 | (SSA def(y)) | y |
| main.go:116:3:116:3 | (SSA def(x)) | x |
| main.go:130:3:130:3 | (SSA def(p)) | p |
| main.go:132:3:132:3 | (SSA def(p)) | p |
| main.go:135:2:135:2 | (SSA phi(p)) | p |
| main.go:135:2:135:2 | (SSA phi(p)).a | p.a |
| main.go:135:2:135:2 | (SSA phi(p)).b | p.b |
| main.go:135:2:135:2 | (SSA phi(p)).b.a | p.b.a |
| main.go:135:2:135:2 | (SSA phi(p)).c | p.c |
| main.go:115:3:115:12 | (SSA def(y)) | y |
| main.go:116:3:116:7 | (SSA def(x)) | x |
| main.go:129:2:133:2 | (SSA phi(p)) | p |
| main.go:129:2:133:2 | (SSA phi(p)).a | p.a |
| main.go:129:2:133:2 | (SSA phi(p)).b | p.b |
| main.go:129:2:133:2 | (SSA phi(p)).b.a | p.b.a |
| main.go:129:2:133:2 | (SSA phi(p)).c | p.c |
| main.go:130:3:130:24 | (SSA def(p)) | p |
| main.go:132:3:132:24 | (SSA def(p)) | p |

View File

@@ -1,54 +1,54 @@
| main.go:13:6:13:6 | assignment to x | main.go:13:6:13:6 | x | main.go:13:6:13:6 | zero value for x |
| main.go:14:2:14:2 | assignment to y | main.go:14:2:14:2 | y | main.go:14:7:14:8 | 23 |
| main.go:17:3:17:3 | assignment to y | main.go:14:2:14:2 | y | main.go:17:3:17:9 | ... += ... |
| main.go:21:3:21:3 | assignment to x | main.go:13:6:13:6 | x | main.go:21:7:21:7 | y |
| main.go:26:10:26:10 | initialization of x | main.go:26:10:26:10 | x | main.go:26:10:26:10 | argument corresponding to x |
| main.go:27:2:27:2 | assignment to a | main.go:27:2:27:2 | a | main.go:27:10:27:10 | x |
| main.go:27:5:27:5 | assignment to b | main.go:27:5:27:5 | b | main.go:27:13:27:13 | 0 |
| main.go:29:3:29:3 | assignment to a | main.go:27:2:27:2 | a | main.go:29:10:29:10 | b |
| main.go:29:6:29:6 | assignment to b | main.go:27:5:27:5 | b | main.go:29:13:29:13 | a |
| main.go:34:11:34:11 | initialization of x | main.go:34:11:34:11 | x | main.go:34:11:34:11 | argument corresponding to x |
| main.go:39:2:39:2 | assignment to x | main.go:39:2:39:2 | x | main.go:39:7:39:8 | 23 |
| main.go:40:2:40:4 | assignment to ptr | main.go:40:2:40:4 | ptr | main.go:40:9:40:10 | &... |
| main.go:47:13:47:18 | initialization of result | main.go:47:13:47:18 | result | main.go:47:13:47:18 | zero value for result |
| main.go:48:2:48:7 | assignment to result | main.go:47:13:47:18 | result | main.go:48:11:48:12 | 42 |
| main.go:52:14:52:19 | initialization of result | main.go:52:14:52:19 | result | main.go:52:14:52:19 | zero value for result |
| main.go:57:6:57:6 | assignment to x | main.go:57:6:57:6 | x | main.go:57:6:57:6 | zero value for x |
| main.go:59:3:59:3 | assignment to x | main.go:57:6:57:6 | x | main.go:59:7:59:7 | 2 |
| main.go:63:2:63:2 | assignment to y | main.go:63:2:63:2 | y | main.go:63:7:63:7 | 1 |
| main.go:64:6:64:6 | assignment to i | main.go:64:6:64:6 | i | main.go:64:11:64:11 | 0 |
| main.go:64:16:64:18 | increment statement | main.go:64:6:64:6 | i | main.go:64:16:64:18 | rhs of increment statement |
| main.go:68:3:68:3 | assignment to y | main.go:63:2:63:2 | y | main.go:68:7:68:7 | 2 |
| main.go:72:2:72:2 | assignment to z | main.go:72:2:72:2 | z | main.go:72:7:72:7 | 1 |
| main.go:73:6:73:6 | assignment to i | main.go:73:6:73:6 | i | main.go:73:11:73:11 | 0 |
| main.go:73:16:73:18 | increment statement | main.go:73:6:73:6 | i | main.go:73:16:73:18 | rhs of increment statement |
| main.go:74:3:74:3 | assignment to z | main.go:72:2:72:2 | z | main.go:74:7:74:7 | 2 |
| main.go:82:18:82:18 | initialization of a | main.go:82:18:82:18 | a | main.go:82:18:82:18 | zero value for a |
| main.go:82:25:82:25 | initialization of b | main.go:82:25:82:25 | b | main.go:82:25:82:25 | zero value for b |
| main.go:83:2:83:2 | assignment to x | main.go:83:2:83:2 | x | main.go:83:7:83:8 | 23 |
| main.go:84:2:84:2 | assignment to x | main.go:83:2:83:2 | x | main.go:84:9:84:12 | ...+... |
| main.go:84:5:84:5 | assignment to a | main.go:82:18:82:18 | a | main.go:84:15:84:15 | x |
| main.go:93:15:93:16 | initialization of cb | main.go:93:15:93:16 | cb | main.go:93:15:93:16 | argument corresponding to cb |
| main.go:95:22:95:28 | initialization of wrapper | main.go:95:22:95:28 | wrapper | main.go:95:22:95:28 | argument corresponding to wrapper |
| main.go:96:2:96:2 | assignment to x | main.go:96:2:96:2 | x | main.go:96:7:96:7 | 0 |
| main.go:98:3:98:3 | assignment to x | main.go:96:2:96:2 | x | main.go:98:7:98:7 | 1 |
| main.go:103:20:103:26 | initialization of wrapper | main.go:103:20:103:26 | wrapper | main.go:103:20:103:26 | argument corresponding to wrapper |
| main.go:104:2:104:2 | assignment to x | main.go:104:2:104:2 | x | main.go:104:7:104:7 | 0 |
| main.go:106:3:106:3 | assignment to y | main.go:106:3:106:3 | y | main.go:106:8:106:8 | x |
| main.go:112:29:112:35 | initialization of wrapper | main.go:112:29:112:35 | wrapper | main.go:112:29:112:35 | argument corresponding to wrapper |
| main.go:113:2:113:2 | assignment to x | main.go:113:2:113:2 | x | main.go:113:7:113:7 | 0 |
| main.go:115:3:115:3 | assignment to y | main.go:115:3:115:3 | y | main.go:115:8:115:12 | ...+... |
| main.go:116:3:116:3 | assignment to x | main.go:113:2:113:2 | x | main.go:116:7:116:7 | y |
| main.go:128:6:128:6 | assignment to p | main.go:128:6:128:6 | p | main.go:128:6:128:6 | zero value for p |
| main.go:130:3:130:3 | assignment to p | main.go:128:6:128:6 | p | main.go:130:7:130:24 | struct literal |
| main.go:130:9:130:9 | init of 2 | main.go:122:2:122:2 | a | main.go:130:9:130:9 | 2 |
| main.go:130:12:130:18 | init of struct literal | main.go:123:2:123:2 | b | main.go:130:12:130:18 | struct literal |
| main.go:130:14:130:14 | init of 1 | main.go:89:2:89:2 | a | main.go:130:14:130:14 | 1 |
| main.go:130:17:130:17 | init of 5 | main.go:90:2:90:2 | b | main.go:130:17:130:17 | 5 |
| main.go:130:21:130:23 | init of 'n' | main.go:124:2:124:2 | c | main.go:130:21:130:23 | 'n' |
| main.go:132:3:132:3 | assignment to p | main.go:128:6:128:6 | p | main.go:132:7:132:24 | struct literal |
| main.go:132:9:132:9 | init of 3 | main.go:122:2:122:2 | a | main.go:132:9:132:9 | 3 |
| main.go:132:12:132:18 | init of struct literal | main.go:123:2:123:2 | b | main.go:132:12:132:18 | struct literal |
| main.go:132:14:132:14 | init of 4 | main.go:89:2:89:2 | a | main.go:132:14:132:14 | 4 |
| main.go:132:17:132:17 | init of 5 | main.go:90:2:90:2 | b | main.go:132:17:132:17 | 5 |
| main.go:132:21:132:23 | init of '2' | main.go:124:2:124:2 | c | main.go:132:21:132:23 | '2' |
| main.go:13:6:13:10 | assign:0 value declaration specifier | main.go:13:6:13:6 | x | main.go:13:6:13:10 | zero-init:0 value declaration specifier |
| main.go:14:2:14:8 | assign:0 ... := ... | main.go:14:2:14:2 | y | main.go:14:7:14:8 | 23 |
| main.go:17:3:17:9 | assign:0 ... += ... | main.go:14:2:14:2 | y | main.go:17:3:17:9 | compound-rhs ... += ... |
| main.go:21:3:21:7 | assign:0 ... = ... | main.go:13:6:13:6 | x | main.go:21:7:21:7 | y |
| main.go:26:28:32:1 | param-init:0 block statement | main.go:26:10:26:10 | x | main.go:26:28:32:1 | arg:0 block statement |
| main.go:27:2:27:13 | assign:0 ... := ... | main.go:27:2:27:2 | a | main.go:27:10:27:10 | x |
| main.go:27:2:27:13 | assign:1 ... := ... | main.go:27:5:27:5 | b | main.go:27:13:27:13 | 0 |
| main.go:29:3:29:13 | assign:0 ... = ... | main.go:27:2:27:2 | a | main.go:29:10:29:10 | b |
| main.go:29:3:29:13 | assign:1 ... = ... | main.go:27:5:27:5 | b | main.go:29:13:29:13 | a |
| main.go:34:19:36:1 | param-init:0 block statement | main.go:34:11:34:11 | x | main.go:34:19:36:1 | arg:0 block statement |
| main.go:39:2:39:8 | assign:0 ... := ... | main.go:39:2:39:2 | x | main.go:39:7:39:8 | 23 |
| main.go:40:2:40:10 | assign:0 ... := ... | main.go:40:2:40:4 | ptr | main.go:40:9:40:10 | &... |
| main.go:47:25:50:1 | result-init:0 block statement | main.go:47:13:47:18 | result | main.go:47:25:50:1 | result-zero-init:0 block statement |
| main.go:48:2:48:12 | assign:0 ... = ... | main.go:47:13:47:18 | result | main.go:48:11:48:12 | 42 |
| main.go:52:26:54:1 | result-init:0 block statement | main.go:52:14:52:19 | result | main.go:52:26:54:1 | result-zero-init:0 block statement |
| main.go:57:6:57:10 | assign:0 value declaration specifier | main.go:57:6:57:6 | x | main.go:57:6:57:10 | zero-init:0 value declaration specifier |
| main.go:59:3:59:7 | assign:0 ... = ... | main.go:57:6:57:6 | x | main.go:59:7:59:7 | 2 |
| main.go:63:2:63:7 | assign:0 ... := ... | main.go:63:2:63:2 | y | main.go:63:7:63:7 | 1 |
| main.go:64:6:64:11 | assign:0 ... := ... | main.go:64:6:64:6 | i | main.go:64:11:64:11 | 0 |
| main.go:64:16:64:18 | increment statement | main.go:64:6:64:6 | i | main.go:64:16:64:18 | incdec-rhs increment statement |
| main.go:68:3:68:7 | assign:0 ... = ... | main.go:63:2:63:2 | y | main.go:68:7:68:7 | 2 |
| main.go:72:2:72:7 | assign:0 ... := ... | main.go:72:2:72:2 | z | main.go:72:7:72:7 | 1 |
| main.go:73:6:73:11 | assign:0 ... := ... | main.go:73:6:73:6 | i | main.go:73:11:73:11 | 0 |
| main.go:73:16:73:18 | increment statement | main.go:73:6:73:6 | i | main.go:73:16:73:18 | incdec-rhs increment statement |
| main.go:74:3:74:7 | assign:0 ... = ... | main.go:72:2:72:2 | z | main.go:74:7:74:7 | 2 |
| main.go:82:36:86:1 | result-init:0 block statement | main.go:82:18:82:18 | a | main.go:82:36:86:1 | result-zero-init:0 block statement |
| main.go:82:36:86:1 | result-init:1 block statement | main.go:82:25:82:25 | b | main.go:82:36:86:1 | result-zero-init:1 block statement |
| main.go:83:2:83:8 | assign:0 ... := ... | main.go:83:2:83:2 | x | main.go:83:7:83:8 | 23 |
| main.go:84:2:84:15 | assign:0 ... = ... | main.go:83:2:83:2 | x | main.go:84:9:84:12 | ...+... |
| main.go:84:2:84:15 | assign:1 ... = ... | main.go:82:18:82:18 | a | main.go:84:15:84:15 | x |
| main.go:93:26:93:27 | param-init:0 block statement | main.go:93:15:93:16 | cb | main.go:93:26:93:27 | arg:0 block statement |
| main.go:95:47:101:1 | param-init:0 block statement | main.go:95:22:95:28 | wrapper | main.go:95:47:101:1 | arg:0 block statement |
| main.go:96:2:96:7 | assign:0 ... := ... | main.go:96:2:96:2 | x | main.go:96:7:96:7 | 0 |
| main.go:98:3:98:7 | assign:0 ... = ... | main.go:96:2:96:2 | x | main.go:98:7:98:7 | 1 |
| main.go:103:45:110:1 | param-init:0 block statement | main.go:103:20:103:26 | wrapper | main.go:103:45:110:1 | arg:0 block statement |
| main.go:104:2:104:7 | assign:0 ... := ... | main.go:104:2:104:2 | x | main.go:104:7:104:7 | 0 |
| main.go:106:3:106:8 | assign:0 ... := ... | main.go:106:3:106:3 | y | main.go:106:8:106:8 | x |
| main.go:112:54:119:1 | param-init:0 block statement | main.go:112:29:112:35 | wrapper | main.go:112:54:119:1 | arg:0 block statement |
| main.go:113:2:113:7 | assign:0 ... := ... | main.go:113:2:113:2 | x | main.go:113:7:113:7 | 0 |
| main.go:115:3:115:12 | assign:0 ... := ... | main.go:115:3:115:3 | y | main.go:115:8:115:12 | ...+... |
| main.go:116:3:116:7 | assign:0 ... = ... | main.go:113:2:113:2 | x | main.go:116:7:116:7 | y |
| main.go:128:6:128:8 | assign:0 value declaration specifier | main.go:128:6:128:6 | p | main.go:128:6:128:8 | zero-init:0 value declaration specifier |
| main.go:130:3:130:24 | assign:0 ... = ... | main.go:128:6:128:6 | p | main.go:130:7:130:24 | struct literal |
| main.go:130:9:130:9 | lit-init 2 | main.go:122:2:122:2 | a | main.go:130:9:130:9 | 2 |
| main.go:130:12:130:18 | lit-init struct literal | main.go:123:2:123:2 | b | main.go:130:12:130:18 | struct literal |
| main.go:130:14:130:14 | lit-init 1 | main.go:89:2:89:2 | a | main.go:130:14:130:14 | 1 |
| main.go:130:17:130:17 | lit-init 5 | main.go:90:2:90:2 | b | main.go:130:17:130:17 | 5 |
| main.go:130:21:130:23 | lit-init 'n' | main.go:124:2:124:2 | c | main.go:130:21:130:23 | 'n' |
| main.go:132:3:132:24 | assign:0 ... = ... | main.go:128:6:128:6 | p | main.go:132:7:132:24 | struct literal |
| main.go:132:9:132:9 | lit-init 3 | main.go:122:2:122:2 | a | main.go:132:9:132:9 | 3 |
| main.go:132:12:132:18 | lit-init struct literal | main.go:123:2:123:2 | b | main.go:132:12:132:18 | struct literal |
| main.go:132:14:132:14 | lit-init 4 | main.go:89:2:89:2 | a | main.go:132:14:132:14 | 4 |
| main.go:132:17:132:17 | lit-init 5 | main.go:90:2:90:2 | b | main.go:132:17:132:17 | 5 |
| main.go:132:21:132:23 | lit-init '2' | main.go:124:2:124:2 | c | main.go:132:21:132:23 | '2' |

View File

@@ -15,15 +15,15 @@
| main.go:40:10:40:10 | x | main.go:39:2:39:2 | x |
| main.go:42:8:42:10 | ptr | main.go:40:2:40:4 | ptr |
| main.go:44:12:44:12 | x | main.go:39:2:39:2 | x |
| main.go:47:13:47:18 | implicit read of result | main.go:47:13:47:18 | result |
| main.go:52:14:52:19 | implicit read of result | main.go:52:14:52:19 | result |
| main.go:47:25:50:1 | result-read:0 block statement | main.go:47:13:47:18 | result |
| main.go:52:26:54:1 | result-read:0 block statement | main.go:52:14:52:19 | result |
| main.go:61:12:61:12 | x | main.go:57:6:57:6 | x |
| main.go:64:16:64:16 | i | main.go:64:6:64:6 | i |
| main.go:70:12:70:12 | y | main.go:63:2:63:2 | y |
| main.go:73:16:73:16 | i | main.go:73:6:73:6 | i |
| main.go:79:12:79:12 | z | main.go:72:2:72:2 | z |
| main.go:82:18:82:18 | implicit read of a | main.go:82:18:82:18 | a |
| main.go:82:25:82:25 | implicit read of b | main.go:82:25:82:25 | b |
| main.go:82:36:86:1 | result-read:0 block statement | main.go:82:18:82:18 | a |
| main.go:82:36:86:1 | result-read:1 block statement | main.go:82:25:82:25 | b |
| main.go:84:9:84:9 | x | main.go:83:2:83:2 | x |
| main.go:84:15:84:15 | x | main.go:83:2:83:2 | x |
| main.go:97:2:97:8 | wrapper | main.go:95:22:95:28 | wrapper |

View File

@@ -266,6 +266,14 @@ signature module AstSig<LocationSig Location> {
Stmt getStmt(int index);
}
/**
* Gets the initializer of `switch` statement `switch`, if any.
*
* Only some languages (e.g. Go) support an initializer that is evaluated
* before the switch expression.
*/
default AstNode getSwitchInit(Switch switch) { none() }
/** A case in a switch. */
class Case extends AstNode {
/** Gets the pattern being matched by this case at the specified (zero-based) `index`. */
@@ -655,7 +663,12 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
not exists(getChild(n, _)) and
not postOrInOrder(n) and
not additionalNode(n, _, _) and
not inConditionalContext(n, _)
not inConditionalContext(n, _) and
// A switch is a branching construct with an explicit step from its
// "before" node to its "after" node, so it must keep distinct before and
// after nodes even when it has no children (e.g. an empty `switch {}`).
// Merging them would otherwise turn that step into a spurious self-loop.
not n instanceof Switch
}
private string loopHeaderTag() { result = "[LoopHeader]" }
@@ -1866,11 +1879,25 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
not exists(getRankedCaseCfgOrder(switch, _)) and firstCase.isAfter(switch)
|
n1.isBefore(switch) and
n2.isBefore(switch.getExpr())
(
n2.isBefore(getSwitchInit(switch))
or
not exists(getSwitchInit(switch)) and
(
n2.isBefore(switch.getExpr())
or
not exists(switch.getExpr()) and
n2 = firstCase
)
)
or
n1.isBefore(switch) and
not exists(switch.getExpr()) and
n2 = firstCase
n1.isAfter(getSwitchInit(switch)) and
(
n2.isBefore(switch.getExpr())
or
not exists(switch.getExpr()) and
n2 = firstCase
)
or
n1.isAfter(switch.getExpr()) and
n2 = firstCase