]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: return canonical Node* from temp
authorRuss Cox <rsc@golang.org>
Tue, 14 Jan 2014 15:43:13 +0000 (10:43 -0500)
committerRuss Cox <rsc@golang.org>
Tue, 14 Jan 2014 15:43:13 +0000 (10:43 -0500)
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

src/cmd/gc/gen.c
src/cmd/gc/sinit.c
src/cmd/gc/typecheck.c
test/fixedbugs/issue7083.go [new file with mode: 0644]

index 49b3f7a9999f5dc1b24c6b0aa3e8fbe81cd952d4..21a184944457e75bbc4670f9a866b6144ca3b581 100644 (file)
@@ -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;
 }
index 59c5097e040221c0120e262404fdaf8c41bfa557..ece0b8fdfa5c9428b8647c71ee4d30410f801a89 100644 (file)
@@ -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));
                        }
index 4d0a636bb907e496f1de16cf639613d8497cf9f5..68d2c3404da5a368514dd8a74944946ce7ec092c 100644 (file)
@@ -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 (file)
index 0000000..79bfd3b
--- /dev/null
@@ -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")
+               }
+       }
+}