]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: make pointers to arrays their own shape
authorKeith Randall <khr@golang.org>
Wed, 3 Nov 2021 16:40:32 +0000 (09:40 -0700)
committerKeith Randall <khr@golang.org>
Wed, 3 Nov 2021 17:56:16 +0000 (17:56 +0000)
Pointers to arrays can be used to cast from a slice. We need
the shape of such type params to be different so we can compile
those casts correctly.

This is kind of a big hammer to fix #49295. It would be nice to
only do this when we know there's a []T->*[N]T conversion.

Fixes #49295

Change-Id: Ibda33057fab2dd28162537aab0f1244211d68e3f
Reviewed-on: https://go-review.googlesource.com/c/go/+/361135
Trust: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dan Scales <danscales@google.com>
src/cmd/compile/internal/typecheck/subr.go
test/typeparam/issue49295.go [new file with mode: 0644]

index 96e120fe03a78578796f8dcd67f3a48ef8742472..1986845f64299df7151cd9179dbe89ceaf3fe11f 100644 (file)
@@ -1421,7 +1421,9 @@ func Shapify(t *types.Type, index int) *types.Type {
 
        // All pointers have the same shape.
        // TODO: Make unsafe.Pointer the same shape as normal pointers.
-       if u.Kind() == types.TPTR {
+       // Note: pointers to arrays are special because of slice-to-array-pointer
+       // conversions. See issue 49295.
+       if u.Kind() == types.TPTR && u.Elem().Kind() != types.TARRAY {
                u = types.Types[types.TUINT8].PtrTo()
        }
 
diff --git a/test/typeparam/issue49295.go b/test/typeparam/issue49295.go
new file mode 100644 (file)
index 0000000..435b44d
--- /dev/null
@@ -0,0 +1,30 @@
+// run -gcflags=-G=3
+
+// Copyright 2021 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 "io"
+
+type Reader struct {
+       buf []byte
+}
+type Token *[16]byte
+
+func Read[T interface{ ~*[16]byte }](r *Reader) (t T, err error) {
+       if n := len(t); len(r.buf) >= n {
+               t = T(r.buf[:n])
+               r.buf = r.buf[n:]
+               return
+       }
+       err = io.EOF
+       return
+}
+
+func main() {
+       r := &Reader{buf: []byte("0123456789abcdef")}
+       token, err := Read[Token](r)
+       _, _ = token, err
+}