diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c index 5d37ac0fd5..64eb196928 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 ac90baafd2..63ad4a92eb 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 0000000000..7ee7c48604 --- /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 0000000000..d8fb5693db --- /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 0000000000..842c8117ff --- /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