diff options
author | Daniel Morsing <daniel.morsing@gmail.com> | 2012-09-17 21:29:10 +0200 |
---|---|---|
committer | Daniel Morsing <daniel.morsing@gmail.com> | 2012-09-17 21:29:10 +0200 |
commit | 506438723710dd8473db2f5f7848d2fe721b7a22 (patch) | |
tree | 446219e01aa160977eaf02e4d0821739df900912 | |
parent | 83ff7191f858e6bb834455b3503f785a50c762e9 (diff) | |
download | go-506438723710dd8473db2f5f7848d2fe721b7a22.tar.gz |
cmd/gc: add missing conversion from bool to interface in switches.
In switches without an expression, the compiler would not convert the implicit true to an interface, causing codegen errors.
Fixes issue 3980.
R=golang-dev, rsc
CC=golang-dev
http://codereview.appspot.com/6497147
-rw-r--r-- | src/cmd/gc/swt.c | 7 | ||||
-rw-r--r-- | test/switch.go | 11 |
2 files changed, 18 insertions, 0 deletions
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c index aff1b5ea8..860fed84a 100644 --- a/src/cmd/gc/swt.c +++ b/src/cmd/gc/swt.c @@ -442,6 +442,10 @@ exprbsw(Case *c0, int ncase, int arg) n = c0->node; lno = setlineno(n); + if(assignop(n->left->type, exprname->type, nil) == OCONVIFACE || + assignop(exprname->type, n->left->type, nil) == OCONVIFACE) + goto snorm; + switch(arg) { case Strue: a = nod(OIF, N, N); @@ -457,6 +461,7 @@ exprbsw(Case *c0, int ncase, int arg) break; default: + snorm: a = nod(OIF, N, N); a->ntest = nod(OEQ, exprname, n->left); // if name == val typecheck(&a->ntest, Erv); @@ -520,6 +525,8 @@ exprswitch(Node *sw) exprname = temp(sw->ntest->type); cas = list1(nod(OAS, exprname, sw->ntest)); typechecklist(cas, Etop); + } else { + exprname = nodbool(arg == Strue); } c0 = mkcaselist(sw, arg); diff --git a/test/switch.go b/test/switch.go index a4242f257..fd8748b9b 100644 --- a/test/switch.go +++ b/test/switch.go @@ -294,6 +294,17 @@ func main() { assert(false, `i should be "hello"`) } + // switch on implicit bool converted to interface + // was broken: see issue 3980 + switch i := interface{}(true); { + case i: + assert(true, "true") + case false: + assert(false, "i should be true") + default: + assert(false, "i should be true") + } + // switch on array. switch ar := [3]int{1, 2, 3}; ar { case [3]int{1,2,3}: |