1// errorcheck -0 -m -l 2 3// Copyright 2019 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 7// Test escape analysis for unsafe.Pointer rules. 8 9package escape 10 11import ( 12 "reflect" 13 "unsafe" 14) 15 16// (1) Conversion of a *T1 to Pointer to *T2. 17 18func convert(p *float64) *uint64 { // ERROR "leaking param: p to result ~r0 level=0$" 19 return (*uint64)(unsafe.Pointer(p)) 20} 21 22// (3) Conversion of a Pointer to a uintptr and back, with arithmetic. 23 24func arithAdd() unsafe.Pointer { 25 var x [2]byte // ERROR "moved to heap: x" 26 return unsafe.Pointer(uintptr(unsafe.Pointer(&x[0])) + 1) 27} 28 29func arithSub() unsafe.Pointer { 30 var x [2]byte // ERROR "moved to heap: x" 31 return unsafe.Pointer(uintptr(unsafe.Pointer(&x[1])) - 1) 32} 33 34func arithMask() unsafe.Pointer { 35 var x [2]byte // ERROR "moved to heap: x" 36 return unsafe.Pointer(uintptr(unsafe.Pointer(&x[1])) &^ 1) 37} 38 39// (5) Conversion of the result of reflect.Value.Pointer or 40// reflect.Value.UnsafeAddr from uintptr to Pointer. 41 42// BAD: should be "leaking param: p to result ~r0 level=0$" 43func valuePointer(p *int) unsafe.Pointer { // ERROR "leaking param: p$" 44 return unsafe.Pointer(reflect.ValueOf(p).Pointer()) 45} 46 47// BAD: should be "leaking param: p to result ~r0 level=0$" 48func valueUnsafeAddr(p *int) unsafe.Pointer { // ERROR "leaking param: p$" 49 return unsafe.Pointer(reflect.ValueOf(p).Elem().UnsafeAddr()) 50} 51 52// (6) Conversion of a reflect.SliceHeader or reflect.StringHeader 53// Data field to or from Pointer. 54 55func fromSliceData(s []int) unsafe.Pointer { // ERROR "leaking param: s to result ~r0 level=0$" 56 return unsafe.Pointer((*reflect.SliceHeader)(unsafe.Pointer(&s)).Data) 57} 58 59func fromStringData(s string) unsafe.Pointer { // ERROR "leaking param: s to result ~r0 level=0$" 60 return unsafe.Pointer((*reflect.StringHeader)(unsafe.Pointer(&s)).Data) 61} 62 63func toSliceData(s *[]int, p unsafe.Pointer) { // ERROR "s does not escape" "leaking param: p$" 64 (*reflect.SliceHeader)(unsafe.Pointer(s)).Data = uintptr(p) 65} 66 67func toStringData(s *string, p unsafe.Pointer) { // ERROR "s does not escape" "leaking param: p$" 68 (*reflect.StringHeader)(unsafe.Pointer(s)).Data = uintptr(p) 69} 70