1
0
mirror of https://github.com/golang/go synced 2024-11-27 02:41:23 -07:00
go/test/unsafebuiltins.go

108 lines
2.3 KiB
Go
Raw Normal View History

// run
// 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 (
"math"
"unsafe"
)
const maxUintptr = 1 << (8 * unsafe.Sizeof(uintptr(0)))
func main() {
var p [10]byte
// unsafe.Add
{
p1 := unsafe.Pointer(&p[1])
assert(unsafe.Add(p1, 1) == unsafe.Pointer(&p[2]))
assert(unsafe.Add(p1, -1) == unsafe.Pointer(&p[0]))
}
// unsafe.Slice
{
s := unsafe.Slice(&p[0], len(p))
assert(&s[0] == &p[0])
assert(len(s) == len(p))
assert(cap(s) == len(p))
// nil pointer with zero length returns nil
assert(unsafe.Slice((*int)(nil), 0) == nil)
// nil pointer with positive length panics
mustPanic(func() { _ = unsafe.Slice((*int)(nil), 1) })
// negative length
var neg int = -1
mustPanic(func() { _ = unsafe.Slice(new(byte), neg) })
// length too large
var tooBig uint64 = math.MaxUint64
mustPanic(func() { _ = unsafe.Slice(new(byte), tooBig) })
// size overflows address space
mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8) })
mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8+1) })
// sliced memory overflows address space
last := (*byte)(unsafe.Pointer(^uintptr(0)))
_ = unsafe.Slice(last, 1)
mustPanic(func() { _ = unsafe.Slice(last, 2) })
}
// unsafe.String
{
s := unsafe.String(&p[0], len(p))
assert(s == string(p[:]))
assert(len(s) == len(p))
// the empty string
assert(unsafe.String(nil, 0) == "")
// nil pointer with positive length panics
mustPanic(func() { _ = unsafe.String(nil, 1) })
// negative length
var neg int = -1
mustPanic(func() { _ = unsafe.String(new(byte), neg) })
// length too large
var tooBig uint64 = math.MaxUint64
mustPanic(func() { _ = unsafe.String(new(byte), tooBig) })
// string memory overflows address space
last := (*byte)(unsafe.Pointer(^uintptr(0)))
_ = unsafe.String(last, 1)
mustPanic(func() { _ = unsafe.String(last, 2) })
}
// unsafe.StringData
{
var s = "string"
assert(string(unsafe.Slice(unsafe.StringData(s), len(s))) == s)
}
//unsafe.SliceData
{
var s = []byte("slice")
assert(unsafe.String(unsafe.SliceData(s), len(s)) == string(s))
}
}
func assert(ok bool) {
if !ok {
panic("FAIL")
}
}
func mustPanic(f func()) {
defer func() {
assert(recover() != nil)
}()
f()
}