diff options
| author | Robert Griesemer <gri@golang.org> | 2017-04-18 17:16:54 -0700 |
|---|---|---|
| committer | Robert Griesemer <gri@golang.org> | 2017-04-19 02:27:58 +0000 |
| commit | bb70f517e9ee0406408ffd82a2ce60cdef95ec3b (patch) | |
| tree | 28673442d44aebabae8912ed06e4ac5bdaf2455d /src | |
| parent | 08fe56386ba117a44b52b28e5ab8dd4321af49f9 (diff) | |
| download | go-bb70f517e9ee0406408ffd82a2ce60cdef95ec3b.tar.xz | |
cmd/compile: report block start for gotos jumping into blocks
Follow-up on https://go-review.googlesource.com/#/c/39998/
which dropped this information.
The reported blocks are the innermost blocks containing a
label jumped to from outside, not the outermost block as
reported originally by cmd/compile.
We could report the outermost block with a slighly more
involved algorithm (need to track containing blocks for
all unresolved forward gotos), but since gccgo also reports
the innermost blocks, the current approach seems good enough.
Change-Id: Ic0235b8fafe8d5f99dc9872b58e90e8d9e72c5db
Reviewed-on: https://go-review.googlesource.com/40980
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/syntax/branches.go | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/src/cmd/compile/internal/syntax/branches.go b/src/cmd/compile/internal/syntax/branches.go index b54a2c7567..a6b533319a 100644 --- a/src/cmd/compile/internal/syntax/branches.go +++ b/src/cmd/compile/internal/syntax/branches.go @@ -25,21 +25,19 @@ func checkBranches(body *BlockStmt, errh ErrorHandler) { // scope of all labels in this body ls := &labelScope{errh: errh} - fwdGo2s := ls.blockBranches(nil, 0, nil, body.List) + fwdGo2s := ls.blockBranches(nil, 0, nil, body.Pos(), body.List) // If there are any forward gotos left, no matching label was // found for them. Either those labels were never defined, or // they are inside blocks and not reachable from the gotos. for _, go2 := range fwdGo2s { - var msg string name := go2.Label.Value - if alt, found := ls.labels[name]; found { - msg = "goto %s jumps into block" - alt.used = true // avoid "defined and not used" error + if l := ls.labels[name]; l != nil { + l.used = true // avoid "defined and not used" error + ls.err(go2.Label.Pos(), "goto %s jumps into block starting at %s", name, l.parent.start) } else { - msg = "label %s not defined" + ls.err(go2.Label.Pos(), "label %s not defined", name) } - ls.err(go2.Label.Pos(), msg, name) } // spec: "It is illegal to define a label that is never used." @@ -64,7 +62,8 @@ type label struct { type block struct { parent *block // immediately enclosing block, or nil - lstmt *LabeledStmt // labeled statement to which this block belongs, or nil + start src.Pos // start of block + lstmt *LabeledStmt // labeled statement associated with this block, or nil } func (ls *labelScope) err(pos src.Pos, format string, args ...interface{}) { @@ -128,11 +127,12 @@ const ( continueOk ) -// blockBranches processes a block's body and returns the list of unresolved (forward) gotos. -// parent is the immediately enclosing block (or nil), context provides information about the -// enclosing statements, and lstmt is the labeled statement this body belongs to, or nil. -func (ls *labelScope) blockBranches(parent *block, context uint, lstmt *LabeledStmt, body []Stmt) []*BranchStmt { - b := &block{parent: parent, lstmt: lstmt} +// blockBranches processes a block's body starting at start and returns the +// list of unresolved (forward) gotos. parent is the immediately enclosing +// block (or nil), context provides information about the enclosing statements, +// and lstmt is the labeled statement asociated with this block, or nil. +func (ls *labelScope) blockBranches(parent *block, context uint, lstmt *LabeledStmt, start src.Pos, body []Stmt) []*BranchStmt { + b := &block{parent: parent, start: start, lstmt: lstmt} var varPos src.Pos var varName Expr @@ -159,8 +159,8 @@ func (ls *labelScope) blockBranches(parent *block, context uint, lstmt *LabeledS return false } - innerBlock := func(flags uint, body []Stmt) { - fwdGo2s = append(fwdGo2s, ls.blockBranches(b, context|flags, lstmt, body)...) + innerBlock := func(flags uint, start src.Pos, body []Stmt) { + fwdGo2s = append(fwdGo2s, ls.blockBranches(b, context|flags, lstmt, start, body)...) } for _, stmt := range body { @@ -277,25 +277,25 @@ func (ls *labelScope) blockBranches(parent *block, context uint, lstmt *LabeledS case *BlockStmt: // Unresolved forward gotos from the nested block // become forward gotos for the current block. - innerBlock(0, s.List) + innerBlock(0, s.Pos(), s.List) case *IfStmt: - innerBlock(0, s.Then.List) + innerBlock(0, s.Then.Pos(), s.Then.List) if s.Else != nil { - innerBlock(0, []Stmt{s.Else}) + innerBlock(0, s.Else.Pos(), []Stmt{s.Else}) } case *ForStmt: - innerBlock(breakOk|continueOk, s.Body.List) + innerBlock(breakOk|continueOk, s.Body.Pos(), s.Body.List) case *SwitchStmt: for _, cc := range s.Body { - innerBlock(breakOk, cc.Body) + innerBlock(breakOk, cc.Pos(), cc.Body) } case *SelectStmt: for _, cc := range s.Body { - innerBlock(breakOk, cc.Body) + innerBlock(breakOk, cc.Pos(), cc.Body) } } } |
