mirror of
https://github.com/github/codeql.git
synced 2026-06-24 14:17:05 +02:00
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:
@@ -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))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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] |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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) |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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' |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user