mirror of
https://github.com/golang/go
synced 2024-11-26 09:28:07 -07:00
cmd/gc: fix compiler crash during race instrumentation
The compiler is crashing on the following code: type TypeID int func (t *TypeID) encodeType(x int) (tt TypeID, err error) { switch x { case 0: return t.encodeType(x * x) } return 0, nil } The pass marks "return struct" {tt TypeID, err error} as used, and this causes internal check failure. I've added the test to: https://golang.org/cl/6525052/diff/7020/src/pkg/runtime/race/regression_test.go R=golang-dev, minux.ma, rsc CC=golang-dev https://golang.org/cl/6611049
This commit is contained in:
parent
27e93fbd00
commit
21b2ce724a
@ -17,12 +17,12 @@
|
|||||||
#include "go.h"
|
#include "go.h"
|
||||||
#include "opnames.h"
|
#include "opnames.h"
|
||||||
|
|
||||||
//TODO: do not instrument initialization as writes:
|
// TODO(dvyukov): do not instrument initialization as writes:
|
||||||
// a := make([]int, 10)
|
// a := make([]int, 10)
|
||||||
|
|
||||||
static void racewalklist(NodeList *l, NodeList **init);
|
static void racewalklist(NodeList *l, NodeList **init);
|
||||||
static void racewalknode(Node **np, NodeList **init, int wr, int skip);
|
static void racewalknode(Node **np, NodeList **init, int wr, int skip);
|
||||||
static void callinstr(Node *n, NodeList **init, int wr, int skip);
|
static int callinstr(Node *n, NodeList **init, int wr, int skip);
|
||||||
static Node* uintptraddr(Node *n);
|
static Node* uintptraddr(Node *n);
|
||||||
static Node* basenod(Node *n);
|
static Node* basenod(Node *n);
|
||||||
|
|
||||||
@ -42,6 +42,9 @@ racewalk(Node *fn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(dvyukov): ideally this should be:
|
||||||
|
// racefuncenter(getreturnaddress())
|
||||||
|
// because it's much more costly to obtain from runtime library.
|
||||||
nd = mkcall("racefuncenter", T, nil);
|
nd = mkcall("racefuncenter", T, nil);
|
||||||
fn->enter = list(fn->enter, nd);
|
fn->enter = list(fn->enter, nd);
|
||||||
nd = mkcall("racefuncexit", T, nil);
|
nd = mkcall("racefuncexit", T, nil);
|
||||||
@ -200,7 +203,7 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
|
|||||||
racewalknode(&n->left, init, 0, 0);
|
racewalknode(&n->left, init, 0, 0);
|
||||||
if(istype(n->left->type, TMAP)) {
|
if(istype(n->left->type, TMAP)) {
|
||||||
// crashes on len(m[0]) or len(f())
|
// crashes on len(m[0]) or len(f())
|
||||||
USED(&n1);
|
USED(n1);
|
||||||
/*
|
/*
|
||||||
n1 = nod(OADDR, n->left, N);
|
n1 = nod(OADDR, n->left, N);
|
||||||
n1 = conv(n1, types[TUNSAFEPTR]);
|
n1 = conv(n1, types[TUNSAFEPTR]);
|
||||||
@ -350,41 +353,44 @@ ret:
|
|||||||
*np = n;
|
*np = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
callinstr(Node *n, NodeList **init, int wr, int skip)
|
callinstr(Node *n, NodeList **init, int wr, int skip)
|
||||||
{
|
{
|
||||||
Node *f, *b;
|
Node *f, *b;
|
||||||
Type *t, *t1;
|
Type *t, *t1;
|
||||||
int class;
|
int class, res;
|
||||||
|
|
||||||
//print("callinstr for %N [ %s ] etype=%d class=%d\n",
|
//print("callinstr for %N [ %s ] etype=%d class=%d\n",
|
||||||
// n, opnames[n->op], n->type ? n->type->etype : -1, n->class);
|
// n, opnames[n->op], n->type ? n->type->etype : -1, n->class);
|
||||||
|
|
||||||
if(skip || n->type == T || n->type->etype >= TIDEAL)
|
if(skip || n->type == T || n->type->etype >= TIDEAL)
|
||||||
return;
|
return 0;
|
||||||
t = n->type;
|
t = n->type;
|
||||||
if(n->op == ONAME) {
|
if(n->op == ONAME) {
|
||||||
if(n->sym != S) {
|
if(n->sym != S) {
|
||||||
if(n->sym->name != nil) {
|
if(n->sym->name != nil) {
|
||||||
if(strncmp(n->sym->name, "_", sizeof("_")-1) == 0)
|
if(strncmp(n->sym->name, "_", sizeof("_")-1) == 0)
|
||||||
return;
|
return 0;
|
||||||
if(strncmp(n->sym->name, "autotmp_", sizeof("autotmp_")-1) == 0)
|
if(strncmp(n->sym->name, "autotmp_", sizeof("autotmp_")-1) == 0)
|
||||||
return;
|
return 0;
|
||||||
if(strncmp(n->sym->name, "statictmp_", sizeof("statictmp_")-1) == 0)
|
if(strncmp(n->sym->name, "statictmp_", sizeof("statictmp_")-1) == 0)
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (t->etype == TSTRUCT) {
|
if(t->etype == TSTRUCT) {
|
||||||
|
res = 0;
|
||||||
for(t1=t->type; t1; t1=t1->down) {
|
for(t1=t->type; t1; t1=t1->down) {
|
||||||
if(t1->sym && strncmp(t1->sym->name, "_", sizeof("_")-1)) {
|
if(t1->sym && strncmp(t1->sym->name, "_", sizeof("_")-1)) {
|
||||||
n = treecopy(n);
|
n = treecopy(n);
|
||||||
f = nod(OXDOT, n, newname(t1->sym));
|
f = nod(OXDOT, n, newname(t1->sym));
|
||||||
typecheck(&f, Erv);
|
if(callinstr(f, init, wr, 0)) {
|
||||||
callinstr(f, init, wr, 0);
|
typecheck(&f, Erv);
|
||||||
|
res = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
b = basenod(n);
|
b = basenod(n);
|
||||||
@ -399,7 +405,9 @@ callinstr(Node *n, NodeList **init, int wr, int skip)
|
|||||||
f = mkcall(wr ? "racewrite" : "raceread", T, nil, uintptraddr(n));
|
f = mkcall(wr ? "racewrite" : "raceread", T, nil, uintptraddr(n));
|
||||||
//typecheck(&f, Etop);
|
//typecheck(&f, Etop);
|
||||||
*init = list(*init, f);
|
*init = list(*init, f);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node*
|
static Node*
|
||||||
|
Loading…
Reference in New Issue
Block a user