mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/compile: fix broken IR for iface -> eface
For implementing interface to empty interface conversion, the compiler generate code like: var res *uint8 res = itab if res != nil { res = res.type } However, itab has type *uintptr, so the assignment is broken. The problem is not shown up, until CL 450215, which call typecheck on this broken assignment. To fix this, just cast itab to *uint8 when doing the conversion. Fixes #56768 Change-Id: Id42792d18e7f382578b40854d46eecd49673792c Reviewed-on: https://go-review.googlesource.com/c/go/+/451256 Reviewed-by: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
0bd4710ca6
commit
81c9b1d65f
@ -80,13 +80,15 @@ func walkConvInterface(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
|
|||||||
|
|
||||||
var typeWord ir.Node
|
var typeWord ir.Node
|
||||||
if toType.IsEmptyInterface() {
|
if toType.IsEmptyInterface() {
|
||||||
// Implement interface to empty interface conversion.
|
// Implement interface to empty interface conversion:
|
||||||
// res = itab
|
//
|
||||||
|
// var res *uint8
|
||||||
|
// res = (*uint8)(unsafe.Pointer(itab))
|
||||||
// if res != nil {
|
// if res != nil {
|
||||||
// res = res.type
|
// res = res.type
|
||||||
// }
|
// }
|
||||||
typeWord = typecheck.Temp(types.NewPtr(types.Types[types.TUINT8]))
|
typeWord = typecheck.Temp(types.NewPtr(types.Types[types.TUINT8]))
|
||||||
init.Append(ir.NewAssignStmt(base.Pos, typeWord, itab))
|
init.Append(ir.NewAssignStmt(base.Pos, typeWord, typecheck.Conv(typecheck.Conv(itab, types.Types[types.TUNSAFEPTR]), typeWord.Type())))
|
||||||
nif := ir.NewIfStmt(base.Pos, typecheck.Expr(ir.NewBinaryExpr(base.Pos, ir.ONE, typeWord, typecheck.NodNil())), nil, nil)
|
nif := ir.NewIfStmt(base.Pos, typecheck.Expr(ir.NewBinaryExpr(base.Pos, ir.ONE, typeWord, typecheck.NodNil())), nil, nil)
|
||||||
nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, typeWord, itabType(typeWord))}
|
nif.Body = []ir.Node{ir.NewAssignStmt(base.Pos, typeWord, itabType(typeWord))}
|
||||||
init.Append(nif)
|
init.Append(nif)
|
||||||
|
37
test/fixedbugs/issue56768.go
Normal file
37
test/fixedbugs/issue56768.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// compile
|
||||||
|
|
||||||
|
// Copyright 2022 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 p
|
||||||
|
|
||||||
|
type I interface {
|
||||||
|
M()
|
||||||
|
}
|
||||||
|
|
||||||
|
type slice []any
|
||||||
|
|
||||||
|
func f() {
|
||||||
|
ss := struct{ i I }{}
|
||||||
|
|
||||||
|
_ = [...]struct {
|
||||||
|
s slice
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
s: slice{ss.i},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
s: slice{ss.i},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
s: slice{ss.i},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
s: slice{ss.i},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
s: slice{ss.i},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user