mirror of
https://github.com/golang/go.git
synced 2026-04-02 01:10:27 +09:00
cmd/compile: pointer-shaped types are SSAable even if lots of 0-sized fields
Normally we don't SSA-ify variables with types that have more than 4 fields. But we really do want to SSA-ify them if they are pointer shaped. An odd case, but the compiler shouldn't barf on them. Failure probably started with CL 714421. Fixes #77534 Change-Id: I51ef87676cc31df1e51e164bbd58d58c0ab72436 Reviewed-on: https://go-review.googlesource.com/c/go/+/744280 Reviewed-by: Junyang Shao <shaojunyang@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
@@ -363,9 +363,9 @@ func decomposeUserPhi(v *Value) {
|
||||
func decomposeStructPhi(v *Value) {
|
||||
t := v.Type
|
||||
n := t.NumFields()
|
||||
var fields [MaxStruct]*Value
|
||||
fields := make([]*Value, 0, MaxStruct)
|
||||
for i := 0; i < n; i++ {
|
||||
fields[i] = v.Block.NewValue0(v.Pos, OpPhi, t.FieldType(i))
|
||||
fields = append(fields, v.Block.NewValue0(v.Pos, OpPhi, t.FieldType(i)))
|
||||
}
|
||||
for _, a := range v.Args {
|
||||
for i := 0; i < n; i++ {
|
||||
@@ -373,10 +373,10 @@ func decomposeStructPhi(v *Value) {
|
||||
}
|
||||
}
|
||||
v.reset(OpStructMake)
|
||||
v.AddArgs(fields[:n]...)
|
||||
v.AddArgs(fields...)
|
||||
|
||||
// Recursively decompose phis for each field.
|
||||
for _, f := range fields[:n] {
|
||||
for _, f := range fields {
|
||||
decomposeUserPhi(f)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,7 +566,7 @@ func (x *expandState) rewriteSelectOrArg(pos src.XPos, b *Block, container, a, m
|
||||
addArg(e)
|
||||
pos = pos.WithNotStmt()
|
||||
}
|
||||
if at.NumFields() > 4 {
|
||||
if at.NumFields() > MaxStruct && !types.IsDirectIface(at) {
|
||||
panic(fmt.Errorf("Too many fields (%d, %d bytes), container=%s", at.NumFields(), at.Size(), container.LongString()))
|
||||
}
|
||||
a = makeOf(a, OpStructMake, args)
|
||||
|
||||
@@ -635,6 +635,10 @@ func CanSSA(t *types.Type) bool {
|
||||
}
|
||||
return false
|
||||
case types.TSTRUCT:
|
||||
if types.IsDirectIface(t) {
|
||||
// Note: even if t.NumFields()>MaxStruct! See issue 77534.
|
||||
return true
|
||||
}
|
||||
if t.NumFields() > MaxStruct {
|
||||
return false
|
||||
}
|
||||
|
||||
36
test/fixedbugs/issue77534.go
Normal file
36
test/fixedbugs/issue77534.go
Normal file
@@ -0,0 +1,36 @@
|
||||
// compile
|
||||
|
||||
// Copyright 2026 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.
|
||||
|
||||
// Issue 77534: compiler crash when >4 fields, but only one nonempty pointer field.
|
||||
|
||||
package p
|
||||
|
||||
type T struct {
|
||||
a, b, c, d struct{}
|
||||
e *byte
|
||||
}
|
||||
|
||||
func f1(p *any, t T) {
|
||||
*p = t
|
||||
}
|
||||
|
||||
func f2(p *any, t *T) {
|
||||
*p = *t
|
||||
}
|
||||
|
||||
func f3(p, x, y *T, b bool) {
|
||||
var z T
|
||||
if b {
|
||||
z = *x
|
||||
} else {
|
||||
z = *y
|
||||
}
|
||||
*p = z
|
||||
}
|
||||
|
||||
func f4(i any) T {
|
||||
return i.(T)
|
||||
}
|
||||
Reference in New Issue
Block a user