mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
cmd/compile: qualify unexported fields of unnamed types
The compiler was canonicalizing unnamed types of the form struct { i int } across packages, even though an unexported field i should not be accessible from other packages. The fix requires both qualifying the field name in the string used by the compiler to distinguish the type, and ensuring the struct's pkgpath is set in the rtype version of the data when the type being written is not part of the localpkg. Fixes #16616 Change-Id: Ibab160b8b5936dfa47b17dbfd48964a65586785b Reviewed-on: https://go-review.googlesource.com/27791 Run-TryBot: David Crawshaw <crawshaw@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
3e59b20d41
commit
14efaa0dc3
|
@ -1574,7 +1574,10 @@ func Fldconv(f *Field, flag FmtFlag) string {
|
||||||
if f.Funarg != FunargNone {
|
if f.Funarg != FunargNone {
|
||||||
name = Nconv(f.Nname, 0)
|
name = Nconv(f.Nname, 0)
|
||||||
} else if flag&FmtLong != 0 {
|
} else if flag&FmtLong != 0 {
|
||||||
name = sconv(s, FmtShort|FmtByte) // qualify non-exported names (used on structs, not on funarg)
|
name = sconv(s, FmtShort|FmtByte)
|
||||||
|
if !exportname(name) && flag&FmtUnsigned == 0 {
|
||||||
|
name = sconv(s, 0) // qualify non-exported names (used on structs, not on funarg)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
name = sconv(s, 0)
|
name = sconv(s, 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1301,6 +1301,15 @@ ok:
|
||||||
pkg := localpkg
|
pkg := localpkg
|
||||||
if t.Sym != nil {
|
if t.Sym != nil {
|
||||||
pkg = t.Sym.Pkg
|
pkg = t.Sym.Pkg
|
||||||
|
} else {
|
||||||
|
// Unnamed type. Grab the package from the first field, if any.
|
||||||
|
for _, f := range t.Fields().Slice() {
|
||||||
|
if f.Embedded != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pkg = f.Sym.Pkg
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ot = dgopkgpath(s, ot, pkg)
|
ot = dgopkgpath(s, ot, pkg)
|
||||||
ot = dsymptr(s, ot, s, ot+Widthptr+2*Widthint+uncommonSize(t))
|
ot = dsymptr(s, ot, s, ot+Widthptr+2*Widthint+uncommonSize(t))
|
||||||
|
|
7
test/fixedbugs/issue16616.dir/a.go
Normal file
7
test/fixedbugs/issue16616.dir/a.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Copyright 2016 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.
|
||||||
|
|
||||||
|
package a
|
||||||
|
|
||||||
|
type V struct{ i int }
|
14
test/fixedbugs/issue16616.dir/b.go
Normal file
14
test/fixedbugs/issue16616.dir/b.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2016 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.
|
||||||
|
|
||||||
|
package b
|
||||||
|
|
||||||
|
import "./a"
|
||||||
|
|
||||||
|
var V struct{ i int }
|
||||||
|
|
||||||
|
var U struct {
|
||||||
|
a.V
|
||||||
|
j int
|
||||||
|
}
|
26
test/fixedbugs/issue16616.dir/issue16616.go
Normal file
26
test/fixedbugs/issue16616.dir/issue16616.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2016 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.
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
_ "./a"
|
||||||
|
"./b"
|
||||||
|
)
|
||||||
|
|
||||||
|
var V struct{ i int }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if got := reflect.ValueOf(b.V).Type().Field(0).PkgPath; got != "b" {
|
||||||
|
panic(`PkgPath=` + got + ` for first field of b.V, want "b"`)
|
||||||
|
}
|
||||||
|
if got := reflect.ValueOf(V).Type().Field(0).PkgPath; got != "main" {
|
||||||
|
panic(`PkgPath=` + got + ` for first field of V, want "main"`)
|
||||||
|
}
|
||||||
|
if got := reflect.ValueOf(b.U).Type().Field(0).PkgPath; got != "b" {
|
||||||
|
panic(`PkgPath=` + got + ` for first field of b.U, want "b"`)
|
||||||
|
}
|
||||||
|
}
|
9
test/fixedbugs/issue16616.go
Normal file
9
test/fixedbugs/issue16616.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// compiledir
|
||||||
|
|
||||||
|
// Copyright 2016 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.
|
||||||
|
|
||||||
|
// Tests that unexported fields of unnamed types have different PkgPath values.
|
||||||
|
|
||||||
|
package ignored
|
Loading…
Reference in a new issue