• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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("CheckPtrStringOK", CheckPtrStringOK)
24	register("CheckPtrStringFail", CheckPtrStringFail)
25	register("CheckPtrAlignmentNested", CheckPtrAlignmentNested)
26}
27
28func CheckPtrAlignmentNoPtr() {
29	var x [2]int64
30	p := unsafe.Pointer(&x[0])
31	sink2 = (*int64)(unsafe.Pointer(uintptr(p) + 1))
32}
33
34func CheckPtrAlignmentPtr() {
35	var x [2]int64
36	p := unsafe.Pointer(&x[0])
37	sink2 = (**int64)(unsafe.Pointer(uintptr(p) + 1))
38}
39
40// CheckPtrAlignmentNilPtr tests that checkptrAlignment doesn't crash
41// on nil pointers (#47430).
42func CheckPtrAlignmentNilPtr() {
43	var do func(int)
44	do = func(n int) {
45		// Inflate the stack so runtime.shrinkstack gets called during GC
46		if n > 0 {
47			do(n - 1)
48		}
49
50		var p unsafe.Pointer
51		_ = (*int)(p)
52	}
53
54	go func() {
55		for {
56			runtime.GC()
57		}
58	}()
59
60	go func() {
61		for i := 0; ; i++ {
62			do(i % 1024)
63		}
64	}()
65
66	time.Sleep(time.Second)
67}
68
69func CheckPtrArithmetic() {
70	var x int
71	i := uintptr(unsafe.Pointer(&x))
72	sink2 = (*int)(unsafe.Pointer(i))
73}
74
75func CheckPtrArithmetic2() {
76	var x [2]int64
77	p := unsafe.Pointer(&x[1])
78	var one uintptr = 1
79	sink2 = unsafe.Pointer(uintptr(p) & ^one)
80}
81
82func CheckPtrSize() {
83	p := new(int64)
84	sink2 = p
85	sink2 = (*[100]int64)(unsafe.Pointer(p))
86}
87
88func CheckPtrSmall() {
89	sink2 = unsafe.Pointer(uintptr(1))
90}
91
92func CheckPtrSliceOK() {
93	p := new([4]int64)
94	sink2 = unsafe.Slice(&p[1], 3)
95}
96
97func CheckPtrSliceFail() {
98	p := new(int64)
99	sink2 = p
100	sink2 = unsafe.Slice(p, 100)
101}
102
103func CheckPtrStringOK() {
104	p := new([4]byte)
105	sink2 = unsafe.String(&p[1], 3)
106}
107
108func CheckPtrStringFail() {
109	p := new(byte)
110	sink2 = p
111	sink2 = unsafe.String(p, 100)
112}
113
114func CheckPtrAlignmentNested() {
115	s := make([]int8, 100)
116	p := unsafe.Pointer(&s[0])
117	n := 9
118	_ = ((*[10]int8)(unsafe.Pointer((*[10]int64)(unsafe.Pointer(&p)))))[:n:n]
119}
120