summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorR?my Oudompheng <oudomphe@phare.normalesup.org>2013-02-26 00:43:31 +0100
committerR?my Oudompheng <oudomphe@phare.normalesup.org>2013-02-26 00:43:31 +0100
commitd3668771286a97e056f402c39a47f577810b9a6c (patch)
tree4116946bd284bb54d9b8a0f307c516b44019402f
parente655e97ad31ebb98f05cf12f7eccdfda9a0c438a (diff)
downloadgo-d3668771286a97e056f402c39a47f577810b9a6c.tar.gz
cmd/gc: fix corruption in export of &T{} literals.
Composite literals using the &T{} form were incorrectly exported, leading to weird errors at import time. Fixes issue 4879. R=golang-dev, rsc CC=golang-dev https://codereview.appspot.com/7395054
-rw-r--r--src/cmd/gc/fmt.c8
-rw-r--r--src/cmd/gc/typecheck.c6
-rw-r--r--test/fixedbugs/issue4879.dir/a.go33
-rw-r--r--test/fixedbugs/issue4879.dir/b.go9
-rw-r--r--test/fixedbugs/issue4879.go10
5 files changed, 62 insertions, 4 deletions
diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c
index 5d37ac0fd..64eb19692 100644
--- a/src/cmd/gc/fmt.c
+++ b/src/cmd/gc/fmt.c
@@ -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:
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index ac90baafd..63ad4a92e 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -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
index 000000000..7ee7c4860
--- /dev/null
+++ b/test/fixedbugs/issue4879.dir/a.go
@@ -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
index 000000000..d8fb5693d
--- /dev/null
+++ b/test/fixedbugs/issue4879.dir/b.go
@@ -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
index 000000000..842c8117f
--- /dev/null
+++ b/test/fixedbugs/issue4879.go
@@ -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