]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: correctly import labels, gotos, and fallthroughs
authorRobert Griesemer <gri@golang.org>
Wed, 25 May 2016 23:38:02 +0000 (16:38 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 26 May 2016 00:32:03 +0000 (00:32 +0000)
The importer had several bugs with respect to labels and gotos:
- it didn't create a new ONAME node for label names (label dcl,
  goto, continue, and break)
- it overwrote the symbol for gotos with the dclstack
- it didn't set the dclstack for labels

In the process changed export format slightly to always assume
a label name for labels and gotos, and never assume a label for
fallthroughs.

For fallthroughs and switch cases, now also set Xoffset like in
the parser. (Not setting it, i.e., using 0 was ok since this is
only used for verifying correct use of fallthroughs, which was
checked already. But it's an extra level of verification of the
import.)

Fixes #15838.

Change-Id: I3637f6314b8651c918df0c8cd70cd858c92bd483
Reviewed-on: https://go-review.googlesource.com/23445
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/bexport.go
src/cmd/compile/internal/gc/bimport.go
test/fixedbugs/issue15838.dir/a.go [new file with mode: 0644]
test/fixedbugs/issue15838.dir/b.go [new file with mode: 0644]
test/fixedbugs/issue15838.go [new file with mode: 0644]

index 1997068d1af4efdf16558d9a4e39e7ed967fe482..80b8e4f9450df39fb08e536683f8327df8c5108a 100644 (file)
@@ -1488,19 +1488,18 @@ func (p *exporter) stmt(n *Node) {
                p.stmtList(n.List)
                p.stmtList(n.Nbody)
 
-       case OFALL:
-               op = OXFALL
-               fallthrough
+       case OFALL, OXFALL:
+               p.op(OXFALL)
 
-       case OBREAK, OCONTINUE, OGOTO, OXFALL:
+       case OBREAK, OCONTINUE:
                p.op(op)
                p.exprsOrNil(n.Left, nil)
 
        case OEMPTY:
                // nothing to emit
 
-       case OLABEL:
-               p.op(OLABEL)
+       case OGOTO, OLABEL:
+               p.op(op)
                p.expr(n.Left)
 
        default:
index b9e69c24bb9a879b2c1046134d6407b3593107ac..36aa0e8b9ceaf36a5a18bd7c9316d93b47589629 100644 (file)
@@ -1038,6 +1038,7 @@ func (p *importer) node() *Node {
        case OXCASE:
                markdcl()
                n := Nod(OXCASE, nil, nil)
+               n.Xoffset = int64(block)
                n.List.Set(p.exprList())
                // TODO(gri) eventually we must declare variables for type switch
                // statements (type switch statements are not yet exported)
@@ -1048,16 +1049,24 @@ func (p *importer) node() *Node {
        // case OFALL:
        //      unreachable - mapped to OXFALL case below by exporter
 
-       case OBREAK, OCONTINUE, OGOTO, OXFALL:
+       case OXFALL:
+               n := Nod(OXFALL, nil, nil)
+               n.Xoffset = int64(block)
+               return n
+
+       case OBREAK, OCONTINUE:
                left, _ := p.exprsOrNil()
+               if left != nil {
+                       left = newname(left.Sym)
+               }
                return Nod(op, left, nil)
 
        // case OEMPTY:
        //      unreachable - not emitted by exporter
 
-       case OLABEL:
-               n := Nod(OLABEL, p.expr(), nil)
-               n.Left.Sym = dclstack // context, for goto restrictions
+       case OGOTO, OLABEL:
+               n := Nod(op, newname(p.expr().Sym), nil)
+               n.Sym = dclstack // context, for goto restrictions
                return n
 
        case OEND:
diff --git a/test/fixedbugs/issue15838.dir/a.go b/test/fixedbugs/issue15838.dir/a.go
new file mode 100644 (file)
index 0000000..15b7f1d
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+func F1() {
+L:
+       goto L
+}
+
+func F2() {
+L:
+       for {
+               break L
+       }
+}
+
+func F3() {
+L:
+       for {
+               continue L
+       }
+}
+
+func F4() {
+       switch {
+       case true:
+               fallthrough
+       default:
+       }
+}
+
+type T struct{}
+
+func (T) M1() {
+L:
+       goto L
+}
+
+func (T) M2() {
+L:
+       for {
+               break L
+       }
+}
+
+func (T) M3() {
+L:
+       for {
+               continue L
+       }
+}
+
+func (T) M4() {
+       switch {
+       case true:
+               fallthrough
+       default:
+       }
+}
diff --git a/test/fixedbugs/issue15838.dir/b.go b/test/fixedbugs/issue15838.dir/b.go
new file mode 100644 (file)
index 0000000..9fd6efc
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "./a"
+
+type T struct{ a.T }
diff --git a/test/fixedbugs/issue15838.go b/test/fixedbugs/issue15838.go
new file mode 100644 (file)
index 0000000..fb1c64d
--- /dev/null
@@ -0,0 +1,12 @@
+// compiledir
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test cases for issue #15838, and related failures.
+// Make sure the importer correctly sets up nodes for
+// label decls, goto, continue, break, and fallthrough
+// statements.
+
+package ignored