1// Copyright 2020 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package main 6 7import ( 8 "runtime" 9 "time" 10 "unsafe" 11) 12 13func init() { 14 register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr) 15 register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr) 16 register("CheckPtrAlignmentNilPtr", CheckPtrAlignmentNilPtr) 17 register("CheckPtrArithmetic", CheckPtrArithmetic) 18 register("CheckPtrArithmetic2", CheckPtrArithmetic2) 19 register("CheckPtrSize", CheckPtrSize) 20 register("CheckPtrSmall", CheckPtrSmall) 21 register("CheckPtrSliceOK", CheckPtrSliceOK) 22 register("CheckPtrSliceFail", CheckPtrSliceFail) 23 register("CheckPtrAlignmentNested", CheckPtrAlignmentNested) 24} 25 26func CheckPtrAlignmentNoPtr() { 27 var x [2]int64 28 p := unsafe.Pointer(&x[0]) 29 sink2 = (*int64)(unsafe.Pointer(uintptr(p) + 1)) 30} 31 32func CheckPtrAlignmentPtr() { 33 var x [2]int64 34 p := unsafe.Pointer(&x[0]) 35 sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1)) 36} 37 38// CheckPtrAlignmentNilPtr tests that checkptrAlignment doesn't crash 39// on nil pointers (#47430). 40func CheckPtrAlignmentNilPtr() { 41 var do func(int) 42 do = func(n int) { 43 // Inflate the stack so runtime.shrinkstack gets called during GC 44 if n > 0 { 45 do(n - 1) 46 } 47 48 var p unsafe.Pointer 49 _ = (*int)(p) 50 } 51 52 go func() { 53 for { 54 runtime.GC() 55 } 56 }() 57 58 go func() { 59 for i := 0; ; i++ { 60 do(i % 1024) 61 } 62 }() 63 64 time.Sleep(time.Second) 65} 66 67func CheckPtrArithmetic() { 68 var x int 69 i := uintptr(unsafe.Pointer(&x)) 70 sink2 = (*int)(unsafe.Pointer(i)) 71} 72 73func CheckPtrArithmetic2() { 74 var x [2]int64 75 p := unsafe.Pointer(&x[1]) 76 var one uintptr = 1 77 sink2 = unsafe.Pointer(uintptr(p) & ^one) 78} 79 80func CheckPtrSize() { 81 p := new(int64) 82 sink2 = p 83 sink2 = (*[100]int64)(unsafe.Pointer(p)) 84} 85 86func CheckPtrSmall() { 87 sink2 = unsafe.Pointer(uintptr(1)) 88} 89 90func CheckPtrSliceOK() { 91 p := new([4]int64) 92 sink2 = unsafe.Slice(&p[1], 3) 93} 94 95func CheckPtrSliceFail() { 96 p := new(int64) 97 sink2 = p 98 sink2 = unsafe.Slice(p, 100) 99} 100 101func CheckPtrAlignmentNested() { 102 s := make([]int8, 100) 103 p := unsafe.Pointer(&s[0]) 104 n := 9 105 _ = ((*[10]int8)(unsafe.Pointer((*[10]int64)(unsafe.Pointer(&p)))))[:n:n] 106} 107