cmd/compile: allow StructSelect [x] of interface data fields for x>0

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>
This commit is contained in:
Keith Randall
2025-08-05 13:37:21 -07:00
parent b0945a54b5
commit bcd25c79aa
3 changed files with 25 additions and 8 deletions

View 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]
@@ -109,7 +109,7 @@
// 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.

View 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

View File

@@ -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) {
}