Source file
test/fixedbugs/issue80519.go
1
2
3
4
5
6
7 package main
8
9 import (
10 "runtime"
11 "unsafe"
12 )
13
14 var aliased = [3][3]int{{9, 9, 9}, {1, 9, 9}, {9, 9, 9}}
15 var unsafeAliased [3]unsafe.Pointer
16
17 type unsafeFieldTarget struct {
18 array *[4]uintptr
19 pad [3]uintptr
20 }
21
22
23 func clearAliased() {
24 keyp := &aliased[1][0]
25 for i := range 3 {
26 aliased[*keyp][i] = 0
27 }
28 }
29
30
31 func clearUnsafeAliased() {
32 target := (*[3]unsafe.Pointer)(unsafe.Pointer(&unsafeAliased[0]))
33 unsafeAliased[0] = unsafe.Pointer(target)
34 targetp := (**[3]unsafe.Pointer)(unsafe.Pointer(&unsafeAliased[0]))
35 for i := range 3 {
36 (**targetp)[i] = nil
37 }
38 }
39
40
41 func clearUnsafeField(t *unsafeFieldTarget) {
42 for i := range t.array {
43 t.array[i] = 0
44 }
45 }
46
47
48 func clearUnsafeSlice() {
49 var values []uintptr
50 values = unsafe.Slice((*uintptr)(unsafe.Pointer(&values)), 3)
51 for i := range values {
52 values[i] = 0
53 }
54 }
55
56 func main() {
57 want := [3][2]int{{0, 2}, {3, 0}, {5, 6}}
58
59 rows := [3][2]int{{1, 2}, {3, 4}, {5, 6}}
60 key := 2
61 for key = range 2 {
62 rows[key][key] = 0
63 }
64 if rows != want || key != 1 {
65 panic("range clear with assigned index variable")
66 }
67
68 rows = [3][2]int{{1, 2}, {3, 4}, {5, 6}}
69 for key := range 2 {
70 rows[key][key] = 0
71 }
72 if rows != want {
73 panic("range clear with declared index variable")
74 }
75
76 slices := [3][]int{{1, 2}, {3, 4}, {5, 6}}
77 key = 0
78 for key = range slices[key] {
79 slices[key][key] = 0
80 }
81 if slices[0][0] != 0 || slices[0][1] != 2 || slices[1][0] != 3 || slices[1][1] != 0 || key != 1 {
82 panic("range clear with index-dependent slice")
83 }
84
85 rows = [3][2]int{{1, 2}, {3, 4}, {5, 6}}
86 key = 0
87 keyp := &key
88 for key = range 2 {
89 rows[*keyp][key] = 0
90 }
91 if rows != want || key != 1 {
92 panic("range clear with indirect index dependency")
93 }
94
95 clearAliased()
96 if aliased != [3][3]int{{9, 0, 0}, {0, 9, 9}, {9, 9, 9}} {
97 panic("range clear target changed through cleared memory")
98 }
99
100 panicked := false
101 func() {
102 defer func() {
103 panicked = recover() != nil
104 }()
105 clearUnsafeAliased()
106 }()
107 if !panicked {
108 panic("range clear target changed through unsafe pointer")
109 }
110
111 fieldTarget := unsafeFieldTarget{}
112 fieldTarget.array = (*[4]uintptr)(unsafe.Pointer(&fieldTarget))
113 panicked = false
114 func() {
115 defer func() {
116 panicked = recover() != nil
117 }()
118 clearUnsafeField(&fieldTarget)
119 }()
120 if !panicked {
121 panic("range clear target changed through unsafe pointer field")
122 }
123
124 if runtime.GOARCH != "wasm" {
125 panicked = false
126 func() {
127 defer func() {
128 panicked = recover() != nil
129 }()
130 clearUnsafeSlice()
131 }()
132 if !panicked {
133 panic("range clear target changed through unsafe slice header")
134 }
135 }
136 }
137
View as plain text