]> Cypherpunks repositories - gostls13.git/commitdiff
exp/ssa: support multiple labels on same statement.
authorAlan Donovan <adonovan@google.com>
Tue, 26 Feb 2013 19:07:03 +0000 (14:07 -0500)
committerAlan Donovan <adonovan@google.com>
Tue, 26 Feb 2013 19:07:03 +0000 (14:07 -0500)
Actually it already worked since the spec only requires that
the one immediately preceding a for/switch/... be usable as
the target of a break or continue statement.

Added a test.
Also: allocate Function.lblocks on first use.

R=gri
CC=golang-dev
https://golang.org/cl/7365058

src/pkg/exp/ssa/builder.go
src/pkg/exp/ssa/func.go
src/pkg/exp/ssa/interp/testdata/coverage.go

index d76d1ffa7513a24279ba2a10d73fed5924cd5740..99102393472bd1b0315a5f9841e2a04ef4723fb1 100644 (file)
@@ -2215,7 +2215,6 @@ func (b *Builder) stmt(fn *Function, _s ast.Stmt) {
        // target is always set; its _break and _continue are set only
        // within the body of switch/typeswitch/select/for/range.
        // It is effectively an additional default-nil parameter of stmt().
-       // TODO(adonovan): fix: handle multiple labels on the same stmt.
        var label *lblock
 start:
        switch s := _s.(type) {
index eb45ee0f82276b59988a84106593e67e283d4659..6e0aa583516f41bf1bae80152dfbc4fece246f3a 100644 (file)
@@ -152,6 +152,9 @@ func (f *Function) labelledBlock(label *ast.Ident) *lblock {
        lb := f.lblocks[label.Obj]
        if lb == nil {
                lb = &lblock{_goto: f.newBasicBlock(label.Name)}
+               if f.lblocks == nil {
+                       f.lblocks = make(map[*ast.Object]*lblock)
+               }
                f.lblocks[label.Obj] = lb
        }
        return lb
@@ -200,7 +203,6 @@ func (f *Function) start(idents map[*ast.Ident]types.Object) {
        if f.syntax == nil {
                return // synthetic function; no syntax tree
        }
-       f.lblocks = make(map[*ast.Object]*lblock)
 
        // Receiver (at most one inner iteration).
        if f.syntax.recvField != nil {
index a07549b824f2b81a7629f37503bbfaa3b9efe305..c271669ae839136a40b7b7bdafff97c16ae2aa85 100644 (file)
@@ -363,3 +363,30 @@ func init() {
                panic("I.f not called twice")
        }
 }
+
+// Multiple labels on same statement.
+func multipleLabels() {
+       var trace []int
+       i := 0
+one:
+two:
+       for ; i < 3; i++ {
+               trace = append(trace, i)
+               switch i {
+               case 0:
+                       continue two
+               case 1:
+                       i++
+                       goto one
+               case 2:
+                       break two
+               }
+       }
+       if x := fmt.Sprint(trace); x != "[0 1 2]" {
+               panic(x)
+       }
+}
+
+func init() {
+       multipleLabels()
+}