github.com/MangoDowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/misc/cgo/test/issue10303.go (about)

     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  }