diff options
| -rw-r--r-- | src/cmd/compile/internal/ssa/decompose.go | 8 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/expand_calls.go | 2 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ssa/value.go | 4 | ||||
| -rw-r--r-- | test/fixedbugs/issue77534.go | 36 |
4 files changed, 45 insertions, 5 deletions
diff --git a/src/cmd/compile/internal/ssa/decompose.go b/src/cmd/compile/internal/ssa/decompose.go index d2f715a453..a3d0fbd406 100644 --- a/src/cmd/compile/internal/ssa/decompose.go +++ b/src/cmd/compile/internal/ssa/decompose.go @@ -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) } } diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go index 1a2985d5af..ba2bedc65f 100644 --- a/src/cmd/compile/internal/ssa/expand_calls.go +++ b/src/cmd/compile/internal/ssa/expand_calls.go @@ -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) diff --git a/src/cmd/compile/internal/ssa/value.go b/src/cmd/compile/internal/ssa/value.go index 5f60409901..dba73de771 100644 --- a/src/cmd/compile/internal/ssa/value.go +++ b/src/cmd/compile/internal/ssa/value.go @@ -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 } diff --git a/test/fixedbugs/issue77534.go b/test/fixedbugs/issue77534.go new file mode 100644 index 0000000000..ab4f922308 --- /dev/null +++ b/test/fixedbugs/issue77534.go @@ -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) +} |
