]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.26] cmd/compile: ensure StructMake/ArrayMake1 of direct interface...
authorKeith Randall <khr@golang.org>
Wed, 11 Feb 2026 01:44:08 +0000 (17:44 -0800)
committerDavid Chase <drchase@google.com>
Thu, 26 Feb 2026 19:45:11 +0000 (11:45 -0800)
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 <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit 1aa534dbb8970b86b0f4059b7665e3505d145e25)
Reviewed-on: https://go-review.googlesource.com/c/go/+/749460

src/cmd/compile/internal/ssa/_gen/dec.rules
src/cmd/compile/internal/ssa/rewritedec.go
test/fixedbugs/issue77534.go

index fce00262114c21beba242648d5573a555d95442f..a04a7cd5f836e20a7a3556ba200d99cc58b7ca1a 100644 (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
index c45034ead02a4a2788b475259c9b4690722484ab..1e5c19cd23dc201347f49c01879a0bdce22e9b29 100644 (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
        }
index ab4f9223086d47ce6d0efa9ce8ef79843c8ec226..77a6e616e6e9309d2a4ddb9d55592960cd193093 100644 (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)
+}