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 #4879.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/7395054
This commit is contained in:
Rémy Oudompheng 2013-02-26 00:43:31 +01:00
parent 9fe60801ae
commit 9e66ee4562
5 changed files with 62 additions and 4 deletions

View file

@ -1206,7 +1206,7 @@ exprfmt(Fmt *f, Node *n, int prec)
return fmtprint(f, "(%N{ %,H })", n->right, n->list); return fmtprint(f, "(%N{ %,H })", n->right, n->list);
case OPTRLIT: 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);
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(fmtmode == FExp) { // requires special handling of field names
if(n->implicit) if(n->implicit)
fmtstrcpy(f, "{"); fmtstrcpy(f, "{");
else if(n->right->implicit)
fmtprint(f, "&%T{", n->type);
else else
fmtprint(f, "(%T{", n->type); fmtprint(f, "(%T{", n->type);
for(l=n->list; l; l=l->next) { for(l=n->list; l; l=l->next) {
@ -1224,7 +1226,7 @@ exprfmt(Fmt *f, Node *n, int prec)
else else
fmtstrcpy(f, " "); fmtstrcpy(f, " ");
} }
if(!n->implicit) if(!n->implicit && !n->right->implicit)
return fmtstrcpy(f, "})"); return fmtstrcpy(f, "})");
return fmtstrcpy(f, "}"); return fmtstrcpy(f, "}");
} }
@ -1236,6 +1238,8 @@ exprfmt(Fmt *f, Node *n, int prec)
return fmtprint(f, "%T literal", n->type); return fmtprint(f, "%T literal", n->type);
if(fmtmode == FExp && n->implicit) if(fmtmode == FExp && n->implicit)
return fmtprint(f, "{ %,H }", n->list); 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); return fmtprint(f, "(%T{ %,H })", n->type, n->list);
case OKEY: case OKEY:

View file

@ -2354,13 +2354,12 @@ typecheckcomplit(Node **np)
yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type); yyerror("invalid pointer type %T for composite literal (use &%T instead)", t, t->type);
goto error; goto error;
} }
// Also, the underlying type must be a struct, map, slice, or array. // Also, the underlying type must be a struct, map, slice, or array.
if(!iscomptype(t)) { if(!iscomptype(t)) {
yyerror("invalid pointer type %T for composite literal", t); yyerror("invalid pointer type %T for composite literal", t);
goto error; goto error;
} }
t = t->type; t = t->type;
} }
switch(t->etype) { switch(t->etype) {
@ -2414,6 +2413,9 @@ typecheckcomplit(Node **np)
if(t->bound < 0) if(t->bound < 0)
n->right = nodintconst(len); n->right = nodintconst(len);
n->op = OARRAYLIT; n->op = OARRAYLIT;
// restore implicitness.
if(isptr[n->type->etype])
n->right->implicit = 1;
break; break;
case TMAP: case TMAP:

View file

@ -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{}),
}
}

View file

@ -0,0 +1,9 @@
package b
import "./a"
func F() {
a.MakePrivateCollection()
a.MakePrivateCollection2()
a.MakePrivateCollection3()
}

View file

@ -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