diff options
| author | Keith Randall <khr@golang.org> | 2025-10-22 10:13:44 -0700 |
|---|---|---|
| committer | David Chase <drchase@google.com> | 2025-10-29 09:16:38 -0700 |
| commit | 5ba37a3677d322c442ab77f94d4f92f1acc67dba (patch) | |
| tree | 7236ab1148f9d15ad2d03f070855399b38d37640 | |
| parent | 8097b1915f617167f3b12b03e78a23859d256eb6 (diff) | |
| download | go-5ba37a3677d322c442ab77f94d4f92f1acc67dba.tar.xz | |
[release-branch.go1.25] cmd/compile: don't optimize away a panicing interface comparison
We can't do direct pointer comparisons if the type is not a
comparable type.
Fixes #76010
Change-Id: I1687acff21832d2c2e8f3b875e7b5ec125702ef3
Reviewed-on: https://go-review.googlesource.com/c/go/+/713840
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/715720
Reviewed-by: Michael Knyszek <mknyszek@google.com>
| -rw-r--r-- | src/cmd/compile/internal/ssa/rewrite.go | 10 | ||||
| -rw-r--r-- | test/fixedbugs/issue76008.go | 35 |
2 files changed, 41 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go index eb2c3b31b8..4834f833c2 100644 --- a/src/cmd/compile/internal/ssa/rewrite.go +++ b/src/cmd/compile/internal/ssa/rewrite.go @@ -2555,7 +2555,7 @@ func rewriteStructStore(v *Value) *Value { // isDirectType reports whether v represents a type // (a *runtime._type) whose value is stored directly in an -// interface (i.e., is pointer or pointer-like). +// interface (i.e., is pointer or pointer-like) and is comparable. func isDirectType(v *Value) bool { return isDirectType1(v) } @@ -2571,7 +2571,8 @@ func isDirectType1(v *Value) bool { return false } if ti, ok := (*lsym.Extra).(*obj.TypeInfo); ok { - return types.IsDirectIface(ti.Type.(*types.Type)) + t := ti.Type.(*types.Type) + return types.IsDirectIface(t) && types.IsComparable(t) } } return false @@ -2588,7 +2589,7 @@ func isDirectType2(v *Value) bool { // isDirectIface reports whether v represents an itab // (a *runtime._itab) for a type whose value is stored directly -// in an interface (i.e., is pointer or pointer-like). +// in an interface (i.e., is pointer or pointer-like) and is comparable. func isDirectIface(v *Value) bool { return isDirectIface1(v, 9) } @@ -2607,7 +2608,8 @@ func isDirectIface1(v *Value, depth int) bool { return false } if ii, ok := (*lsym.Extra).(*obj.ItabInfo); ok { - return types.IsDirectIface(ii.Type.(*types.Type)) + t := ii.Type.(*types.Type) + return types.IsDirectIface(t) && types.IsComparable(t) } case OpConstNil: // We can treat this as direct, because if the itab is diff --git a/test/fixedbugs/issue76008.go b/test/fixedbugs/issue76008.go new file mode 100644 index 0000000000..bdf273bca1 --- /dev/null +++ b/test/fixedbugs/issue76008.go @@ -0,0 +1,35 @@ +// run + +// 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 + +import "runtime" + +func main() { + shouldPanic(func() { + g = any(func() {}) == any(func() {}) + }) + shouldPanic(func() { + g = any(map[int]int{}) == any(map[int]int{}) + }) + shouldPanic(func() { + g = any([]int{}) == any([]int{}) + }) +} + +var g bool + +func shouldPanic(f func()) { + defer func() { + err := recover() + if err == nil { + _, _, line, _ := runtime.Caller(2) + println("did not panic at line", line+1) + } + }() + + f() +} |
