]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: report block start for gotos jumping into blocks
authorRobert Griesemer <gri@golang.org>
Wed, 19 Apr 2017 00:16:54 +0000 (17:16 -0700)
committerRobert Griesemer <gri@golang.org>
Wed, 19 Apr 2017 02:27:58 +0000 (02:27 +0000)
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>
src/cmd/compile/internal/syntax/branches.go
test/goto.go

index b54a2c75676793a33c42409e8181a4307d6968c0..a6b533319a5bf01d0161035441dc88ee16900427 100644 (file)
@@ -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)
                        }
                }
        }
index 6630fb7e340c2af4f1119f6e8ca60ef10c8bb149..d660c9ce624aaa69c3e355940c9e891b4643c561 100644 (file)
@@ -77,7 +77,7 @@ L:
 
 // error shows first offending variable
 func _() {
-       goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto L jumps over declaration of y at LINE+3|goto jumps over declaration"
+       goto L // ERROR "goto L jumps over declaration of y at LINE+3|goto jumps over declaration"
        x := 1 // GCCGO_ERROR "defined here"
        _ = x
        y := 1
@@ -87,7 +87,7 @@ L:
 
 // goto not okay even if code path is dead
 func _() {
-       goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto L jumps over declaration of y at LINE+3|goto jumps over declaration"
+       goto L // ERROR "goto L jumps over declaration of y at LINE+3|goto jumps over declaration"
        x := 1 // GCCGO_ERROR "defined here"
        _ = x
        y := 1
@@ -114,7 +114,7 @@ L:
 
 // goto into inner block not okay
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
        {      // GCCGO_ERROR "block starts here"
        L:
        }
@@ -125,12 +125,12 @@ func _() {
        { // GCCGO_ERROR "block starts here"
        L:
        }
-       goto L // ERROR "goto L jumps into block starting at LINE-3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
 }
 
 // error shows first (outermost) offending block
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
        {
                {
                        { // GCCGO_ERROR "block starts here"
@@ -142,7 +142,7 @@ func _() {
 
 // error prefers block diagnostic over declaration diagnostic
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
        x := 1
        _ = x
        { // GCCGO_ERROR "block starts here"
@@ -179,14 +179,14 @@ L:
 }
 
 func _() {
-       goto L    // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+       goto L    // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
        if true { // GCCGO_ERROR "block starts here"
        L:
        }
 }
 
 func _() {
-       goto L    // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+       goto L    // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
        if true { // GCCGO_ERROR "block starts here"
        L:
        } else {
@@ -194,7 +194,7 @@ func _() {
 }
 
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
        if true {
        } else { // GCCGO_ERROR "block starts here"
        L:
@@ -205,13 +205,13 @@ func _() {
        if false { // GCCGO_ERROR "block starts here"
        L:
        } else {
-               goto L // ERROR "goto L jumps into block starting at LINE-3|goto L jumps into block|goto jumps into block"
+               goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
        }
 }
 
 func _() {
        if true {
-               goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+               goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
        } else { // GCCGO_ERROR "block starts here"
        L:
        }
@@ -219,7 +219,7 @@ func _() {
 
 func _() {
        if true {
-               goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+               goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
        } else if false { // GCCGO_ERROR "block starts here"
        L:
        }
@@ -227,7 +227,7 @@ func _() {
 
 func _() {
        if true {
-               goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+               goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
        } else if false { // GCCGO_ERROR "block starts here"
        L:
        } else {
@@ -241,7 +241,7 @@ func _() {
        // really is LINE+1 (like in the previous test),
        // even though it looks like it might be LINE+3 instead.
        if true {
-               goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+               goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
        } else if false {
        } else { // GCCGO_ERROR "block starts here"
        L:
@@ -290,7 +290,7 @@ func _() {
        for { // GCCGO_ERROR "block starts here"
        L:
        }
-       goto L // ERROR "goto L jumps into block starting at LINE-3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
 }
 
 func _() {
@@ -299,49 +299,49 @@ func _() {
        L1:
        }
 L:
-       goto L1 // ERROR "goto L1 jumps into block starting at LINE-5|goto L1 jumps into block|goto jumps into block"
+       goto L1 // ERROR "goto L1 jumps into block starting at LINE-5|goto jumps into block"
 }
 
 func _() {
        for i < n { // GCCGO_ERROR "block starts here"
        L:
        }
-       goto L // ERROR "goto L jumps into block starting at LINE-3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
 }
 
 func _() {
        for i = 0; i < n; i++ { // GCCGO_ERROR "block starts here"
        L:
        }
-       goto L // ERROR "goto L jumps into block starting at LINE-3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
 }
 
 func _() {
        for i = range x { // GCCGO_ERROR "block starts here"
        L:
        }
-       goto L // ERROR "goto L jumps into block starting at LINE-3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
 }
 
 func _() {
        for i = range c { // GCCGO_ERROR "block starts here"
        L:
        }
-       goto L // ERROR "goto L jumps into block starting at LINE-3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
 }
 
 func _() {
        for i = range m { // GCCGO_ERROR "block starts here"
        L:
        }
-       goto L // ERROR "goto L jumps into block starting at LINE-3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
 }
 
 func _() {
        for i = range s { // GCCGO_ERROR "block starts here"
        L:
        }
-       goto L // ERROR "goto L jumps into block starting at LINE-3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
 }
 
 // switch
@@ -395,7 +395,7 @@ func _() {
 }
 
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
        switch i {
        case 0:
        L: // GCCGO_ERROR "block starts here"
@@ -403,7 +403,7 @@ func _() {
 }
 
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
        switch i {
        case 0:
        L: // GCCGO_ERROR "block starts here"
@@ -413,7 +413,7 @@ func _() {
 }
 
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
        switch i {
        case 0:
        default:
@@ -424,7 +424,7 @@ func _() {
 func _() {
        switch i {
        default:
-               goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+               goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
        case 0:
        L: // GCCGO_ERROR "block starts here"
        }
@@ -436,7 +436,7 @@ func _() {
        L: // GCCGO_ERROR "block starts here"
                ;
        default:
-               goto L // ERROR "goto L jumps into block starting at LINE-4|goto L jumps into block|goto jumps into block"
+               goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
        }
 }
 
@@ -492,7 +492,7 @@ func _() {
 }
 
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+2|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
        select {
        case c <- 1:
        L: // GCCGO_ERROR "block starts here"
@@ -500,7 +500,7 @@ func _() {
 }
 
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+2|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
        select {
        case c <- 1:
        L: // GCCGO_ERROR "block starts here"
@@ -510,7 +510,7 @@ func _() {
 }
 
 func _() {
-       goto L // ERROR "goto L jumps into block starting at LINE+3|goto L jumps into block|goto jumps into block"
+       goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
        select {
        case <-c:
        default:
@@ -521,7 +521,7 @@ func _() {
 func _() {
        select {
        default:
-               goto L // ERROR "goto L jumps into block starting at LINE+1|goto L jumps into block|goto jumps into block"
+               goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
        case <-c:
        L: // GCCGO_ERROR "block starts here"
        }
@@ -533,6 +533,6 @@ func _() {
        L: // GCCGO_ERROR "block starts here"
                ;
        default:
-               goto L // ERROR "goto L jumps into block starting at LINE-4|goto L jumps into block|goto jumps into block"
+               goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
        }
 }