| // Copyright 2020 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 ( |
| "runtime" |
| "time" |
| "unsafe" |
| ) |
| |
| func init() { |
| register("CheckPtrAlignmentNoPtr", CheckPtrAlignmentNoPtr) |
| register("CheckPtrAlignmentPtr", CheckPtrAlignmentPtr) |
| register("CheckPtrAlignmentNilPtr", CheckPtrAlignmentNilPtr) |
| register("CheckPtrArithmetic", CheckPtrArithmetic) |
| register("CheckPtrArithmetic2", CheckPtrArithmetic2) |
| register("CheckPtrSize", CheckPtrSize) |
| register("CheckPtrSmall", CheckPtrSmall) |
| register("CheckPtrSliceOK", CheckPtrSliceOK) |
| register("CheckPtrSliceFail", CheckPtrSliceFail) |
| register("CheckPtrAlignmentNested", CheckPtrAlignmentNested) |
| } |
| |
| func CheckPtrAlignmentNoPtr() { |
| var x [2]int64 |
| p := unsafe.Pointer(&x[0]) |
| sink2 = (*int64)(unsafe.Pointer(uintptr(p) + 1)) |
| } |
| |
| func CheckPtrAlignmentPtr() { |
| var x [2]int64 |
| p := unsafe.Pointer(&x[0]) |
| sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1)) |
| } |
| |
| // CheckPtrAlignmentNilPtr tests that checkptrAlignment doesn't crash |
| // on nil pointers (#47430). |
| func CheckPtrAlignmentNilPtr() { |
| var do func(int) |
| do = func(n int) { |
| // Inflate the stack so runtime.shrinkstack gets called during GC |
| if n > 0 { |
| do(n - 1) |
| } |
| |
| var p unsafe.Pointer |
| _ = (*int)(p) |
| } |
| |
| go func() { |
| for { |
| runtime.GC() |
| } |
| }() |
| |
| go func() { |
| for i := 0; ; i++ { |
| do(i % 1024) |
| } |
| }() |
| |
| time.Sleep(time.Second) |
| } |
| |
| func CheckPtrArithmetic() { |
| var x int |
| i := uintptr(unsafe.Pointer(&x)) |
| sink2 = (*int)(unsafe.Pointer(i)) |
| } |
| |
| func CheckPtrArithmetic2() { |
| var x [2]int64 |
| p := unsafe.Pointer(&x[1]) |
| var one uintptr = 1 |
| sink2 = unsafe.Pointer(uintptr(p) & ^one) |
| } |
| |
| func CheckPtrSize() { |
| p := new(int64) |
| sink2 = p |
| sink2 = (*[100]int64)(unsafe.Pointer(p)) |
| } |
| |
| func CheckPtrSmall() { |
| sink2 = unsafe.Pointer(uintptr(1)) |
| } |
| |
| func CheckPtrSliceOK() { |
| p := new([4]int64) |
| sink2 = unsafe.Slice(&p[1], 3) |
| } |
| |
| func CheckPtrSliceFail() { |
| p := new(int64) |
| sink2 = p |
| sink2 = unsafe.Slice(p, 100) |
| } |
| |
| func CheckPtrAlignmentNested() { |
| s := make([]int8, 100) |
| p := unsafe.Pointer(&s[0]) |
| n := 9 |
| _ = ((*[10]int8)(unsafe.Pointer((*[10]int64)(unsafe.Pointer(&p)))))[:n:n] |
| } |