mirror of
https://github.com/golang/go.git
synced 2026-04-02 09:20:29 +09:00
cmd/compile: treat all zero-sized values as SSA-able
Might as well, we don't need any registers for such values. Fixes #77635 Change-Id: Iedc1bc3f13662b043b183228bcc1dc4e6c91da81 Reviewed-on: https://go-review.googlesource.com/c/go/+/747780 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:
committed by
Keith Randall
parent
b48b2002fe
commit
0886e65b11
@@ -616,6 +616,9 @@ func CanSSA(t *types.Type) bool {
|
||||
if t.IsSIMD() {
|
||||
return true
|
||||
}
|
||||
if t.Size() == 0 {
|
||||
return true
|
||||
}
|
||||
sizeLimit := int64(MaxStruct * types.PtrSize)
|
||||
if t.Size() > sizeLimit {
|
||||
// 4*Widthptr is an arbitrary constant. We want it
|
||||
|
||||
@@ -4529,7 +4529,15 @@ func (s *state) assignWhichMayOverlap(left ir.Node, right *ssa.Value, deref bool
|
||||
return
|
||||
}
|
||||
if n != 1 {
|
||||
s.Fatalf("assigning to non-1-length array")
|
||||
// This can happen in weird, always-panics cases, like:
|
||||
// var x [0][2]int
|
||||
// x[i][j] = 5
|
||||
// We know it always panics because the LHS is ssa-able,
|
||||
// and arrays of length > 1 can't be ssa-able unless
|
||||
// they are somewhere inside an outer [0].
|
||||
// We can ignore the actual assignment, it is dynamically
|
||||
// unreachable. See issue 77635.
|
||||
return
|
||||
}
|
||||
if t.Size() == 0 {
|
||||
return
|
||||
@@ -5223,7 +5231,15 @@ func (s *state) addr(n ir.Node) *ssa.Value {
|
||||
}
|
||||
|
||||
if s.canSSA(n) {
|
||||
s.Fatalf("addr of canSSA expression: %+v", n)
|
||||
// This happens in weird, always-panics cases, like:
|
||||
// var x [0][2]int
|
||||
// x[i][j] = 5
|
||||
// The outer assignment, ...[j] = 5, is a fine
|
||||
// assignment to do, but requires computing the address
|
||||
// &x[i], which will always panic when evaluated.
|
||||
// We just return something reasonable in this case.
|
||||
// It will be dynamically unreachable. See issue 77635.
|
||||
return s.newValue1A(ssa.OpAddr, n.Type().PtrTo(), ir.Syms.Zerobase, s.sb)
|
||||
}
|
||||
|
||||
t := types.NewPtr(n.Type())
|
||||
|
||||
23
test/fixedbugs/issue77635.go
Normal file
23
test/fixedbugs/issue77635.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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 77635: test building values of zero-sized types.
|
||||
|
||||
package main
|
||||
|
||||
import "reflect"
|
||||
|
||||
func F[T interface{ [2][0]int }](x T) bool {
|
||||
return reflect.DeepEqual(struct {
|
||||
t T
|
||||
c chan int
|
||||
}{t: x}, 1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var t [2][0]int
|
||||
F(t)
|
||||
}
|
||||
62
test/fixedbugs/issue77635b.go
Normal file
62
test/fixedbugs/issue77635b.go
Normal file
@@ -0,0 +1,62 @@
|
||||
// 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 77635: test building values of zero-sized types.
|
||||
|
||||
package p
|
||||
|
||||
type T1 [2][0]int
|
||||
type T2 [0][2]int
|
||||
type T3 struct {
|
||||
t T1
|
||||
x *byte
|
||||
}
|
||||
type T4 struct {
|
||||
t T2
|
||||
x *byte
|
||||
}
|
||||
|
||||
func f1(t T1) any {
|
||||
return t
|
||||
}
|
||||
func f2(t T2) any {
|
||||
return t
|
||||
}
|
||||
func f3(t T3) any {
|
||||
return t
|
||||
}
|
||||
func f4(t T4) any {
|
||||
return t
|
||||
}
|
||||
func f5(t T1) any {
|
||||
return T3{t:t}
|
||||
}
|
||||
func f6(t T2) any {
|
||||
return T4{t:t}
|
||||
}
|
||||
func f7(t T1) {
|
||||
use(T3{t:t})
|
||||
}
|
||||
func f8(t T2) {
|
||||
use(T4{t:t})
|
||||
}
|
||||
|
||||
func g1(t T3, i int) {
|
||||
t.t[i][i] = 1
|
||||
}
|
||||
func g2(t T4, i int) {
|
||||
t.t[i][i] = 1
|
||||
}
|
||||
func g3(t *T3, i int) {
|
||||
t.t[i][i] = 1
|
||||
}
|
||||
func g4(t *T4, i int) {
|
||||
t.t[i][i] = 1
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func use(x any) {
|
||||
}
|
||||
Reference in New Issue
Block a user