]> Cypherpunks.ru repositories - gostls13.git/commit
cmd/compile: fix devirtualization bug with unified IR
authorMatthew Dempsky <mdempsky@google.com>
Thu, 18 Aug 2022 11:56:10 +0000 (04:56 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 18 Aug 2022 17:26:32 +0000 (17:26 +0000)
commitd6294e00f029d93b8552827bce1f24f67458d3f2
tree545454bc49d3b40b69ae85fa9efb9016bbddc329
parent07cf24bdfe55dd3493e580c67b5437a114df7658
cmd/compile: fix devirtualization bug with unified IR

As a consistency check in devirtualization, when we determine `i` (of
interface type `I`) always has dynamic type `T`, we insert a type
assertion `i.(T)`. This emits an itab check for `go:itab.T,I`, but
it's always true (and so SSA optimizes it away).

However, if `I` is instead the generic interface type `I[T]`, then
`go:itab.T,I[int]` and `go:itab.T,I[go.shape.int]` are equivalent but
distinct itabs. And notably, we'll have originally created the
interface value using the former; but the (non-dynamic) TypeAssertExpr
created by devirtualization would ultimately emit a comparison against
the latter. This comparison would then evaluate false, leading to a
spurious type assertion panic at runtime.

The comparison is just meant as an extra safety check, so it should be
safe to just disable. But for now, it's simpler/safer to just punt on
devirtualization in this case. (The non-unified frontend doesn't
devirtualize this either.)

Change-Id: I6a8809bcfebc9571f32e289fa4bc6a8b0d21ca46
Reviewed-on: https://go-review.googlesource.com/c/go/+/424774
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Keith Randall <khr@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
src/cmd/compile/internal/devirtualize/devirtualize.go
test/typeparam/mdempsky/21.go [new file with mode: 0644]