Skip to content

Commit bd4dc41

Browse files
committed
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 #76008 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>
1 parent 30c047d commit bd4dc41

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

src/cmd/compile/internal/ssa/rewrite.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2626,7 +2626,7 @@ func rewriteStructStore(v *Value) *Value {
26262626

26272627
// isDirectType reports whether v represents a type
26282628
// (a *runtime._type) whose value is stored directly in an
2629-
// interface (i.e., is pointer or pointer-like).
2629+
// interface (i.e., is pointer or pointer-like) and is comparable.
26302630
func isDirectType(v *Value) bool {
26312631
return isDirectType1(v)
26322632
}
@@ -2639,7 +2639,8 @@ func isDirectType1(v *Value) bool {
26392639
case OpAddr:
26402640
lsym := v.Aux.(*obj.LSym)
26412641
if ti := lsym.TypeInfo(); ti != nil {
2642-
return types.IsDirectIface(ti.Type.(*types.Type))
2642+
t := ti.Type.(*types.Type)
2643+
return types.IsDirectIface(t) && types.IsComparable(t)
26432644
}
26442645
}
26452646
return false
@@ -2656,7 +2657,7 @@ func isDirectType2(v *Value) bool {
26562657

26572658
// isDirectIface reports whether v represents an itab
26582659
// (a *runtime._itab) for a type whose value is stored directly
2659-
// in an interface (i.e., is pointer or pointer-like).
2660+
// in an interface (i.e., is pointer or pointer-like) and is comparable.
26602661
func isDirectIface(v *Value) bool {
26612662
return isDirectIface1(v, 9)
26622663
}
@@ -2672,7 +2673,8 @@ func isDirectIface1(v *Value, depth int) bool {
26722673
case OpAddr:
26732674
lsym := v.Aux.(*obj.LSym)
26742675
if ii := lsym.ItabInfo(); ii != nil {
2675-
return types.IsDirectIface(ii.Type.(*types.Type))
2676+
t := ii.Type.(*types.Type)
2677+
return types.IsDirectIface(t) && types.IsComparable(t)
26762678
}
26772679
case OpConstNil:
26782680
// We can treat this as direct, because if the itab is

test/fixedbugs/issue76008.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// run
2+
3+
// Copyright 2025 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package main
8+
9+
import "runtime"
10+
11+
func main() {
12+
shouldPanic(func() {
13+
g = any(func() {}) == any(func() {})
14+
})
15+
shouldPanic(func() {
16+
g = any(map[int]int{}) == any(map[int]int{})
17+
})
18+
shouldPanic(func() {
19+
g = any([]int{}) == any([]int{})
20+
})
21+
}
22+
23+
var g bool
24+
25+
func shouldPanic(f func()) {
26+
defer func() {
27+
err := recover()
28+
if err == nil {
29+
_, _, line, _ := runtime.Caller(2)
30+
println("did not panic at line", line+1)
31+
}
32+
}()
33+
34+
f()
35+
}

0 commit comments

Comments
 (0)