From: Keith Randall Date: Tue, 5 Aug 2025 20:37:21 +0000 (-0700) Subject: cmd/compile: allow StructSelect [x] of interface data fields for x>0 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=bcd25c79aa5675d3e5d28c09715b8147906da006;p=gostls13.git 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 Reviewed-by: David Chase LUCI-TryBot-Result: Go LUCI --- diff --git a/src/cmd/compile/internal/ssa/_gen/dec.rules b/src/cmd/compile/internal/ssa/_gen/dec.rules index 5309a7f6b4..d3052b2a5b 100644 --- a/src/cmd/compile/internal/ssa/_gen/dec.rules +++ b/src/cmd/compile/internal/ssa/_gen/dec.rules @@ -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. diff --git a/src/cmd/compile/internal/ssa/rewritedec.go b/src/cmd/compile/internal/ssa/rewritedec.go index 16d0269210..bdbda1aaa8 100644 --- a/src/cmd/compile/internal/ssa/rewritedec.go +++ b/src/cmd/compile/internal/ssa/rewritedec.go @@ -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 index 0000000000..a0083adb9c --- /dev/null +++ b/test/fixedbugs/issue74888.go @@ -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) { +}