Commit 375092bd authored by Alberto Donizetti's avatar Alberto Donizetti Committed by Quentin Smith

cmd/compile: fix bogus "fallthrough statement out of place"

When processing a fallthrough, the casebody function in swt.go
checks that the last statement has indeed Op == OXFALL (not-processed
fallthrough) before setting it to OFALL (processed fallthrough).

Unfortunately, sometimes the fallthrough statement won't be in the
last node. For example, in

case 0:
	 return func() int {return 1}()
	 fallthrough

the compiler generates

autotmp_0 = (func literal)(); return autotmp_0; fallthrough; <node VARKILL>

with an OVARKILL node in the last position. casebody will find that
last.Op != OXFALL, won't mark the fallthrough as processed, and the
fallthrough line will cause a "fallthrough statement out of place" error.

To fix this, we change casebody so that it searches for the fallthrough
statement backwards in the statements list, without assuming that it'll
be in the last position.

Fixes #13262

Change-Id: I366c6caa7fd7442d365bd7a08cc66a552212d9b2
Reviewed-on: https://go-review.googlesource.com/22921
Run-TryBot: Quentin Smith <quentin@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarQuentin Smith <quentin@golang.org>
parent d15295c6
......@@ -449,8 +449,18 @@ func casebody(sw *Node, typeswvar *Node) {
}
stat = append(stat, n.Nbody.Slice()...)
// Search backwards for the index of the fallthrough
// statement. Do not assume it'll be in the last
// position, since in some cases (e.g. when the statement
// list contains autotmp_ variables), one or more OVARKILL
// nodes will be at the end of the list.
fallIndex := len(stat) - 1
for stat[fallIndex].Op == OVARKILL {
fallIndex--
}
last := stat[fallIndex]
// botch - shouldn't fall through declaration
last := stat[len(stat)-1]
if last.Xoffset == n.Xoffset && last.Op == OXFALL {
if typeswvar != nil {
setlineno(last)
......
......@@ -195,7 +195,7 @@ func walkstmt(n *Node) *Node {
n.Op = OEMPTY // don't leave plain values as statements.
}
// special case for a receive where we throw away
// special case for a receive where we throw away
// the value received.
case ORECV:
if n.Typecheck == 0 {
......
// compile
// 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.
// Issue 13262: cmd/compile: bogus "fallthrough
// statement out of place" error
package p
func f() int {
var a int
switch a {
case 0:
return func() int { return 1 }()
fallthrough
default:
}
return 0
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment