]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: allow StructSelect [x] of interface data fields for x>0
authorKeith Randall <khr@golang.org>
Tue, 5 Aug 2025 20:37:21 +0000 (13:37 -0700)
committerKeith Randall <khr@golang.org>
Tue, 5 Aug 2025 21:30:13 +0000 (14:30 -0700)
As of CL 681937 we can now have structs which are pointer shaped, but
their pointer field is not the first field, like struct{ struct{}; *int }.

Fixes #74888

Change-Id: Idc80f6b1abde3ae01437e2a9cadb5aa23d04b806
Reviewed-on: https://go-review.googlesource.com/c/go/+/693415
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/ssa/_gen/dec.rules
src/cmd/compile/internal/ssa/rewritedec.go
test/fixedbugs/issue74888.go [new file with mode: 0644]

index 5309a7f6b49f1edc9c9ccdcc5736f08ba6395b78..d3052b2a5b554867610dce5fdb3ead62a7eb4152 100644 (file)
@@ -98,7 +98,7 @@
 // Some of these are copied from generic.rules
 
 (IMake _typ (StructMake val)) => (IMake _typ val)
-(StructSelect [0] (IData x)) => (IData x)
+(StructSelect (IData x)) => (IData x)
 
 (StructSelect [i] x:(StructMake ___)) => x.Args[i]
 
 // More annoying case: (ArraySelect[0] (StructSelect[0] isAPtr))
 // There, result of the StructSelect is an Array (not a pointer) and
 // the pre-rewrite input to the ArraySelect is a struct, not a pointer.
-(StructSelect [0] x) && x.Type.IsPtrShaped()  => x
+(StructSelect    x) && x.Type.IsPtrShaped()  => x
 (ArraySelect [0] x) && x.Type.IsPtrShaped()  => x
 
 // These, too.  Bits is bits.
index 16d02692105b55a8620b495d869a3bc56e42fa60..bdbda1aaa8e897e64cae3c13becb62284b3d3646 100644 (file)
@@ -839,10 +839,10 @@ func rewriteValuedec_OpStructMake(v *Value) bool {
 func rewriteValuedec_OpStructSelect(v *Value) bool {
        v_0 := v.Args[0]
        b := v.Block
-       // match: (StructSelect [0] (IData x))
+       // match: (StructSelect (IData x))
        // result: (IData x)
        for {
-               if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpIData {
+               if v_0.Op != OpIData {
                        break
                }
                x := v_0.Args[0]
@@ -861,13 +861,10 @@ func rewriteValuedec_OpStructSelect(v *Value) bool {
                v.copyOf(x.Args[i])
                return true
        }
-       // match: (StructSelect [0] x)
+       // match: (StructSelect x)
        // cond: x.Type.IsPtrShaped()
        // result: x
        for {
-               if auxIntToInt64(v.AuxInt) != 0 {
-                       break
-               }
                x := v_0
                if !(x.Type.IsPtrShaped()) {
                        break
diff --git a/test/fixedbugs/issue74888.go b/test/fixedbugs/issue74888.go
new file mode 100644 (file)
index 0000000..a0083ad
--- /dev/null
@@ -0,0 +1,20 @@
+// compile
+
+// Copyright 2025 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
+
+type P struct {
+       q struct{}
+       p *int
+}
+
+func f(x any) {
+       h(x.(P))
+}
+
+//go:noinline
+func h(P) {
+}