// optimization: one-case select: single op.
if(i == 1) {
cas = sel->list->n;
+ setlineno(cas);
l = cas->ninit;
if(cas->left != N) { // not default:
n = cas->left;
// this rewrite is used by both the general code and the next optimization.
for(l=sel->list; l; l=l->next) {
cas = l->n;
+ setlineno(cas);
n = cas->left;
if(n == N)
continue;
}
n = cas->left;
+ setlineno(n);
r = nod(OIF, N, N);
r->ninit = cas->ninit;
switch(n->op) {
sel->ninit = nil;
// generate sel-struct
+ setlineno(sel);
var = nod(OXXX, N, N);
tempname(var, ptrto(types[TUINT8]));
r = nod(OAS, var, mkcall("newselect", var->type, nil, nodintconst(sel->xoffset)));
// register cases
for(l=sel->list; l; l=l->next) {
cas = l->n;
+ setlineno(cas);
n = cas->left;
r = nod(OIF, N, N);
r->nbody = cas->ninit;
}
// run the select
+ setlineno(sel);
init = list(init, mkcall("selectgo", T, nil, var));
sel->nbody = init;
--- /dev/null
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2011 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.
+
+package main
+
+import (
+ "runtime"
+ "strings"
+)
+
+var t *struct {
+ c chan int
+}
+
+var c chan int
+
+func f() {
+ select {
+ case <-t.c: // THIS IS LINE 22
+ break
+ case <-c:
+ break
+ }
+}
+
+func main() {
+ defer func() {
+ recover()
+ for i := 0;; i++ {
+ pc, file, line, ok := runtime.Caller(i)
+ if !ok {
+ print("BUG: bug347: cannot find caller\n")
+ return
+ }
+ if !strings.Contains(file, "bug347.go") || runtime.FuncForPC(pc).Name() != "main.f" {
+ // walk past runtime frames
+ continue
+ }
+ if line != 22 {
+ print("BUG: bug347: panic at ", file, ":", line, " in ", runtime.FuncForPC(pc).Name(), "\n")
+ }
+ return
+ }
+ }()
+ f()
+}