mirror of https://github.com/golang/go.git
go/ssa/interp: handle nil slice convert to array pointer
Converting from nil slice to a zero length array pointer must be nil. Updates golang/go#46987 Change-Id: I8894b92bd85fae8ea77bf01b92ee56f1a215a75b Reviewed-on: https://go-review.googlesource.com/c/tools/+/336489 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Trust: Tim King <taking@google.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Tim King <taking@google.com> gopls-CI: kokoro <noreply+kokoro@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Tim King <taking@google.com> Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
parent
ab1fe7202b
commit
3810fa8296
|
|
@ -1367,11 +1367,13 @@ func sliceToArrayPointer(t_dst, t_src types.Type, x value) value {
|
|||
if utSrc, ok := utDst.(*types.Pointer); ok {
|
||||
if arr, ok := utSrc.Elem().(*types.Array); ok {
|
||||
x := x.([]value)
|
||||
a := make(array, arr.Len())
|
||||
for i := range a {
|
||||
a[i] = x[i]
|
||||
if arr.Len() > int64(len(x)) {
|
||||
panic("array length is greater than slice length")
|
||||
}
|
||||
v := value(a)
|
||||
if x == nil {
|
||||
return zero(utSrc)
|
||||
}
|
||||
v := value(array(x[:arr.Len()]))
|
||||
return &v
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,22 +2,47 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Test for slice to array pointer conversion introduced in go1.17
|
||||
// See: https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer
|
||||
|
||||
package main
|
||||
|
||||
// Test for slice to array pointer conversion introduced in go1.17
|
||||
|
||||
import "fmt"
|
||||
|
||||
var s = []byte{1, 2, 3, 4}
|
||||
var a = (*[4]byte)(s)
|
||||
|
||||
func main() {
|
||||
for i := range s {
|
||||
if a[i] != s[i] {
|
||||
panic(fmt.Sprintf("value mismatched: %v - %v\n", a[i], s[i]))
|
||||
}
|
||||
if (*a)[i] != s[i] {
|
||||
panic(fmt.Sprintf("value mismatched: %v - %v\n", (*a)[i], s[i]))
|
||||
}
|
||||
s := make([]byte, 2, 4)
|
||||
if s0 := (*[0]byte)(s); s0 == nil {
|
||||
panic("converted from non-nil slice result in nil array pointer")
|
||||
}
|
||||
if s2 := (*[2]byte)(s); &s2[0] != &s[0] {
|
||||
panic("the converted array is not slice underlying array")
|
||||
}
|
||||
wantPanic(
|
||||
func() {
|
||||
_ = (*[4]byte)(s) // panics: len([4]byte) > len(s)
|
||||
},
|
||||
"runtime error: array length is greater than slice length",
|
||||
)
|
||||
|
||||
var t []string
|
||||
if t0 := (*[0]string)(t); t0 != nil {
|
||||
panic("nil slice converted to *[0]byte should be nil")
|
||||
}
|
||||
wantPanic(
|
||||
func() {
|
||||
_ = (*[1]string)(t) // panics: len([1]string) > len(t)
|
||||
},
|
||||
"runtime error: array length is greater than slice length",
|
||||
)
|
||||
}
|
||||
|
||||
func wantPanic(fn func(), s string) {
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
panic("expected panic")
|
||||
}
|
||||
if got := err.(error).Error(); got != s {
|
||||
panic("expected panic " + s + " got " + got)
|
||||
}
|
||||
}()
|
||||
fn()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue