From: Russ Cox Date: Tue, 14 Jan 2014 15:43:13 +0000 (-0500) Subject: cmd/gc: return canonical Node* from temp X-Git-Tag: go1.3beta1~980 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=334056a7bc68d3adef884bf1348b9227a98ab663;p=gostls13.git cmd/gc: return canonical Node* from temp For historical reasons, temp was returning a copy of the created Node*, not the original Node*. This meant that if analysis recorded information in the returned node (for example, n->addrtaken = 1), the analysis would not show up on the original Node*, the one kept in fn->dcl and consulted during liveness bitmap creation. Correct this, and watch for it when setting addrtaken. Fixes #7083. R=khr, dave, minux.ma CC=golang-codereviews https://golang.org/cl/51010045 --- diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c index 49b3f7a999..21a1849444 100644 --- a/src/cmd/gc/gen.c +++ b/src/cmd/gc/gen.c @@ -939,5 +939,5 @@ temp(Type *t) n = nod(OXXX, N, N); tempname(n, t); n->sym->def->used = 1; - return n; + return n->orig; } diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c index 59c5097e04..ece0b8fdfa 100644 --- a/src/cmd/gc/sinit.c +++ b/src/cmd/gc/sinit.c @@ -468,6 +468,7 @@ staticassign(Node *l, Node *r, NodeList **out) else { a = nod(OXXX, N, N); *a = n1; + a->orig = a; // completely separate copy if(!staticassign(a, e->expr, out)) *out = list(*out, nod(OAS, a, e->expr)); } diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 4d0a636bb9..68d2c3404d 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -723,6 +723,8 @@ reswitch: checklvalue(n->left, "take the address of"); for(l=n->left; l->op == ODOT; l=l->left) l->addrtaken = 1; + if(l->orig != l && l->op == ONAME) + fatal("found non-orig name node %N", l); l->addrtaken = 1; defaultlit(&n->left, T); l = n->left; diff --git a/test/fixedbugs/issue7083.go b/test/fixedbugs/issue7083.go new file mode 100644 index 0000000000..79bfd3b5ef --- /dev/null +++ b/test/fixedbugs/issue7083.go @@ -0,0 +1,22 @@ +// run + +package main + +import "runtime/debug" + +func f(m map[int]*string, i int) { + s := "" + m[i] = &s +} + +func main() { + debug.SetGCPercent(0) + m := map[int]*string{} + for i := 0; i < 40; i++ { + f(m, i) + if len(*m[i]) != 0 { + println("bad length", i, m[i], len(*m[i])) + panic("bad length") + } + } +}