mirror of
https://github.com/golang/go.git
synced 2026-06-26 10:50:23 +00:00
cmd/compile: compute embedded field offset in static initialization
Currently, when static initializes a variable with a struct literal, the compiler uses the field's offset in its containing struct. This is usually correct, except that with the newly- allowed direct access of embedded field, the offset does not include the offset of the embedded type in its containing type. We need to include all the implicit field offsets in the offset calculation. For #9859. Change-Id: Ifa4fae77383d912fba2638538248b06a3c286373 Reviewed-on: https://go-review.googlesource.com/c/go/+/780220 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Robert Griesemer <gri@google.com>
This commit is contained in:
parent
dd1da37fa4
commit
e2c188568d
3 changed files with 23 additions and 1 deletions
|
|
@ -546,7 +546,7 @@ func (s *Schedule) initplan(n ir.Node) {
|
|||
if a.Sym().IsBlank() {
|
||||
continue
|
||||
}
|
||||
s.addvalue(p, a.Field.Offset, a.Value)
|
||||
s.addvalue(p, typecheck.FieldOffset(n.Type(), a.Field), a.Value)
|
||||
}
|
||||
|
||||
case ir.OMAPLIT:
|
||||
|
|
|
|||
|
|
@ -790,3 +790,21 @@ var slist []symlink
|
|||
type symlink struct {
|
||||
field *types.Field
|
||||
}
|
||||
|
||||
// FieldOffset returns the offset of field f in t,
|
||||
// including any implicit offsets from embedded fields.
|
||||
func FieldOffset(t *types.Type, f *types.Field) int64 {
|
||||
if f.Sym == nil {
|
||||
return f.Offset
|
||||
}
|
||||
path, ambig := dotpath(f.Sym, t, nil, false)
|
||||
if path == nil || ambig {
|
||||
return f.Offset
|
||||
}
|
||||
var offset int64
|
||||
for _, d := range path {
|
||||
offset += d.field.Offset
|
||||
}
|
||||
offset += f.Offset
|
||||
return offset
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ type C struct {
|
|||
func main() {
|
||||
eq(A{1, B{b: "foo"}}, A{a: 1, b: "foo"})
|
||||
eq(A{B: B{C: C{c: "foo"}}}, A{c: "foo"})
|
||||
eq(x, A{B: B{b: "foo"}})
|
||||
}
|
||||
|
||||
func eq(x, y any) {
|
||||
|
|
@ -35,3 +36,6 @@ func eq(x, y any) {
|
|||
panic(fmt.Sprintf("%v != %v", x, y))
|
||||
}
|
||||
}
|
||||
|
||||
// test global initializer
|
||||
var x = A{b: "foo"}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue