summaryrefslogtreecommitdiff
path: root/libgo/misc/cgo/test/issue10303.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/misc/cgo/test/issue10303.go')
-rw-r--r--libgo/misc/cgo/test/issue10303.go76
1 files changed, 76 insertions, 0 deletions
diff --git a/libgo/misc/cgo/test/issue10303.go b/libgo/misc/cgo/test/issue10303.go
new file mode 100644
index 00000000000..66e2644d066
--- /dev/null
+++ b/libgo/misc/cgo/test/issue10303.go
@@ -0,0 +1,76 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 10303. Pointers passed to C were not marked as escaping (bug in cgo).
+
+package cgotest
+
+import "runtime"
+
+/*
+typedef int *intptr;
+
+void setintstar(int *x) {
+ *x = 1;
+}
+
+void setintptr(intptr x) {
+ *x = 1;
+}
+
+void setvoidptr(void *x) {
+ *(int*)x = 1;
+}
+
+typedef struct Struct Struct;
+struct Struct {
+ int *P;
+};
+
+void setstruct(Struct s) {
+ *s.P = 1;
+}
+
+*/
+import "C"
+
+import (
+ "testing"
+ "unsafe"
+)
+
+func test10303(t *testing.T, n int) {
+ if runtime.Compiler == "gccgo" {
+ t.Skip("gccgo permits C pointers on the stack")
+ }
+
+ // Run at a few different stack depths just to avoid an unlucky pass
+ // due to variables ending up on different pages.
+ if n > 0 {
+ test10303(t, n-1)
+ }
+ if t.Failed() {
+ return
+ }
+ var x, y, z, v, si C.int
+ var s C.Struct
+ C.setintstar(&x)
+ C.setintptr(&y)
+ C.setvoidptr(unsafe.Pointer(&v))
+ s.P = &si
+ C.setstruct(s)
+
+ if uintptr(unsafe.Pointer(&x))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff {
+ t.Error("C int* argument on stack")
+ }
+ if uintptr(unsafe.Pointer(&y))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff {
+ t.Error("C intptr argument on stack")
+ }
+ if uintptr(unsafe.Pointer(&v))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff {
+ t.Error("C void* argument on stack")
+ }
+ if uintptr(unsafe.Pointer(&si))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff {
+ t.Error("C struct field pointer on stack")
+ }
+}