1// run 2 3// Copyright 2021 The Go Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7package main 8 9import ( 10 "math" 11 "unsafe" 12) 13 14const maxUintptr = 1 << (8 * unsafe.Sizeof(uintptr(0))) 15 16func main() { 17 var p [10]byte 18 19 // unsafe.Add 20 { 21 p1 := unsafe.Pointer(&p[1]) 22 assert(unsafe.Add(p1, 1) == unsafe.Pointer(&p[2])) 23 assert(unsafe.Add(p1, -1) == unsafe.Pointer(&p[0])) 24 } 25 26 // unsafe.Slice 27 { 28 s := unsafe.Slice(&p[0], len(p)) 29 assert(&s[0] == &p[0]) 30 assert(len(s) == len(p)) 31 assert(cap(s) == len(p)) 32 33 // nil pointer with zero length returns nil 34 assert(unsafe.Slice((*int)(nil), 0) == nil) 35 36 // nil pointer with positive length panics 37 mustPanic(func() { _ = unsafe.Slice((*int)(nil), 1) }) 38 39 // negative length 40 var neg int = -1 41 mustPanic(func() { _ = unsafe.Slice(new(byte), neg) }) 42 43 // length too large 44 var tooBig uint64 = math.MaxUint64 45 mustPanic(func() { _ = unsafe.Slice(new(byte), tooBig) }) 46 47 // size overflows address space 48 mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8) }) 49 mustPanic(func() { _ = unsafe.Slice(new(uint64), maxUintptr/8+1) }) 50 51 // sliced memory overflows address space 52 last := (*byte)(unsafe.Pointer(^uintptr(0))) 53 _ = unsafe.Slice(last, 1) 54 mustPanic(func() { _ = unsafe.Slice(last, 2) }) 55 } 56 57 // unsafe.String 58 { 59 s := unsafe.String(&p[0], len(p)) 60 assert(s == string(p[:])) 61 assert(len(s) == len(p)) 62 63 // the empty string 64 assert(unsafe.String(nil, 0) == "") 65 66 // nil pointer with positive length panics 67 mustPanic(func() { _ = unsafe.String(nil, 1) }) 68 69 // negative length 70 var neg int = -1 71 mustPanic(func() { _ = unsafe.String(new(byte), neg) }) 72 73 // length too large 74 var tooBig uint64 = math.MaxUint64 75 mustPanic(func() { _ = unsafe.String(new(byte), tooBig) }) 76 77 // string memory overflows address space 78 last := (*byte)(unsafe.Pointer(^uintptr(0))) 79 _ = unsafe.String(last, 1) 80 mustPanic(func() { _ = unsafe.String(last, 2) }) 81 } 82 83 // unsafe.StringData 84 { 85 var s = "string" 86 assert(string(unsafe.Slice(unsafe.StringData(s), len(s))) == s) 87 } 88 89 //unsafe.SliceData 90 { 91 var s = []byte("slice") 92 assert(unsafe.String(unsafe.SliceData(s), len(s)) == string(s)) 93 } 94} 95 96func assert(ok bool) { 97 if !ok { 98 panic("FAIL") 99 } 100} 101 102func mustPanic(f func()) { 103 defer func() { 104 assert(recover() != nil) 105 }() 106 f() 107} 108