mirror of https://github.com/golang/go.git
exp/ssa: support multiple labels on same statement.
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
This commit is contained in:
parent
b302d68ebc
commit
c8c16cfbb9
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue