]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: fix corruption in export of &T{} literals.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 25 Feb 2013 23:43:31 +0000 (00:43 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 25 Feb 2013 23:43:31 +0000 (00:43 +0100)
Composite literals using the &T{} form were incorrectly
exported, leading to weird errors at import time.

Fixes #4879.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7395054

src/cmd/gc/fmt.c
src/cmd/gc/typecheck.c
test/fixedbugs/issue4879.dir/a.go [new file with mode: 0644]
test/fixedbugs/issue4879.dir/b.go [new file with mode: 0644]
test/fixedbugs/issue4879.go [new file with mode: 0644]

index 5d37ac0fd5232ea54ba24763ecfda408f838993b..64eb196928bcd2e38a7c254aefcbb3573463717f 100644 (file)
@@ -1206,7 +1206,7 @@ exprfmt(Fmt *f, Node *n, int prec)
                return fmtprint(f, "(%N{ %,H })", n->right, n->list);
 
        case OPTRLIT:
-               if(fmtmode == FExp && n->left->implicit)
+               if(fmtmode == FExp)  // handle printing of '&' below.
                        return fmtprint(f, "%N", n->left);
                return fmtprint(f, "&%N", n->left);
 
@@ -1214,6 +1214,8 @@ exprfmt(Fmt *f, Node *n, int prec)
                if(fmtmode == FExp) {   // requires special handling of field names
                        if(n->implicit)
                                fmtstrcpy(f, "{");
+                       else if(n->right->implicit)
+                               fmtprint(f, "&%T{", n->type);
                        else
                                fmtprint(f, "(%T{", n->type);
                        for(l=n->list; l; l=l->next) {
@@ -1224,7 +1226,7 @@ exprfmt(Fmt *f, Node *n, int prec)
                                else
                                        fmtstrcpy(f, " ");
                        }
-                       if(!n->implicit)
+                       if(!n->implicit && !n->right->implicit)
                                return fmtstrcpy(f, "})");
                        return fmtstrcpy(f, "}");
                }
@@ -1236,6 +1238,8 @@ exprfmt(Fmt *f, Node *n, int prec)
                        return fmtprint(f, "%T literal", n->type);
                if(fmtmode == FExp && n->implicit)
                        return fmtprint(f, "{ %,H }", n->list);
+               if(fmtmode == FExp && n->right->implicit)
+                       return fmtprint(f, "&%T{ %,H }", n->type, n->list);
                return fmtprint(f, "(%T{ %,H })", n->type, n->list);
 
        case OKEY:
index ac90baafd2979080a65874a1f4e1787fe9d7d968..63ad4a92eb25115d6a0c08ea849744c59adf9c7e 100644 (file)
@@ -2354,13 +2354,12 @@ typecheckcomplit(Node **np)
                        yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type);
                        goto error;
                }
-               
                // Also, the underlying type must be a struct, map, slice, or array.
                if(!iscomptype(t)) {
                        yyerror("invalid pointer type %T for composite literal", t);
                        goto error;
                }
-               t = t->type;            
+               t = t->type;
        }
 
        switch(t->etype) {
@@ -2414,6 +2413,9 @@ typecheckcomplit(Node **np)
                if(t->bound < 0)
                        n->right = nodintconst(len);
                n->op = OARRAYLIT;
+               // restore implicitness.
+               if(isptr[n->type->etype])
+                       n->right->implicit = 1;
                break;
 
        case TMAP:
diff --git a/test/fixedbugs/issue4879.dir/a.go b/test/fixedbugs/issue4879.dir/a.go
new file mode 100644 (file)
index 0000000..7ee7c48
--- /dev/null
@@ -0,0 +1,33 @@
+package a
+
+import (
+       "unsafe"
+)
+
+type Collection struct {
+       root unsafe.Pointer
+}
+
+type nodeLoc struct{}
+
+type slice []int
+
+type maptype map[int]int
+
+func MakePrivateCollection() *Collection {
+       return &Collection{
+               root: unsafe.Pointer(&nodeLoc{}),
+       }
+}
+
+func MakePrivateCollection2() *Collection {
+       return &Collection{
+               root: unsafe.Pointer(&slice{}),
+       }
+}
+func MakePrivateCollection3() *Collection {
+       return &Collection{
+               root: unsafe.Pointer(&maptype{}),
+       }
+}
+
diff --git a/test/fixedbugs/issue4879.dir/b.go b/test/fixedbugs/issue4879.dir/b.go
new file mode 100644 (file)
index 0000000..d8fb569
--- /dev/null
@@ -0,0 +1,9 @@
+package b
+
+import "./a"
+
+func F() {
+      a.MakePrivateCollection()
+      a.MakePrivateCollection2()
+      a.MakePrivateCollection3()
+}
diff --git a/test/fixedbugs/issue4879.go b/test/fixedbugs/issue4879.go
new file mode 100644 (file)
index 0000000..842c811
--- /dev/null
@@ -0,0 +1,10 @@
+// compiledir
+
+// Copyright 2013 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.
+
+// Issue 4879: export data misses the '&' for some
+// composite literals in inlined bodies.
+
+package ignored