interp: fix a wrong control flow in switch
In switch case expressions, the condition on case clause was not always properly evaluated. Reverse the order of case clause evaluations (as already done for if-else-if fashion), and fix the wiring to false-next and true-next nodes. Fixes #1126.
This commit is contained in:
@@ -57,7 +57,7 @@ func main() {
|
||||
fmt.Println(err, vvv)
|
||||
}
|
||||
|
||||
// Ouput:
|
||||
// Output:
|
||||
// <nil> {work bob@work.com}
|
||||
// <nil> {work bob@work.com}
|
||||
// <nil> {work bob@work.com}
|
||||
|
||||
@@ -103,7 +103,7 @@ func main() {
|
||||
intoMap()
|
||||
}
|
||||
|
||||
// Ouput:
|
||||
// Output:
|
||||
// 0 : foo
|
||||
// 1 : bar
|
||||
// 0 : foo
|
||||
|
||||
@@ -8,5 +8,5 @@ func main() {
|
||||
fmt.Printf("%v %T\n", x, x)
|
||||
}
|
||||
|
||||
// Ouput:
|
||||
// Output:
|
||||
// ab string
|
||||
|
||||
23
_test/issue-1126.go
Normal file
23
_test/issue-1126.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := errors.New("hello there")
|
||||
|
||||
switch true {
|
||||
case err == nil:
|
||||
break
|
||||
case strings.Contains(err.Error(), "hello"):
|
||||
fmt.Println("True!")
|
||||
default:
|
||||
fmt.Println("False!")
|
||||
}
|
||||
}
|
||||
|
||||
// Output:
|
||||
// True!
|
||||
@@ -1737,15 +1737,17 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {
|
||||
break
|
||||
}
|
||||
// Chain case clauses.
|
||||
for i, c := range clauses[:l-1] {
|
||||
// Chain to next clause.
|
||||
setFNext(c, clauses[i+1])
|
||||
for i := l - 1; i >= 0; i-- {
|
||||
c := clauses[i]
|
||||
if len(c.child) == 0 {
|
||||
c.tnext = n // Clause body is empty, exit.
|
||||
} else {
|
||||
body := c.lastChild()
|
||||
c.tnext = body.start
|
||||
if len(body.child) > 0 && body.lastChild().kind == fallthroughtStmt {
|
||||
c.child[0].tnext = c
|
||||
c.start = c.child[0].start
|
||||
|
||||
if i < l-1 && len(body.child) > 0 && body.lastChild().kind == fallthroughtStmt {
|
||||
if n.kind == typeSwitch {
|
||||
err = body.lastChild().cfgErrorf("cannot fallthrough in type switch")
|
||||
}
|
||||
@@ -1758,15 +1760,16 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {
|
||||
body.tnext = n // Exit switch at end of clause body.
|
||||
}
|
||||
}
|
||||
}
|
||||
c := clauses[l-1] // Last clause.
|
||||
c.fnext = n
|
||||
if len(c.child) == 0 {
|
||||
c.tnext = n // Clause body is empty, exit.
|
||||
} else {
|
||||
body := c.lastChild()
|
||||
c.tnext = body.start
|
||||
body.tnext = n
|
||||
|
||||
if i == l-1 {
|
||||
setFNext(clauses[i], n)
|
||||
continue
|
||||
}
|
||||
if len(clauses[i+1].child) > 1 {
|
||||
setFNext(c, clauses[i+1].start)
|
||||
} else {
|
||||
setFNext(c, clauses[i+1])
|
||||
}
|
||||
}
|
||||
n.start = n.child[0].start
|
||||
n.child[0].tnext = sbn.start
|
||||
|
||||
Reference in New Issue
Block a user