aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-01-03 14:37:06 -0800
committerMatthew Dempsky <mdempsky@google.com>2021-01-04 10:30:08 +0000
commitd89705e08742c0f4fdf5d2bdbab6f344c6be884f (patch)
tree1f9dc4336efac6988c5132bf3b101f046d6aa549 /src
parent290b4154b73b54045a147f463c6988b935d75d49 (diff)
downloadgo-d89705e08742c0f4fdf5d2bdbab6f344c6be884f.tar.gz
go-d89705e08742c0f4fdf5d2bdbab6f344c6be884f.zip
[dev.regabi] cmd/compile: fix re-export of parameters
When exporting signature types, we include the originating package, because it's exposed via go/types's API. And as a consistency check, we ensure that the parameter names came from that same package. However, we were getting this wrong in the case of exported variables that were initialized with a method value using an imported method. In this case, when we created the method value wrapper function's type (which is reused as the variable's type if none is explicitly provided in the variable declaration), we were reusing the original (i.e., imported) parameter names, but the newly created signature type was associated with the current package instead. The correct fix here is really to preserve the original signature type's package (along with position and name for its parameters), but that's awkward to do at the moment because the DeclFunc API requires an ir representation of the function signature, whereas we only provide a way to explicitly set packages via the type constructor APIs. As an interim fix, we associate the parameters with the current package, to be consistent with the signature type's package. Fixes #43479. Change-Id: Id45a10f8cf64165c9bc7d9598f0a0ee199a5e752 Reviewed-on: https://go-review.googlesource.com/c/go/+/281292 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/typecheck/dcl.go3
-rw-r--r--src/cmd/compile/internal/typecheck/iexport.go13
-rw-r--r--src/cmd/compile/internal/typecheck/iimport.go27
-rw-r--r--src/cmd/compile/internal/typecheck/subr.go3
4 files changed, 32 insertions, 14 deletions
diff --git a/src/cmd/compile/internal/typecheck/dcl.go b/src/cmd/compile/internal/typecheck/dcl.go
index daec9848d0..5eaf100eed 100644
--- a/src/cmd/compile/internal/typecheck/dcl.go
+++ b/src/cmd/compile/internal/typecheck/dcl.go
@@ -486,6 +486,9 @@ func NewMethodType(sig *types.Type, recv *types.Type) *types.Type {
nrecvs++
}
+ // TODO(mdempsky): Move this function to types.
+ // TODO(mdempsky): Preserve positions, names, and package from sig+recv.
+
params := make([]*types.Field, nrecvs+sig.Params().Fields().Len())
if recv != nil {
params[0] = types.NewField(base.Pos, nil, recv)
diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go
index 50acb10a9a..dd515b8ccd 100644
--- a/src/cmd/compile/internal/typecheck/iexport.go
+++ b/src/cmd/compile/internal/typecheck/iexport.go
@@ -574,6 +574,11 @@ func (w *exportWriter) pos(pos src.XPos) {
}
func (w *exportWriter) pkg(pkg *types.Pkg) {
+ // TODO(mdempsky): Add flag to types.Pkg to mark pseudo-packages.
+ if pkg == ir.Pkgs.Go {
+ base.Fatalf("export of pseudo-package: %q", pkg.Path)
+ }
+
// Ensure any referenced packages are declared in the main index.
w.p.allPkgs[pkg] = true
@@ -1529,6 +1534,10 @@ func (w *exportWriter) localName(n *ir.Name) {
}
func (w *exportWriter) localIdent(s *types.Sym, v int32) {
+ if w.currPkg == nil {
+ base.Fatalf("missing currPkg")
+ }
+
// Anonymous parameters.
if s == nil {
w.string("")
@@ -1553,8 +1562,8 @@ func (w *exportWriter) localIdent(s *types.Sym, v int32) {
name = fmt.Sprintf("%s·%d", name, v)
}
- if !types.IsExported(name) && s.Pkg != w.currPkg {
- base.Fatalf("weird package in name: %v => %v, not %q", s, name, w.currPkg.Path)
+ if s.Pkg != w.currPkg {
+ base.Fatalf("weird package in name: %v => %v from %q, not %q", s, name, s.Pkg.Path, w.currPkg.Path)
}
w.string(name)
diff --git a/src/cmd/compile/internal/typecheck/iimport.go b/src/cmd/compile/internal/typecheck/iimport.go
index 0caac362e3..2dc7e70b65 100644
--- a/src/cmd/compile/internal/typecheck/iimport.go
+++ b/src/cmd/compile/internal/typecheck/iimport.go
@@ -327,7 +327,7 @@ func (r *importReader) doDecl(sym *types.Sym) *ir.Name {
ms := make([]*types.Field, r.uint64())
for i := range ms {
mpos := r.pos()
- msym := r.ident()
+ msym := r.selector()
recv := r.param()
mtyp := r.signature(recv)
@@ -434,18 +434,21 @@ func (p *importReader) float(typ *types.Type) constant.Value {
return constant.Make(&f)
}
-func (r *importReader) ident() *types.Sym {
+func (r *importReader) ident(selector bool) *types.Sym {
name := r.string()
if name == "" {
return nil
}
pkg := r.currPkg
- if types.IsExported(name) {
+ if selector && types.IsExported(name) {
pkg = types.LocalPkg
}
return pkg.Lookup(name)
}
+func (r *importReader) localIdent() *types.Sym { return r.ident(false) }
+func (r *importReader) selector() *types.Sym { return r.ident(true) }
+
func (r *importReader) qualifiedIdent() *ir.Ident {
name := r.string()
pkg := r.pkg()
@@ -534,7 +537,7 @@ func (r *importReader) typ1() *types.Type {
fs := make([]*types.Field, r.uint64())
for i := range fs {
pos := r.pos()
- sym := r.ident()
+ sym := r.selector()
typ := r.typ()
emb := r.bool()
note := r.string()
@@ -563,7 +566,7 @@ func (r *importReader) typ1() *types.Type {
methods := make([]*types.Field, r.uint64())
for i := range methods {
pos := r.pos()
- sym := r.ident()
+ sym := r.selector()
typ := r.signature(fakeRecvField())
methods[i] = types.NewField(pos, sym, typ)
@@ -599,7 +602,7 @@ func (r *importReader) paramList() []*types.Field {
}
func (r *importReader) param() *types.Field {
- return types.NewField(r.pos(), r.ident(), r.typ())
+ return types.NewField(r.pos(), r.localIdent(), r.typ())
}
func (r *importReader) bool() bool {
@@ -784,7 +787,7 @@ func (r *importReader) caseList(switchExpr ir.Node) []*ir.CaseClause {
// Note: per-case variables will have distinct, dotted
// names after import. That's okay: swt.go only needs
// Sym for diagnostics anyway.
- caseVar := ir.NewNameAt(cas.Pos(), r.ident())
+ caseVar := ir.NewNameAt(cas.Pos(), r.localIdent())
Declare(caseVar, DeclContext)
cas.Var = caseVar
caseVar.Defn = switchExpr
@@ -851,7 +854,7 @@ func (r *importReader) node() ir.Node {
return r.qualifiedIdent()
case ir.ONAME:
- return r.ident().Def.(*ir.Name)
+ return r.localIdent().Def.(*ir.Name)
// case OPACK, ONONAME:
// unreachable - should have been resolved by typechecking
@@ -862,7 +865,7 @@ func (r *importReader) node() ir.Node {
case ir.OTYPESW:
pos := r.pos()
var tag *ir.Ident
- if s := r.ident(); s != nil {
+ if s := r.localIdent(); s != nil {
tag = ir.NewIdent(pos, s)
}
return ir.NewTypeSwitchGuard(pos, tag, r.expr())
@@ -899,7 +902,7 @@ func (r *importReader) node() ir.Node {
case ir.OXDOT:
// see parser.new_dotname
- return ir.NewSelectorExpr(r.pos(), ir.OXDOT, r.expr(), r.ident())
+ return ir.NewSelectorExpr(r.pos(), ir.OXDOT, r.expr(), r.selector())
// case ODOTTYPE, ODOTTYPE2:
// unreachable - mapped to case ODOTTYPE below by exporter
@@ -989,7 +992,7 @@ func (r *importReader) node() ir.Node {
// statements
case ir.ODCL:
pos := r.pos()
- lhs := ir.NewDeclNameAt(pos, ir.ONAME, r.ident())
+ lhs := ir.NewDeclNameAt(pos, ir.ONAME, r.localIdent())
lhs.SetType(r.typ())
Declare(lhs, ir.PAUTO)
@@ -1100,7 +1103,7 @@ func (r *importReader) op() ir.Op {
func (r *importReader) fieldList() []ir.Node {
list := make([]ir.Node, r.uint64())
for i := range list {
- list[i] = ir.NewStructKeyExpr(r.pos(), r.ident(), r.expr())
+ list[i] = ir.NewStructKeyExpr(r.pos(), r.selector(), r.expr())
}
return list
}
diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go
index 447e945d81..569075d684 100644
--- a/src/cmd/compile/internal/typecheck/subr.go
+++ b/src/cmd/compile/internal/typecheck/subr.go
@@ -43,6 +43,9 @@ func NewFuncParams(tl *types.Type, mustname bool) []*ir.Field {
// invent a name so that we can refer to it in the trampoline
s = LookupNum(".anon", gen)
gen++
+ } else if s != nil && s.Pkg != types.LocalPkg {
+ // TODO(mdempsky): Preserve original position, name, and package.
+ s = Lookup(s.Name)
}
a := ir.NewField(base.Pos, s, nil, t.Type)
a.Pos = t.Pos