1 // Copyright 2015 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 5 // Issue 10303. Pointers passed to C were not marked as escaping (bug in cgo). 6 7 package cgotest 8 9 import "runtime" 10 11 /* 12 typedef int *intptr; 13 14 void setintstar(int *x) { 15 *x = 1; 16 } 17 18 void setintptr(intptr x) { 19 *x = 1; 20 } 21 22 void setvoidptr(void *x) { 23 *(int*)x = 1; 24 } 25 26 typedef struct Struct Struct; 27 struct Struct { 28 int *P; 29 }; 30 31 void setstruct(Struct s) { 32 *s.P = 1; 33 } 34 35 */ 36 import "C" 37 38 import ( 39 "testing" 40 "unsafe" 41 ) 42 43 func test10303(t *testing.T, n int) { 44 if runtime.Compiler == "gccgo" { 45 t.Skip("gccgo permits C pointers on the stack") 46 } 47 48 // Run at a few different stack depths just to avoid an unlucky pass 49 // due to variables ending up on different pages. 50 if n > 0 { 51 test10303(t, n-1) 52 } 53 if t.Failed() { 54 return 55 } 56 var x, y, z, v, si C.int 57 var s C.Struct 58 C.setintstar(&x) 59 C.setintptr(&y) 60 C.setvoidptr(unsafe.Pointer(&v)) 61 s.P = &si 62 C.setstruct(s) 63 64 if uintptr(unsafe.Pointer(&x))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { 65 t.Error("C int* argument on stack") 66 } 67 if uintptr(unsafe.Pointer(&y))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { 68 t.Error("C intptr argument on stack") 69 } 70 if uintptr(unsafe.Pointer(&v))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { 71 t.Error("C void* argument on stack") 72 } 73 if uintptr(unsafe.Pointer(&si))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { 74 t.Error("C struct field pointer on stack") 75 } 76 } 77