diff options
Diffstat (limited to 'misc/cgo')
26 files changed, 449 insertions, 7 deletions
diff --git a/misc/cgo/errors/err3.go b/misc/cgo/errors/err3.go new file mode 100644 index 000000000..3680a4a4c --- /dev/null +++ b/misc/cgo/errors/err3.go @@ -0,0 +1,18 @@ +// Copyright 2014 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. + +package main + +/* +typedef struct foo foo_t; +typedef struct bar bar_t; + +foo_t *foop; +*/ +import "C" + +func main() { + x := (*C.bar_t)(nil) + C.foop = x // ERROR HERE +} diff --git a/misc/cgo/errors/test.bash b/misc/cgo/errors/test.bash index 697ae2fed..f0f60c844 100755 --- a/misc/cgo/errors/test.bash +++ b/misc/cgo/errors/test.bash @@ -26,6 +26,7 @@ check() { check err1.go check err2.go +check err3.go rm -rf errs _obj exit 0 diff --git a/misc/cgo/nocgo/nocgo.go b/misc/cgo/nocgo/nocgo.go new file mode 100644 index 000000000..00ae5e9c8 --- /dev/null +++ b/misc/cgo/nocgo/nocgo.go @@ -0,0 +1,22 @@ +// Copyright 2014 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. + +// Test that -static works when not using cgo. This test is in +// misc/cgo to take advantage of the testing framework support for +// when -static is expected to work. + +package nocgo + +func NoCgo() int { + c := make(chan int) + + // The test is run with external linking, which means that + // goroutines will be created via the runtime/cgo package. + // Make sure that works. + go func() { + c <- 42 + }() + + return <-c +} diff --git a/misc/cgo/nocgo/nocgo_test.go b/misc/cgo/nocgo/nocgo_test.go new file mode 100644 index 000000000..45d247cf9 --- /dev/null +++ b/misc/cgo/nocgo/nocgo_test.go @@ -0,0 +1,14 @@ +// Copyright 2014 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. + +package nocgo + +import "testing" + +func TestNop(t *testing.T) { + i := NoCgo() + if i != 42 { + t.Errorf("got %d, want %d", i, 42) + } +} diff --git a/misc/cgo/test/backdoor/backdoor.go b/misc/cgo/test/backdoor/backdoor.go index efe4f01f4..7398772bd 100644 --- a/misc/cgo/test/backdoor/backdoor.go +++ b/misc/cgo/test/backdoor/backdoor.go @@ -5,3 +5,4 @@ package backdoor func LockedOSThread() bool // in runtime.c +func Issue7695(x1, x2, x3, x4, x5, x6, x7, x8 uintptr) diff --git a/misc/cgo/test/backdoor/backdoor_gccgo.go b/misc/cgo/test/backdoor/backdoor_gccgo.go new file mode 100644 index 000000000..514f76ec5 --- /dev/null +++ b/misc/cgo/test/backdoor/backdoor_gccgo.go @@ -0,0 +1,11 @@ +// Copyright 2014 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. + +// This is the gccgo version of the stub in runtime.c. + +// +build gccgo + +package backdoor + +func Issue7695(x1, x2, x3, x4, x5, x6, x7, x8 uintptr) {} diff --git a/misc/cgo/test/backdoor/runtime.c b/misc/cgo/test/backdoor/runtime.c index 194a9c8e4..7e6b44872 100644 --- a/misc/cgo/test/backdoor/runtime.c +++ b/misc/cgo/test/backdoor/runtime.c @@ -23,3 +23,10 @@ void b = runtime·lockedOSThread(); FLUSH(&b); } + +// This is what a cgo-compiled stub declaration looks like. +void +·Issue7695(struct{void *y[8*sizeof(void*)];}p) +{ + USED(p); +} diff --git a/misc/cgo/test/cgo_linux_test.go b/misc/cgo/test/cgo_linux_test.go index 056d67c96..0a405c7a3 100644 --- a/misc/cgo/test/cgo_linux_test.go +++ b/misc/cgo/test/cgo_linux_test.go @@ -7,3 +7,4 @@ package cgotest import "testing" func TestSetgid(t *testing.T) { testSetgid(t) } +func Test6997(t *testing.T) { test6997(t) } diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go index b7c6d2876..eb237725a 100644 --- a/misc/cgo/test/cgo_test.go +++ b/misc/cgo/test/cgo_test.go @@ -43,12 +43,15 @@ func TestCflags(t *testing.T) { testCflags(t) } func Test5337(t *testing.T) { test5337(t) } func Test5548(t *testing.T) { test5548(t) } func Test5603(t *testing.T) { test5603(t) } +func Test6833(t *testing.T) { test6833(t) } func Test3250(t *testing.T) { test3250(t) } func TestCallbackStack(t *testing.T) { testCallbackStack(t) } func TestFpVar(t *testing.T) { testFpVar(t) } func Test4339(t *testing.T) { test4339(t) } func Test6390(t *testing.T) { test6390(t) } func Test5986(t *testing.T) { test5986(t) } +func Test7665(t *testing.T) { test7665(t) } func TestNaming(t *testing.T) { testNaming(t) } +func Test7560(t *testing.T) { test7560(t) } func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) } diff --git a/misc/cgo/test/issue6833.go b/misc/cgo/test/issue6833.go new file mode 100644 index 000000000..e12d53422 --- /dev/null +++ b/misc/cgo/test/issue6833.go @@ -0,0 +1,27 @@ +// Copyright 2013 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. + +package cgotest + +/* +extern unsigned long long issue6833Func(unsigned int, unsigned long long); +*/ +import "C" + +import "testing" + +//export GoIssue6833Func +func GoIssue6833Func(aui uint, aui64 uint64) uint64 { + return aui64 + uint64(aui) +} + +func test6833(t *testing.T) { + ui := 7 + ull := uint64(0x4000300020001000) + v := uint64(C.issue6833Func(C.uint(ui), C.ulonglong(ull))) + exp := uint64(ui) + ull + if v != exp { + t.Errorf("issue6833Func() returns %x, expected %x", v, exp) + } +} diff --git a/misc/cgo/test/issue6833_c.c b/misc/cgo/test/issue6833_c.c new file mode 100644 index 000000000..a77b425b5 --- /dev/null +++ b/misc/cgo/test/issue6833_c.c @@ -0,0 +1,10 @@ +// Copyright 2013 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. + +#include "_cgo_export.h" + +unsigned long long +issue6833Func(unsigned int aui, unsigned long long aull) { + return GoIssue6833Func(aui, aull); +} diff --git a/misc/cgo/test/issue6997_linux.c b/misc/cgo/test/issue6997_linux.c new file mode 100644 index 000000000..897cdd081 --- /dev/null +++ b/misc/cgo/test/issue6997_linux.c @@ -0,0 +1,26 @@ +// Copyright 2014 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. + +#include <pthread.h> +#include <stdio.h> +#include <unistd.h> + +static pthread_t thread; + +static void* threadfunc(void* dummy) { + while(1) { + sleep(1); + } +} + +int StartThread() { + return pthread_create(&thread, NULL, &threadfunc, NULL); +} + +int CancelThread() { + void *r; + pthread_cancel(thread); + pthread_join(thread, &r); + return (r == PTHREAD_CANCELED); +} diff --git a/misc/cgo/test/issue6997_linux.go b/misc/cgo/test/issue6997_linux.go new file mode 100644 index 000000000..871bd517a --- /dev/null +++ b/misc/cgo/test/issue6997_linux.go @@ -0,0 +1,40 @@ +// Copyright 2014 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. + +// Test that pthread_cancel works as expected +// (NPTL uses SIGRTMIN to implement thread cancellation) +// See http://golang.org/issue/6997 +package cgotest + +/* +#cgo CFLAGS: -pthread +#cgo LDFLAGS: -pthread +extern int StartThread(); +extern int CancelThread(); +*/ +import "C" + +import "testing" +import "time" + +func test6997(t *testing.T) { + r := C.StartThread() + if r != 0 { + t.Error("pthread_create failed") + } + c := make(chan C.int) + go func() { + time.Sleep(500 * time.Millisecond) + c <- C.CancelThread() + }() + + select { + case r = <-c: + if r == 0 { + t.Error("pthread finished but wasn't cancelled??") + } + case <-time.After(5 * time.Second): + t.Error("hung in pthread_cancel/pthread_join") + } +} diff --git a/misc/cgo/test/issue7234_test.go b/misc/cgo/test/issue7234_test.go new file mode 100644 index 000000000..713dade4c --- /dev/null +++ b/misc/cgo/test/issue7234_test.go @@ -0,0 +1,21 @@ +// Copyright 2014 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. + +package cgotest + +import "testing" + +// This test actually doesn't have anything to do with cgo. It is a +// test of http://golang.org/issue/7234, a compiler/linker bug in +// handling string constants when using -linkmode=external. The test +// is in this directory because we routinely test -linkmode=external +// here. + +var v7234 = [...]string{"runtime/cgo"} + +func TestIssue7234(t *testing.T) { + if v7234[0] != "runtime/cgo" { + t.Errorf("bad string constant %q", v7234[0]) + } +} diff --git a/misc/cgo/test/issue7560.go b/misc/cgo/test/issue7560.go new file mode 100644 index 000000000..4bea6e357 --- /dev/null +++ b/misc/cgo/test/issue7560.go @@ -0,0 +1,44 @@ +// Copyright 2014 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. + +package cgotest + +/* +#include <stdint.h> + +typedef struct { + char x; + long y; +} __attribute__((__packed__)) misaligned; + +int +offset7560(void) +{ + return (uintptr_t)&((misaligned*)0)->y; +} +*/ +import "C" + +import ( + "reflect" + "testing" +) + +func test7560(t *testing.T) { + // some mingw don't implement __packed__ correctly. + if C.offset7560() != 1 { + t.Skip("C compiler did not pack struct") + } + + // C.misaligned should have x but then a padding field to get to the end of the struct. + // There should not be a field named 'y'. + var v C.misaligned + rt := reflect.TypeOf(&v).Elem() + if rt.NumField() != 2 || rt.Field(0).Name != "x" || rt.Field(1).Name != "_" { + t.Errorf("unexpected fields in C.misaligned:\n") + for i := 0; i < rt.NumField(); i++ { + t.Logf("%+v\n", rt.Field(i)) + } + } +} diff --git a/misc/cgo/test/issue7665.go b/misc/cgo/test/issue7665.go new file mode 100644 index 000000000..4f36dce75 --- /dev/null +++ b/misc/cgo/test/issue7665.go @@ -0,0 +1,25 @@ +// Copyright 2013 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. + +package cgotest + +import ( + "testing" + "unsafe" +) + +// extern void f7665(void); +import "C" + +//export f7665 +func f7665() {} + +var bad7665 unsafe.Pointer = C.f7665 +var good7665 uintptr = uintptr(C.f7665) + +func test7665(t *testing.T) { + if bad7665 == nil || bad7665 != unsafe.Pointer(good7665) { + t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665) + } +} diff --git a/misc/cgo/test/issue7695_test.go b/misc/cgo/test/issue7695_test.go new file mode 100644 index 000000000..4bd6f8e73 --- /dev/null +++ b/misc/cgo/test/issue7695_test.go @@ -0,0 +1,27 @@ +// Copyright 2014 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. + +// Demo of deferred C function with untrue prototype +// breaking stack copying. See golang.org/issue/7695. + +package cgotest + +import ( + "testing" + + "./backdoor" +) + +func TestIssue7695(t *testing.T) { + defer backdoor.Issue7695(1, 0, 2, 0, 0, 3, 0, 4) + recurse(100) +} + +func recurse(n int) { + var x [128]int + n += x[0] + if n > 0 { + recurse(n - 1) + } +} diff --git a/misc/cgo/test/issue7786.go b/misc/cgo/test/issue7786.go new file mode 100644 index 000000000..b92763789 --- /dev/null +++ b/misc/cgo/test/issue7786.go @@ -0,0 +1,51 @@ +// Copyright 2013 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 7786. No runtime test, just make sure that typedef and struct/union/class are interchangeable at compile time. + +package cgotest + +// struct test7786; +// typedef struct test7786 typedef_test7786; +// void f7786(struct test7786 *ctx) {} +// void g7786(typedef_test7786 *ctx) {} +// +// typedef struct body7786 typedef_body7786; +// struct body7786 { int x; }; +// void b7786(struct body7786 *ctx) {} +// void c7786(typedef_body7786 *ctx) {} +// +// typedef union union7786 typedef_union7786; +// void u7786(union union7786 *ctx) {} +// void v7786(typedef_union7786 *ctx) {} +import "C" + +func f() { + var x1 *C.typedef_test7786 + var x2 *C.struct_test7786 + x1 = x2 + x2 = x1 + C.f7786(x1) + C.f7786(x2) + C.g7786(x1) + C.g7786(x2) + + var b1 *C.typedef_body7786 + var b2 *C.struct_body7786 + b1 = b2 + b2 = b1 + C.b7786(b1) + C.b7786(b2) + C.c7786(b1) + C.c7786(b2) + + var u1 *C.typedef_union7786 + var u2 *C.union_union7786 + u1 = u2 + u2 = u1 + C.u7786(u1) + C.u7786(u2) + C.v7786(u1) + C.v7786(u2) +} diff --git a/misc/cgo/test/issue8148.go b/misc/cgo/test/issue8148.go new file mode 100644 index 000000000..8e4190848 --- /dev/null +++ b/misc/cgo/test/issue8148.go @@ -0,0 +1,31 @@ +// Copyright 2014 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 8148. A typedef of an unnamed struct didn't work when used +// with an exported Go function. No runtime test; just make sure it +// compiles. + +package cgotest + +/* +typedef struct { int i; } T; + +int issue8148Callback(T*); + +static int get() { + T t; + t.i = 42; + return issue8148Callback(&t); +} +*/ +import "C" + +//export issue8148Callback +func issue8148Callback(t *C.T) C.int { + return t.i +} + +func Issue8148() int { + return int(C.get()) +} diff --git a/misc/cgo/test/issue8331.h b/misc/cgo/test/issue8331.h new file mode 100644 index 000000000..936ae9d5c --- /dev/null +++ b/misc/cgo/test/issue8331.h @@ -0,0 +1,7 @@ +// Copyright 2014 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. + +typedef struct { + int i; +} issue8331; diff --git a/misc/cgo/test/issue8331a.go b/misc/cgo/test/issue8331a.go new file mode 100644 index 000000000..7fa55be43 --- /dev/null +++ b/misc/cgo/test/issue8331a.go @@ -0,0 +1,15 @@ +// Copyright 2014 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 8331. A typedef of an unnamed struct is the same struct when +// #include'd twice. No runtime test; just make sure it compiles. + +package cgotest + +// #include "issue8331.h" +import "C" + +func issue8331a() C.issue8331 { + return issue8331Var +} diff --git a/misc/cgo/test/issue8331b.go b/misc/cgo/test/issue8331b.go new file mode 100644 index 000000000..d52aed63e --- /dev/null +++ b/misc/cgo/test/issue8331b.go @@ -0,0 +1,13 @@ +// Copyright 2014 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 8331. A typedef of an unnamed struct is the same struct when +// #include'd twice. No runtime test; just make sure it compiles. + +package cgotest + +// #include "issue8331.h" +import "C" + +var issue8331Var C.issue8331 diff --git a/misc/cgo/testcdefs/test.bash b/misc/cgo/testcdefs/test.bash index 1a14ad35c..01621a49a 100755 --- a/misc/cgo/testcdefs/test.bash +++ b/misc/cgo/testcdefs/test.bash @@ -12,5 +12,5 @@ done go build . && ./testcdefs EXIT=$? -rm -rf _obj main *.h +rm -rf _obj testcdefs *.h exit $EXIT diff --git a/misc/cgo/testso/cgoso_c.c b/misc/cgo/testso/cgoso_c.c index 27155c27f..7a38022b5 100644 --- a/misc/cgo/testso/cgoso_c.c +++ b/misc/cgo/testso/cgoso_c.c @@ -19,6 +19,11 @@ extern void goCallback(void); void setCallback(void *f) { (void)f; } #endif +// OpenBSD and older Darwin lack TLS support +#if !defined(__OpenBSD__) && !defined(__APPLE__) +__thread int tlsvar = 12345; +#endif + void sofunc(void) { goCallback(); diff --git a/misc/cgo/testso/cgoso_unix.go b/misc/cgo/testso/cgoso_unix.go new file mode 100644 index 000000000..7d5444cd1 --- /dev/null +++ b/misc/cgo/testso/cgoso_unix.go @@ -0,0 +1,20 @@ +// Copyright 2014 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. + +// +build dragonfly freebsd linux netbsd + +package cgosotest + +/* +extern int __thread tlsvar; +int *getTLS() { return &tlsvar; } +*/ +import "C" + +func init() { + if v := *C.getTLS(); v != 12345 { + println("got", v) + panic("BAD TLS value") + } +} diff --git a/misc/cgo/testtls/tls.go b/misc/cgo/testtls/tls.go index a9546a61c..8e9ee7003 100644 --- a/misc/cgo/testtls/tls.go +++ b/misc/cgo/testtls/tls.go @@ -15,14 +15,16 @@ import ( ) func testTLS(t *testing.T) { - var keyVal C.int = 1234 - runtime.LockOSThread() defer runtime.UnlockOSThread() - C.setTLS(C.int(keyVal)) - storedVal := C.getTLS() - if storedVal != keyVal { - t.Fatalf("stored %d want %d", storedVal, keyVal) + if val := C.getTLS(); val != 0 { + t.Fatalf("at start, C.getTLS() = %#x, want 0", val) + } + + const keyVal = 0x1234 + C.setTLS(keyVal) + if val := C.getTLS(); val != keyVal { + t.Fatalf("at end, C.getTLS() = %#x, want %#x", val, keyVal) } } |