mirror of
https://github.com/golang/go
synced 2024-11-02 11:50:30 +00:00
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:
parent
9fe60801ae
commit
9e66ee4562
5 changed files with 62 additions and 4 deletions
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
33
test/fixedbugs/issue4879.dir/a.go
Normal file
33
test/fixedbugs/issue4879.dir/a.go
Normal 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{}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
9
test/fixedbugs/issue4879.dir/b.go
Normal file
9
test/fixedbugs/issue4879.dir/b.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package b
|
||||||
|
|
||||||
|
import "./a"
|
||||||
|
|
||||||
|
func F() {
|
||||||
|
a.MakePrivateCollection()
|
||||||
|
a.MakePrivateCollection2()
|
||||||
|
a.MakePrivateCollection3()
|
||||||
|
}
|
10
test/fixedbugs/issue4879.go
Normal file
10
test/fixedbugs/issue4879.go
Normal 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
|
Loading…
Reference in a new issue