cmd/compile: ensure StructMake/ArrayMake1 of direct interfaces are unwrapped

Ensures that deeply nested structs that have the underlying shape
of a pointer get unwrapped properly.

Update #77534

Change-Id: I004f424d2c62ec7026281daded9b3d96c021e2e1
Reviewed-on: https://go-review.googlesource.com/c/go/+/747760
Reviewed-by: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Keith Randall
2026-02-10 17:44:08 -08:00
committed by David Chase
parent 78da9242cd
commit 1aa534dbb8
3 changed files with 26 additions and 1 deletions

View File

@@ -80,7 +80,9 @@
// interface ops
(ITab (IMake itab _)) => itab
(IData (IMake _ data)) => data
(IData (IMake _ data)) && data.Op != OpStructMake && data.Op != OpArrayMake1 => data
// Note: the conditional on data.Op ensures that StructMake/ArrayMake1 ops are
// unwrapped before the IMake is thrown away. See issue 77534.
(Load <t> ptr mem) && t.IsInterface() =>
(IMake

View File

@@ -242,12 +242,16 @@ func rewriteValuedec_OpIData(v *Value) bool {
config := b.Func.Config
typ := &b.Func.Config.Types
// match: (IData (IMake _ data))
// cond: data.Op != OpStructMake && data.Op != OpArrayMake1
// result: data
for {
if v_0.Op != OpIMake {
break
}
data := v_0.Args[1]
if !(data.Op != OpStructMake && data.Op != OpArrayMake1) {
break
}
v.copyOf(data)
return true
}

View File

@@ -34,3 +34,22 @@ func f3(p, x, y *T, b bool) {
func f4(i any) T {
return i.(T)
}
type Inner struct {
a struct{}
p *byte
}
type Outer struct {
inner Inner
}
func f5(o1, o2 Outer, c bool) Outer {
var i any
if c {
i = o1
} else {
i = o2
}
return i.(Outer)
}