1
0
mirror of https://github.com/golang/go synced 2024-11-21 19:34:46 -07:00

gc: fix select line number

Fixes #1393.

R=ken2
CC=golang-dev
https://golang.org/cl/4811054
This commit is contained in:
Russ Cox 2011-07-26 00:52:17 -04:00
parent bf899befdb
commit cce10dacc6
3 changed files with 56 additions and 0 deletions

View File

@ -685,6 +685,7 @@ select_stmt:
LBODY caseblock_list '}'
{
$$ = nod(OSELECT, N, N);
$$->lineno = typesw->lineno;
$$->list = $4;
typesw = typesw->left;
}

View File

@ -108,6 +108,7 @@ walkselect(Node *sel)
// 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;
@ -165,6 +166,7 @@ walkselect(Node *sel)
// 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;
@ -238,6 +240,7 @@ walkselect(Node *sel)
}
n = cas->left;
setlineno(n);
r = nod(OIF, N, N);
r->ninit = cas->ninit;
switch(n->op) {
@ -283,6 +286,7 @@ walkselect(Node *sel)
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)));
@ -292,6 +296,7 @@ walkselect(Node *sel)
// 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;
@ -338,6 +343,7 @@ walkselect(Node *sel)
}
// run the select
setlineno(sel);
init = list(init, mkcall("selectgo", T, nil, var));
sel->nbody = init;

49
test/fixedbugs/bug347.go Normal file
View File

@ -0,0 +1,49 @@
// $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()
}