]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.19] cmd/compile: fix broken IR for iface -> eface
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 16 Nov 2022 18:02:26 +0000 (01:02 +0700)
committerGopher Robot <gobot@golang.org>
Wed, 28 Dec 2022 16:11:17 +0000 (16:11 +0000)
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 #56770

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>
Reviewed-on: https://go-review.googlesource.com/c/go/+/451875
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
src/cmd/compile/internal/walk/convert.go
test/fixedbugs/issue56768.go [new file with mode: 0644]

index 72631e7dfb04e64375a54e2d107e0f15bd1b7d6d..07ce0b609dcab24f2a27092bdf765502b38b4ae4 100644 (file)
@@ -79,13 +79,15 @@ func walkConvInterface(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
 
        var typeWord ir.Node
        if toType.IsEmptyInterface() {
-               // Implement interface to empty interface conversion.
-               // res = itab
+               // Implement interface to empty interface conversion:
+               //
+               // var res *uint8
+               // res = (*uint8)(unsafe.Pointer(itab))
                // if res != nil {
                //    res = res.type
                // }
                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.Body = []ir.Node{ir.NewAssignStmt(base.Pos, typeWord, itabType(typeWord))}
                init.Append(nif)
diff --git a/test/fixedbugs/issue56768.go b/test/fixedbugs/issue56768.go
new file mode 100644 (file)
index 0000000..1b2db4c
--- /dev/null
@@ -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},
+               },
+       }
+}