From: Keith Randall Date: Wed, 11 Feb 2026 01:44:08 +0000 (-0800) Subject: [release-branch.go1.26] cmd/compile: ensure StructMake/ArrayMake1 of direct interface... X-Git-Tag: go1.26.1~8 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ef041913a827cbd63a23c5029b87991c6e49529e;p=gostls13.git [release-branch.go1.26] 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 #77536 Change-Id: I004f424d2c62ec7026281daded9b3d96c021e2e1 Reviewed-on: https://go-review.googlesource.com/c/go/+/747760 Reviewed-by: Mark Freeman LUCI-TryBot-Result: Go LUCI Reviewed-by: David Chase (cherry picked from commit 1aa534dbb8970b86b0f4059b7665e3505d145e25) Reviewed-on: https://go-review.googlesource.com/c/go/+/749460 --- diff --git a/src/cmd/compile/internal/ssa/_gen/dec.rules b/src/cmd/compile/internal/ssa/_gen/dec.rules index fce0026211..a04a7cd5f8 100644 --- a/src/cmd/compile/internal/ssa/_gen/dec.rules +++ b/src/cmd/compile/internal/ssa/_gen/dec.rules @@ -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 ptr mem) && t.IsInterface() => (IMake diff --git a/src/cmd/compile/internal/ssa/rewritedec.go b/src/cmd/compile/internal/ssa/rewritedec.go index c45034ead0..1e5c19cd23 100644 --- a/src/cmd/compile/internal/ssa/rewritedec.go +++ b/src/cmd/compile/internal/ssa/rewritedec.go @@ -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 } diff --git a/test/fixedbugs/issue77534.go b/test/fixedbugs/issue77534.go index ab4f922308..77a6e616e6 100644 --- a/test/fixedbugs/issue77534.go +++ b/test/fixedbugs/issue77534.go @@ -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) +}