]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.25] cmd/compile: don't optimize away a panicing interface comparison
authorKeith Randall <khr@golang.org>
Wed, 22 Oct 2025 17:13:44 +0000 (10:13 -0700)
committerDavid Chase <drchase@google.com>
Wed, 29 Oct 2025 16:16:38 +0000 (09:16 -0700)
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>
src/cmd/compile/internal/ssa/rewrite.go
test/fixedbugs/issue76008.go [new file with mode: 0644]

index eb2c3b31b8c99827afcb77752afdafd85a52b333..4834f833c2f553c06788d692ca96f3a4db368cbb 100644 (file)
@@ -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 (file)
index 0000000..bdf273b
--- /dev/null
@@ -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()
+}