Skip to content

Commit 03ccda1

Browse files
authored
interp: fix type switch on arbitrary expressions
If the value on which to type-switch was already set (i.e. a variable), there was no problem. But if it had to be obtained through a complex expression (func call, array index, etc...), then the code to retrieve the value prior type-switch was not scheduled. This is now fixed. This issue is nasty because the behavior is silently changed, leading potentially to further unrelated issues or runtime panics. Fixes #1444.
1 parent e026215 commit 03ccda1

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

_test/switch39.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package main
2+
3+
func f(params ...interface{}) {
4+
switch p0 := params[0].(type) {
5+
case string:
6+
println("string:", p0)
7+
default:
8+
println("not a string")
9+
}
10+
}
11+
12+
func main() {
13+
f("Hello")
14+
}
15+
16+
// Output:
17+
// string: Hello

_test/switch40.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package main
2+
3+
func f(params ...interface{}) {
4+
switch params[0].(type) {
5+
case string:
6+
println("a string")
7+
default:
8+
println("not a string")
9+
}
10+
}
11+
12+
func main() {
13+
f("Hello")
14+
}
15+
16+
// Output:
17+
// a string

interp/cfg.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2051,7 +2051,14 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string
20512051
}
20522052
sbn.start = clauses[0].start
20532053
n.start = n.child[0].start
2054-
n.child[0].tnext = sbn.start
2054+
if n.kind == typeSwitch {
2055+
// Handle the typeSwitch init (the type assert expression).
2056+
init := n.child[1].lastChild().child[0]
2057+
init.tnext = sbn.start
2058+
n.child[0].tnext = init.start
2059+
} else {
2060+
n.child[0].tnext = sbn.start
2061+
}
20552062

20562063
case switchIfStmt: // like an if-else chain
20572064
sc = sc.pop()

0 commit comments

Comments
 (0)