Commit 21b2ce72 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

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
parent 27e93fbd
...@@ -17,12 +17,12 @@ ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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) ...@@ -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*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment