mirror of
https://github.com/golang/go
synced 2024-11-26 01:57:56 -07:00
[dev.boringcrypto] all: merge master into dev.boringcrypto
Change-Id: I29cf70cab6b4c28891dce2a3ccf18b690ff568a0
This commit is contained in:
commit
324f8365be
@ -63,7 +63,7 @@ func expect(t *testing.T, file string, errors []*regexp.Regexp) {
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
dst := filepath.Join(dir, strings.TrimSuffix(file, ".go"))
|
||||
cmd := exec.Command("go", "build", "-gcflags=-L", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted
|
||||
cmd := exec.Command("go", "build", "-gcflags=-L -e", "-o="+dst, path(file)) // TODO(gri) no need for -gcflags=-L if go tool is adjusted
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err == nil {
|
||||
t.Errorf("expected cgo to fail but it succeeded")
|
||||
@ -107,21 +107,10 @@ func TestReportsTypeErrors(t *testing.T) {
|
||||
for _, file := range []string{
|
||||
"err1.go",
|
||||
"err2.go",
|
||||
"err3.go",
|
||||
"issue7757.go",
|
||||
"issue8442.go",
|
||||
"issue11097a.go",
|
||||
"issue11097b.go",
|
||||
"issue13129.go",
|
||||
"issue13423.go",
|
||||
"issue13467.go",
|
||||
"issue13635.go",
|
||||
"issue13830.go",
|
||||
"issue16116.go",
|
||||
"issue16591.go",
|
||||
"issue18452.go",
|
||||
"issue18889.go",
|
||||
"issue26745.go",
|
||||
"issue28721.go",
|
||||
} {
|
||||
check(t, file)
|
||||
|
@ -7,21 +7,25 @@
|
||||
package errorstest
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var tmp = flag.String("tmp", "", "use `dir` for temporary files and do not clean up")
|
||||
|
||||
// ptrTest is the tests without the boilerplate.
|
||||
type ptrTest struct {
|
||||
name string // for reporting
|
||||
c string // the cgo comment
|
||||
c1 string // cgo comment forced into non-export cgo file
|
||||
imports []string // a list of imports
|
||||
support string // supporting functions
|
||||
body string // the body of the main function
|
||||
@ -39,253 +43,248 @@ var ptrTests = []ptrTest{
|
||||
{
|
||||
// Passing a pointer to a struct that contains a Go pointer.
|
||||
name: "ptr1",
|
||||
c: `typedef struct s { int *p; } s; void f(s *ps) {}`,
|
||||
body: `C.f(&C.s{new(C.int)})`,
|
||||
c: `typedef struct s1 { int *p; } s1; void f1(s1 *ps) {}`,
|
||||
body: `C.f1(&C.s1{new(C.int)})`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Passing a pointer to a struct that contains a Go pointer.
|
||||
name: "ptr2",
|
||||
c: `typedef struct s { int *p; } s; void f(s *ps) {}`,
|
||||
body: `p := &C.s{new(C.int)}; C.f(p)`,
|
||||
c: `typedef struct s2 { int *p; } s2; void f2(s2 *ps) {}`,
|
||||
body: `p := &C.s2{new(C.int)}; C.f2(p)`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Passing a pointer to an int field of a Go struct
|
||||
// that (irrelevantly) contains a Go pointer.
|
||||
name: "ok1",
|
||||
c: `struct s { int i; int *p; }; void f(int *p) {}`,
|
||||
body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.i)`,
|
||||
c: `struct s3 { int i; int *p; }; void f3(int *p) {}`,
|
||||
body: `p := &C.struct_s3{i: 0, p: new(C.int)}; C.f3(&p.i)`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Passing a pointer to a pointer field of a Go struct.
|
||||
name: "ptr-field",
|
||||
c: `struct s { int i; int *p; }; void f(int **p) {}`,
|
||||
body: `p := &C.struct_s{i: 0, p: new(C.int)}; C.f(&p.p)`,
|
||||
name: "ptrfield",
|
||||
c: `struct s4 { int i; int *p; }; void f4(int **p) {}`,
|
||||
body: `p := &C.struct_s4{i: 0, p: new(C.int)}; C.f4(&p.p)`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Passing a pointer to a pointer field of a Go
|
||||
// struct, where the field does not contain a Go
|
||||
// pointer, but another field (irrelevantly) does.
|
||||
name: "ptr-field-ok",
|
||||
c: `struct s { int *p1; int *p2; }; void f(int **p) {}`,
|
||||
body: `p := &C.struct_s{p1: nil, p2: new(C.int)}; C.f(&p.p1)`,
|
||||
name: "ptrfieldok",
|
||||
c: `struct s5 { int *p1; int *p2; }; void f5(int **p) {}`,
|
||||
body: `p := &C.struct_s5{p1: nil, p2: new(C.int)}; C.f5(&p.p1)`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Passing the address of a slice with no Go pointers.
|
||||
name: "slice-ok-1",
|
||||
c: `void f(void **p) {}`,
|
||||
name: "sliceok1",
|
||||
c: `void f6(void **p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
body: `s := []unsafe.Pointer{nil}; C.f(&s[0])`,
|
||||
body: `s := []unsafe.Pointer{nil}; C.f6(&s[0])`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Passing the address of a slice with a Go pointer.
|
||||
name: "slice-ptr-1",
|
||||
c: `void f(void **p) {}`,
|
||||
name: "sliceptr1",
|
||||
c: `void f7(void **p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
body: `i := 0; s := []unsafe.Pointer{unsafe.Pointer(&i)}; C.f(&s[0])`,
|
||||
body: `i := 0; s := []unsafe.Pointer{unsafe.Pointer(&i)}; C.f7(&s[0])`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Passing the address of a slice with a Go pointer,
|
||||
// where we are passing the address of an element that
|
||||
// is not a Go pointer.
|
||||
name: "slice-ptr-2",
|
||||
c: `void f(void **p) {}`,
|
||||
name: "sliceptr2",
|
||||
c: `void f8(void **p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
body: `i := 0; s := []unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f(&s[0])`,
|
||||
body: `i := 0; s := []unsafe.Pointer{nil, unsafe.Pointer(&i)}; C.f8(&s[0])`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Passing the address of a slice that is an element
|
||||
// in a struct only looks at the slice.
|
||||
name: "slice-ok-2",
|
||||
c: `void f(void **p) {}`,
|
||||
name: "sliceok2",
|
||||
c: `void f9(void **p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
support: `type S struct { p *int; s []unsafe.Pointer }`,
|
||||
body: `i := 0; p := &S{p:&i, s:[]unsafe.Pointer{nil}}; C.f(&p.s[0])`,
|
||||
support: `type S9 struct { p *int; s []unsafe.Pointer }`,
|
||||
body: `i := 0; p := &S9{p:&i, s:[]unsafe.Pointer{nil}}; C.f9(&p.s[0])`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Passing the address of a slice of an array that is
|
||||
// an element in a struct, with a type conversion.
|
||||
name: "slice-ok-3",
|
||||
c: `void f(void* p) {}`,
|
||||
name: "sliceok3",
|
||||
c: `void f10(void* p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
support: `type S struct { p *int; a [4]byte }`,
|
||||
body: `i := 0; p := &S{p:&i}; s := p.a[:]; C.f(unsafe.Pointer(&s[0]))`,
|
||||
support: `type S10 struct { p *int; a [4]byte }`,
|
||||
body: `i := 0; p := &S10{p:&i}; s := p.a[:]; C.f10(unsafe.Pointer(&s[0]))`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Passing the address of a slice of an array that is
|
||||
// an element in a struct, with a type conversion.
|
||||
name: "slice-ok-4",
|
||||
c: `typedef void* PV; void f(PV p) {}`,
|
||||
name: "sliceok4",
|
||||
c: `typedef void* PV11; void f11(PV11 p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
support: `type S struct { p *int; a [4]byte }`,
|
||||
body: `i := 0; p := &S{p:&i}; C.f(C.PV(unsafe.Pointer(&p.a[0])))`,
|
||||
support: `type S11 struct { p *int; a [4]byte }`,
|
||||
body: `i := 0; p := &S11{p:&i}; C.f11(C.PV11(unsafe.Pointer(&p.a[0])))`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Passing the address of a static variable with no
|
||||
// pointers doesn't matter.
|
||||
name: "varok",
|
||||
c: `void f(char** parg) {}`,
|
||||
support: `var hello = [...]C.char{'h', 'e', 'l', 'l', 'o'}`,
|
||||
body: `parg := [1]*C.char{&hello[0]}; C.f(&parg[0])`,
|
||||
c: `void f12(char** parg) {}`,
|
||||
support: `var hello12 = [...]C.char{'h', 'e', 'l', 'l', 'o'}`,
|
||||
body: `parg := [1]*C.char{&hello12[0]}; C.f12(&parg[0])`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Passing the address of a static variable with
|
||||
// pointers does matter.
|
||||
name: "var",
|
||||
c: `void f(char*** parg) {}`,
|
||||
support: `var hello = [...]*C.char{new(C.char)}`,
|
||||
body: `parg := [1]**C.char{&hello[0]}; C.f(&parg[0])`,
|
||||
name: "var1",
|
||||
c: `void f13(char*** parg) {}`,
|
||||
support: `var hello13 = [...]*C.char{new(C.char)}`,
|
||||
body: `parg := [1]**C.char{&hello13[0]}; C.f13(&parg[0])`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Storing a Go pointer into C memory should fail.
|
||||
name: "barrier",
|
||||
c: `#include <stdlib.h>
|
||||
char **f1() { return malloc(sizeof(char*)); }
|
||||
void f2(char **p) {}`,
|
||||
body: `p := C.f1(); *p = new(C.char); C.f2(p)`,
|
||||
char **f14a() { return malloc(sizeof(char*)); }
|
||||
void f14b(char **p) {}`,
|
||||
body: `p := C.f14a(); *p = new(C.char); C.f14b(p)`,
|
||||
fail: true,
|
||||
expensive: true,
|
||||
},
|
||||
{
|
||||
// Storing a Go pointer into C memory by assigning a
|
||||
// large value should fail.
|
||||
name: "barrier-struct",
|
||||
name: "barrierstruct",
|
||||
c: `#include <stdlib.h>
|
||||
struct s { char *a[10]; };
|
||||
struct s *f1() { return malloc(sizeof(struct s)); }
|
||||
void f2(struct s *p) {}`,
|
||||
body: `p := C.f1(); p.a = [10]*C.char{new(C.char)}; C.f2(p)`,
|
||||
struct s15 { char *a[10]; };
|
||||
struct s15 *f15() { return malloc(sizeof(struct s15)); }
|
||||
void f15b(struct s15 *p) {}`,
|
||||
body: `p := C.f15(); p.a = [10]*C.char{new(C.char)}; C.f15b(p)`,
|
||||
fail: true,
|
||||
expensive: true,
|
||||
},
|
||||
{
|
||||
// Storing a Go pointer into C memory using a slice
|
||||
// copy should fail.
|
||||
name: "barrier-slice",
|
||||
name: "barrierslice",
|
||||
c: `#include <stdlib.h>
|
||||
struct s { char *a[10]; };
|
||||
struct s *f1() { return malloc(sizeof(struct s)); }
|
||||
void f2(struct s *p) {}`,
|
||||
body: `p := C.f1(); copy(p.a[:], []*C.char{new(C.char)}); C.f2(p)`,
|
||||
struct s16 { char *a[10]; };
|
||||
struct s16 *f16() { return malloc(sizeof(struct s16)); }
|
||||
void f16b(struct s16 *p) {}`,
|
||||
body: `p := C.f16(); copy(p.a[:], []*C.char{new(C.char)}); C.f16b(p)`,
|
||||
fail: true,
|
||||
expensive: true,
|
||||
},
|
||||
{
|
||||
// A very large value uses a GC program, which is a
|
||||
// different code path.
|
||||
name: "barrier-gcprog-array",
|
||||
name: "barriergcprogarray",
|
||||
c: `#include <stdlib.h>
|
||||
struct s { char *a[32769]; };
|
||||
struct s *f1() { return malloc(sizeof(struct s)); }
|
||||
void f2(struct s *p) {}`,
|
||||
body: `p := C.f1(); p.a = [32769]*C.char{new(C.char)}; C.f2(p)`,
|
||||
struct s17 { char *a[32769]; };
|
||||
struct s17 *f17() { return malloc(sizeof(struct s17)); }
|
||||
void f17b(struct s17 *p) {}`,
|
||||
body: `p := C.f17(); p.a = [32769]*C.char{new(C.char)}; C.f17b(p)`,
|
||||
fail: true,
|
||||
expensive: true,
|
||||
},
|
||||
{
|
||||
// Similar case, with a source on the heap.
|
||||
name: "barrier-gcprog-array-heap",
|
||||
name: "barriergcprogarrayheap",
|
||||
c: `#include <stdlib.h>
|
||||
struct s { char *a[32769]; };
|
||||
struct s *f1() { return malloc(sizeof(struct s)); }
|
||||
void f2(struct s *p) {}
|
||||
void f3(void *p) {}`,
|
||||
struct s18 { char *a[32769]; };
|
||||
struct s18 *f18() { return malloc(sizeof(struct s18)); }
|
||||
void f18b(struct s18 *p) {}
|
||||
void f18c(void *p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
body: `p := C.f1(); n := &[32769]*C.char{new(C.char)}; p.a = *n; C.f2(p); n[0] = nil; C.f3(unsafe.Pointer(n))`,
|
||||
body: `p := C.f18(); n := &[32769]*C.char{new(C.char)}; p.a = *n; C.f18b(p); n[0] = nil; C.f18c(unsafe.Pointer(n))`,
|
||||
fail: true,
|
||||
expensive: true,
|
||||
},
|
||||
{
|
||||
// A GC program with a struct.
|
||||
name: "barrier-gcprog-struct",
|
||||
name: "barriergcprogstruct",
|
||||
c: `#include <stdlib.h>
|
||||
struct s { char *a[32769]; };
|
||||
struct s2 { struct s f; };
|
||||
struct s2 *f1() { return malloc(sizeof(struct s2)); }
|
||||
void f2(struct s2 *p) {}`,
|
||||
body: `p := C.f1(); p.f = C.struct_s{[32769]*C.char{new(C.char)}}; C.f2(p)`,
|
||||
struct s19a { char *a[32769]; };
|
||||
struct s19b { struct s19a f; };
|
||||
struct s19b *f19() { return malloc(sizeof(struct s19b)); }
|
||||
void f19b(struct s19b *p) {}`,
|
||||
body: `p := C.f19(); p.f = C.struct_s19a{[32769]*C.char{new(C.char)}}; C.f19b(p)`,
|
||||
fail: true,
|
||||
expensive: true,
|
||||
},
|
||||
{
|
||||
// Similar case, with a source on the heap.
|
||||
name: "barrier-gcprog-struct-heap",
|
||||
name: "barriergcprogstructheap",
|
||||
c: `#include <stdlib.h>
|
||||
struct s { char *a[32769]; };
|
||||
struct s2 { struct s f; };
|
||||
struct s2 *f1() { return malloc(sizeof(struct s2)); }
|
||||
void f2(struct s2 *p) {}
|
||||
void f3(void *p) {}`,
|
||||
struct s20a { char *a[32769]; };
|
||||
struct s20b { struct s20a f; };
|
||||
struct s20b *f20() { return malloc(sizeof(struct s20b)); }
|
||||
void f20b(struct s20b *p) {}
|
||||
void f20c(void *p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
body: `p := C.f1(); n := &C.struct_s{[32769]*C.char{new(C.char)}}; p.f = *n; C.f2(p); n.a[0] = nil; C.f3(unsafe.Pointer(n))`,
|
||||
body: `p := C.f20(); n := &C.struct_s20a{[32769]*C.char{new(C.char)}}; p.f = *n; C.f20b(p); n.a[0] = nil; C.f20c(unsafe.Pointer(n))`,
|
||||
fail: true,
|
||||
expensive: true,
|
||||
},
|
||||
{
|
||||
// Exported functions may not return Go pointers.
|
||||
name: "export1",
|
||||
c: `extern unsigned char *GoFn();`,
|
||||
support: `//export GoFn
|
||||
func GoFn() *byte { return new(byte) }`,
|
||||
body: `C.GoFn()`,
|
||||
c: `extern unsigned char *GoFn21();`,
|
||||
support: `//export GoFn21
|
||||
func GoFn21() *byte { return new(byte) }`,
|
||||
body: `C.GoFn21()`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Returning a C pointer is fine.
|
||||
name: "exportok",
|
||||
c: `#include <stdlib.h>
|
||||
extern unsigned char *GoFn();`,
|
||||
support: `//export GoFn
|
||||
func GoFn() *byte { return (*byte)(C.malloc(1)) }`,
|
||||
body: `C.GoFn()`,
|
||||
extern unsigned char *GoFn22();`,
|
||||
support: `//export GoFn22
|
||||
func GoFn22() *byte { return (*byte)(C.malloc(1)) }`,
|
||||
body: `C.GoFn22()`,
|
||||
},
|
||||
{
|
||||
// Passing a Go string is fine.
|
||||
name: "pass-string",
|
||||
name: "passstring",
|
||||
c: `#include <stddef.h>
|
||||
typedef struct { const char *p; ptrdiff_t n; } gostring;
|
||||
gostring f(gostring s) { return s; }`,
|
||||
typedef struct { const char *p; ptrdiff_t n; } gostring23;
|
||||
gostring23 f23(gostring23 s) { return s; }`,
|
||||
imports: []string{"unsafe"},
|
||||
body: `s := "a"; r := C.f(*(*C.gostring)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`,
|
||||
body: `s := "a"; r := C.f23(*(*C.gostring23)(unsafe.Pointer(&s))); if *(*string)(unsafe.Pointer(&r)) != s { panic(r) }`,
|
||||
},
|
||||
{
|
||||
// Passing a slice of Go strings fails.
|
||||
name: "pass-string-slice",
|
||||
c: `void f(void *p) {}`,
|
||||
name: "passstringslice",
|
||||
c: `void f24(void *p) {}`,
|
||||
imports: []string{"strings", "unsafe"},
|
||||
support: `type S struct { a [1]string }`,
|
||||
body: `s := S{a:[1]string{strings.Repeat("a", 2)}}; C.f(unsafe.Pointer(&s.a[0]))`,
|
||||
support: `type S24 struct { a [1]string }`,
|
||||
body: `s := S24{a:[1]string{strings.Repeat("a", 2)}}; C.f24(unsafe.Pointer(&s.a[0]))`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Exported functions may not return strings.
|
||||
name: "ret-string",
|
||||
c: `extern void f();`,
|
||||
name: "retstring",
|
||||
c: `extern void f25();`,
|
||||
imports: []string{"strings"},
|
||||
support: `//export GoStr
|
||||
func GoStr() string { return strings.Repeat("a", 2) }`,
|
||||
body: `C.f()`,
|
||||
extra: []extra{
|
||||
{
|
||||
"call.c",
|
||||
`#include <stddef.h>
|
||||
typedef struct { const char *p; ptrdiff_t n; } gostring;
|
||||
extern gostring GoStr();
|
||||
void f() { GoStr(); }`,
|
||||
},
|
||||
},
|
||||
support: `//export GoStr25
|
||||
func GoStr25() string { return strings.Repeat("a", 2) }`,
|
||||
body: `C.f25()`,
|
||||
c1: `#include <stddef.h>
|
||||
typedef struct { const char *p; ptrdiff_t n; } gostring25;
|
||||
extern gostring25 GoStr25();
|
||||
void f25() { GoStr25(); }`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
@ -296,37 +295,37 @@ var ptrTests = []ptrTest{
|
||||
// that is, we are testing something that is not unsafe.
|
||||
name: "ptrdata1",
|
||||
c: `#include <stdlib.h>
|
||||
void f(void* p) {}`,
|
||||
void f26(void* p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
support: `type S struct { p *int; a [8*8]byte; u uintptr }`,
|
||||
body: `i := 0; p := &S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f(unsafe.Pointer(q))`,
|
||||
support: `type S26 struct { p *int; a [8*8]byte; u uintptr }`,
|
||||
body: `i := 0; p := &S26{u:uintptr(unsafe.Pointer(&i))}; q := (*S26)(C.malloc(C.size_t(unsafe.Sizeof(*p)))); *q = *p; C.f26(unsafe.Pointer(q))`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Like ptrdata1, but with a type that uses a GC program.
|
||||
name: "ptrdata2",
|
||||
c: `#include <stdlib.h>
|
||||
void f(void* p) {}`,
|
||||
void f27(void* p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
support: `type S struct { p *int; a [32769*8]byte; q *int; u uintptr }`,
|
||||
body: `i := 0; p := S{u:uintptr(unsafe.Pointer(&i))}; q := (*S)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f(unsafe.Pointer(q))`,
|
||||
support: `type S27 struct { p *int; a [32769*8]byte; q *int; u uintptr }`,
|
||||
body: `i := 0; p := S27{u:uintptr(unsafe.Pointer(&i))}; q := (*S27)(C.malloc(C.size_t(unsafe.Sizeof(p)))); *q = p; C.f27(unsafe.Pointer(q))`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Check deferred pointers when they are used, not
|
||||
// when the defer statement is run.
|
||||
name: "defer",
|
||||
c: `typedef struct s { int *p; } s; void f(s *ps) {}`,
|
||||
body: `p := &C.s{}; defer C.f(p); p.p = new(C.int)`,
|
||||
name: "defer1",
|
||||
c: `typedef struct s28 { int *p; } s28; void f28(s28 *ps) {}`,
|
||||
body: `p := &C.s28{}; defer C.f28(p); p.p = new(C.int)`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
// Check a pointer to a union if the union has any
|
||||
// pointer fields.
|
||||
name: "union1",
|
||||
c: `typedef union { char **p; unsigned long i; } u; void f(u *pu) {}`,
|
||||
c: `typedef union { char **p; unsigned long i; } u29; void f29(u29 *pu) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
body: `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
|
||||
body: `var b C.char; p := &b; C.f29((*C.u29)(unsafe.Pointer(&p)))`,
|
||||
fail: true,
|
||||
},
|
||||
{
|
||||
@ -336,55 +335,55 @@ var ptrTests = []ptrTest{
|
||||
// integer that happens to have the same
|
||||
// representation as a pointer.
|
||||
name: "union2",
|
||||
c: `typedef union { unsigned long i; } u; void f(u *pu) {}`,
|
||||
c: `typedef union { unsigned long i; } u39; void f39(u39 *pu) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
body: `var b C.char; p := &b; C.f((*C.u)(unsafe.Pointer(&p)))`,
|
||||
body: `var b C.char; p := &b; C.f39((*C.u39)(unsafe.Pointer(&p)))`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Test preemption while entering a cgo call. Issue #21306.
|
||||
name: "preempt-during-call",
|
||||
c: `void f() {}`,
|
||||
name: "preemptduringcall",
|
||||
c: `void f30() {}`,
|
||||
imports: []string{"runtime", "sync"},
|
||||
body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
|
||||
body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f30(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Test poller deadline with cgocheck=2. Issue #23435.
|
||||
name: "deadline",
|
||||
c: `#define US 10`,
|
||||
c: `#define US31 10`,
|
||||
imports: []string{"os", "time"},
|
||||
body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US * time.Microsecond))`,
|
||||
body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US31 * time.Microsecond))`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Test for double evaluation of channel receive.
|
||||
name: "chan-recv",
|
||||
c: `void f(char** p) {}`,
|
||||
name: "chanrecv",
|
||||
c: `void f32(char** p) {}`,
|
||||
imports: []string{"time"},
|
||||
body: `c := make(chan []*C.char, 2); c <- make([]*C.char, 1); go func() { time.Sleep(10 * time.Second); panic("received twice from chan") }(); C.f(&(<-c)[0]);`,
|
||||
body: `c := make(chan []*C.char, 2); c <- make([]*C.char, 1); go func() { time.Sleep(10 * time.Second); panic("received twice from chan") }(); C.f32(&(<-c)[0]);`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Test that converting the address of a struct field
|
||||
// to unsafe.Pointer still just checks that field.
|
||||
// Issue #25941.
|
||||
name: "struct-field",
|
||||
c: `void f(void* p) {}`,
|
||||
name: "structfield",
|
||||
c: `void f33(void* p) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
support: `type S struct { p *int; a [8]byte; u uintptr }`,
|
||||
body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a))`,
|
||||
support: `type S33 struct { p *int; a [8]byte; u uintptr }`,
|
||||
body: `s := &S33{p: new(int)}; C.f33(unsafe.Pointer(&s.a))`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Test that converting multiple struct field
|
||||
// addresses to unsafe.Pointer still just checks those
|
||||
// fields. Issue #25941.
|
||||
name: "struct-field-2",
|
||||
c: `void f(void* p, int r, void* s) {}`,
|
||||
name: "structfield2",
|
||||
c: `void f34(void* p, int r, void* s) {}`,
|
||||
imports: []string{"unsafe"},
|
||||
support: `type S struct { a [8]byte; p *int; b int64; }`,
|
||||
body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a), 32, unsafe.Pointer(&s.b))`,
|
||||
support: `type S34 struct { a [8]byte; p *int; b int64; }`,
|
||||
body: `s := &S34{p: new(int)}; C.f34(unsafe.Pointer(&s.a), 32, unsafe.Pointer(&s.b))`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
@ -392,18 +391,18 @@ var ptrTests = []ptrTest{
|
||||
// evaluated when a deferred function is deferred, not
|
||||
// when it is run.
|
||||
name: "defer2",
|
||||
c: `void f(char **pc) {}`,
|
||||
support: `type S1 struct { s []*C.char }; type S2 struct { ps *S1 }`,
|
||||
body: `p := &S2{&S1{[]*C.char{nil}}}; defer C.f(&p.ps.s[0]); p.ps = nil`,
|
||||
c: `void f35(char **pc) {}`,
|
||||
support: `type S35a struct { s []*C.char }; type S35b struct { ps *S35a }`,
|
||||
body: `p := &S35b{&S35a{[]*C.char{nil}}}; defer C.f35(&p.ps.s[0]); p.ps = nil`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
// Test that indexing into a function call still
|
||||
// examines only the slice being indexed.
|
||||
name: "buffer",
|
||||
c: `void f(void *p) {}`,
|
||||
c: `void f36(void *p) {}`,
|
||||
imports: []string{"bytes", "unsafe"},
|
||||
body: `var b bytes.Buffer; b.WriteString("a"); C.f(unsafe.Pointer(&b.Bytes()[0]))`,
|
||||
body: `var b bytes.Buffer; b.WriteString("a"); C.f36(unsafe.Pointer(&b.Bytes()[0]))`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
@ -411,8 +410,8 @@ var ptrTests = []ptrTest{
|
||||
name: "finalizer",
|
||||
c: `// Nothing to declare.`,
|
||||
imports: []string{"os"},
|
||||
support: `func open() { os.Open(os.Args[0]) }; var G [][]byte`,
|
||||
body: `for i := 0; i < 10000; i++ { G = append(G, make([]byte, 4096)); if i % 100 == 0 { G = nil; open() } }`,
|
||||
support: `func open37() { os.Open(os.Args[0]) }; var G37 [][]byte`,
|
||||
body: `for i := 0; i < 10000; i++ { G37 = append(G37, make([]byte, 4096)); if i % 100 == 0 { G37 = nil; open37() } }`,
|
||||
fail: false,
|
||||
},
|
||||
{
|
||||
@ -420,103 +419,155 @@ var ptrTests = []ptrTest{
|
||||
name: "structof",
|
||||
c: `// Nothing to declare.`,
|
||||
imports: []string{"reflect"},
|
||||
support: `type MyInt int; func (i MyInt) Get() int { return int(i) }; type Getter interface { Get() int }`,
|
||||
body: `t := reflect.StructOf([]reflect.StructField{{Name: "MyInt", Type: reflect.TypeOf(MyInt(0)), Anonymous: true}}); v := reflect.New(t).Elem(); v.Interface().(Getter).Get()`,
|
||||
support: `type MyInt38 int; func (i MyInt38) Get() int { return int(i) }; type Getter38 interface { Get() int }`,
|
||||
body: `t := reflect.StructOf([]reflect.StructField{{Name: "MyInt38", Type: reflect.TypeOf(MyInt38(0)), Anonymous: true}}); v := reflect.New(t).Elem(); v.Interface().(Getter38).Get()`,
|
||||
fail: false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestPointerChecks(t *testing.T) {
|
||||
dir, exe := buildPtrTests(t)
|
||||
|
||||
// We (TestPointerChecks) return before the parallel subtest functions do,
|
||||
// so we can't just defer os.RemoveAll(dir). Instead we have to wait for
|
||||
// the parallel subtests to finish. This code looks racy but is not:
|
||||
// the add +1 run in serial before testOne blocks. The -1 run in parallel
|
||||
// after testOne finishes.
|
||||
var pending int32
|
||||
for _, pt := range ptrTests {
|
||||
pt := pt
|
||||
t.Run(pt.name, func(t *testing.T) {
|
||||
testOne(t, pt)
|
||||
atomic.AddInt32(&pending, +1)
|
||||
defer func() {
|
||||
if atomic.AddInt32(&pending, -1) == 0 {
|
||||
println("removing", dir)
|
||||
os.RemoveAll(dir)
|
||||
}
|
||||
}()
|
||||
testOne(t, pt, exe)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testOne(t *testing.T, pt ptrTest) {
|
||||
t.Parallel()
|
||||
|
||||
gopath, err := ioutil.TempDir("", filepath.Base(t.Name()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
func buildPtrTests(t *testing.T) (dir, exe string) {
|
||||
var gopath string
|
||||
if *tmp != "" {
|
||||
gopath = *tmp
|
||||
dir = ""
|
||||
} else {
|
||||
d, err := ioutil.TempDir("", filepath.Base(t.Name()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
dir = d
|
||||
gopath = d
|
||||
}
|
||||
defer os.RemoveAll(gopath)
|
||||
|
||||
src := filepath.Join(gopath, "src", "ptrtest")
|
||||
if err := os.MkdirAll(src, 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
name := filepath.Join(src, fmt.Sprintf("%s.go", filepath.Base(t.Name())))
|
||||
f, err := os.Create(name)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Prepare two cgo inputs: one for standard cgo and one for //export cgo.
|
||||
// (The latter cannot have C definitions, only declarations.)
|
||||
var cgo1, cgo2 bytes.Buffer
|
||||
fmt.Fprintf(&cgo1, "package main\n\n/*\n")
|
||||
fmt.Fprintf(&cgo2, "package main\n\n/*\n")
|
||||
|
||||
b := bufio.NewWriter(f)
|
||||
fmt.Fprintln(b, `package main`)
|
||||
fmt.Fprintln(b)
|
||||
fmt.Fprintln(b, `/*`)
|
||||
fmt.Fprintln(b, pt.c)
|
||||
fmt.Fprintln(b, `*/`)
|
||||
fmt.Fprintln(b, `import "C"`)
|
||||
fmt.Fprintln(b)
|
||||
for _, imp := range pt.imports {
|
||||
fmt.Fprintln(b, `import "`+imp+`"`)
|
||||
// C code
|
||||
for _, pt := range ptrTests {
|
||||
cgo := &cgo1
|
||||
if strings.Contains(pt.support, "//export") {
|
||||
cgo = &cgo2
|
||||
}
|
||||
fmt.Fprintf(cgo, "%s\n", pt.c)
|
||||
fmt.Fprintf(&cgo1, "%s\n", pt.c1)
|
||||
}
|
||||
if len(pt.imports) > 0 {
|
||||
fmt.Fprintln(b)
|
||||
}
|
||||
if len(pt.support) > 0 {
|
||||
fmt.Fprintln(b, pt.support)
|
||||
fmt.Fprintln(b)
|
||||
}
|
||||
fmt.Fprintln(b, `func main() {`)
|
||||
fmt.Fprintln(b, pt.body)
|
||||
fmt.Fprintln(b, `}`)
|
||||
fmt.Fprintf(&cgo1, "*/\nimport \"C\"\n\n")
|
||||
fmt.Fprintf(&cgo2, "*/\nimport \"C\"\n\n")
|
||||
|
||||
if err := b.Flush(); err != nil {
|
||||
t.Fatalf("flushing %s: %v", name, err)
|
||||
}
|
||||
if err := f.Close(); err != nil {
|
||||
t.Fatalf("closing %s: %v", name, err)
|
||||
}
|
||||
// Imports
|
||||
did1 := make(map[string]bool)
|
||||
did2 := make(map[string]bool)
|
||||
did1["os"] = true // for ptrTestMain
|
||||
fmt.Fprintf(&cgo1, "import \"os\"\n")
|
||||
|
||||
for _, e := range pt.extra {
|
||||
if err := ioutil.WriteFile(filepath.Join(src, e.name), []byte(e.contents), 0644); err != nil {
|
||||
t.Fatalf("writing %s: %v", e.name, err)
|
||||
for _, pt := range ptrTests {
|
||||
did := did1
|
||||
cgo := &cgo1
|
||||
if strings.Contains(pt.support, "//export") {
|
||||
did = did2
|
||||
cgo = &cgo2
|
||||
}
|
||||
for _, imp := range pt.imports {
|
||||
if !did[imp] {
|
||||
did[imp] = true
|
||||
fmt.Fprintf(cgo, "import %q\n", imp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gomod := fmt.Sprintf("module %s\n", filepath.Base(src))
|
||||
if err := ioutil.WriteFile(filepath.Join(src, "go.mod"), []byte(gomod), 0666); err != nil {
|
||||
t.Fatalf("writing go.mod: %v", err)
|
||||
// Func support and bodies.
|
||||
for _, pt := range ptrTests {
|
||||
cgo := &cgo1
|
||||
if strings.Contains(pt.support, "//export") {
|
||||
cgo = &cgo2
|
||||
}
|
||||
fmt.Fprintf(cgo, "%s\nfunc %s() {\n%s\n}\n", pt.support, pt.name, pt.body)
|
||||
}
|
||||
|
||||
args := func(cmd *exec.Cmd) string {
|
||||
return strings.Join(cmd.Args, " ")
|
||||
// Func list and main dispatch.
|
||||
fmt.Fprintf(&cgo1, "var funcs = map[string]func() {\n")
|
||||
for _, pt := range ptrTests {
|
||||
fmt.Fprintf(&cgo1, "\t%q: %s,\n", pt.name, pt.name)
|
||||
}
|
||||
fmt.Fprintf(&cgo1, "}\n\n")
|
||||
fmt.Fprintf(&cgo1, "%s\n", ptrTestMain)
|
||||
|
||||
if err := ioutil.WriteFile(filepath.Join(src, "cgo1.go"), cgo1.Bytes(), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ioutil.WriteFile(filepath.Join(src, "cgo2.go"), cgo2.Bytes(), 0666); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("go", "build")
|
||||
cmd := exec.Command("go", "build", "-o", "ptrtest.exe")
|
||||
cmd.Dir = src
|
||||
cmd.Env = append(os.Environ(), "GOPATH="+gopath)
|
||||
buf, err := cmd.CombinedOutput()
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("%#q:\n%s", args(cmd), buf)
|
||||
t.Fatalf("failed to build: %v", err)
|
||||
t.Fatalf("go build: %v\n%s", err, out)
|
||||
}
|
||||
|
||||
exe := filepath.Join(src, filepath.Base(src))
|
||||
cmd = exec.Command(exe)
|
||||
cmd.Dir = src
|
||||
return dir, filepath.Join(src, "ptrtest.exe")
|
||||
}
|
||||
|
||||
const ptrTestMain = `
|
||||
func main() {
|
||||
for _, arg := range os.Args[1:] {
|
||||
f := funcs[arg]
|
||||
if f == nil {
|
||||
panic("missing func "+arg)
|
||||
}
|
||||
f()
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
func testOne(t *testing.T, pt ptrTest, exe string) {
|
||||
t.Parallel()
|
||||
|
||||
newcmd := func(cgocheck string) *exec.Cmd {
|
||||
cmd := exec.Command(exe, pt.name)
|
||||
cmd.Env = append(os.Environ(), "GODEBUG=cgocheck="+cgocheck)
|
||||
return cmd
|
||||
}
|
||||
|
||||
if pt.expensive {
|
||||
cmd.Env = cgocheckEnv("1")
|
||||
cmd := newcmd("1")
|
||||
buf, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("%#q:\n%s", args(cmd), buf)
|
||||
t.Logf("%s", buf)
|
||||
if pt.fail {
|
||||
t.Fatalf("test marked expensive, but failed when not expensive: %v", err)
|
||||
} else {
|
||||
@ -524,54 +575,45 @@ func testOne(t *testing.T, pt ptrTest) {
|
||||
}
|
||||
}
|
||||
|
||||
cmd = exec.Command(exe)
|
||||
cmd.Dir = src
|
||||
}
|
||||
|
||||
cmd := newcmd("")
|
||||
if pt.expensive {
|
||||
cmd.Env = cgocheckEnv("2")
|
||||
cmd = newcmd("2")
|
||||
}
|
||||
|
||||
buf, err = cmd.CombinedOutput()
|
||||
buf, err := cmd.CombinedOutput()
|
||||
if pt.fail {
|
||||
if err == nil {
|
||||
t.Logf("%#q:\n%s", args(cmd), buf)
|
||||
t.Logf("%s", buf)
|
||||
t.Fatalf("did not fail as expected")
|
||||
} else if !bytes.Contains(buf, []byte("Go pointer")) {
|
||||
t.Logf("%#q:\n%s", args(cmd), buf)
|
||||
t.Logf("%s", buf)
|
||||
t.Fatalf("did not print expected error (failed with %v)", err)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
t.Logf("%#q:\n%s", args(cmd), buf)
|
||||
t.Logf("%s", buf)
|
||||
t.Fatalf("failed unexpectedly: %v", err)
|
||||
}
|
||||
|
||||
if !pt.expensive {
|
||||
// Make sure it passes with the expensive checks.
|
||||
cmd := exec.Command(exe)
|
||||
cmd.Dir = src
|
||||
cmd.Env = cgocheckEnv("2")
|
||||
cmd := newcmd("2")
|
||||
buf, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("%#q:\n%s", args(cmd), buf)
|
||||
t.Logf("%s", buf)
|
||||
t.Fatalf("failed unexpectedly with expensive checks: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if pt.fail {
|
||||
cmd = exec.Command(exe)
|
||||
cmd.Dir = src
|
||||
cmd.Env = cgocheckEnv("0")
|
||||
cmd := newcmd("0")
|
||||
buf, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Logf("%#q:\n%s", args(cmd), buf)
|
||||
t.Logf("%s", buf)
|
||||
t.Fatalf("failed unexpectedly with GODEBUG=cgocheck=0: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cgocheckEnv(val string) []string {
|
||||
return append(os.Environ(), "GODEBUG=cgocheck="+val)
|
||||
}
|
||||
|
4
misc/cgo/errors/testdata/err1.go
vendored
4
misc/cgo/errors/testdata/err1.go
vendored
@ -10,6 +10,10 @@ package main
|
||||
void test() {
|
||||
xxx; // ERROR HERE
|
||||
}
|
||||
|
||||
// Issue 8442. Cgo output unhelpful error messages for
|
||||
// invalid C preambles.
|
||||
void issue8442foo(UNDEF*); // ERROR HERE
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
89
misc/cgo/errors/testdata/err2.go
vendored
89
misc/cgo/errors/testdata/err2.go
vendored
@ -4,10 +4,99 @@
|
||||
|
||||
package main
|
||||
|
||||
/*
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct foo foo_t;
|
||||
typedef struct bar bar_t;
|
||||
|
||||
foo_t *foop;
|
||||
|
||||
long double x = 0;
|
||||
|
||||
static int transform(int x) { return x; }
|
||||
|
||||
typedef void v;
|
||||
void F(v** p) {}
|
||||
|
||||
void fvi(void *p, int x) {}
|
||||
|
||||
void fppi(int** p) {}
|
||||
|
||||
int i;
|
||||
void fi(int i) {}
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func main() {
|
||||
s := ""
|
||||
_ = s
|
||||
C.malloc(s) // ERROR HERE
|
||||
|
||||
x := (*C.bar_t)(nil)
|
||||
C.foop = x // ERROR HERE
|
||||
|
||||
// issue 13129: used to output error about C.unsignedshort with CC=clang
|
||||
var x C.ushort
|
||||
x = int(0) // ERROR HERE: C\.ushort
|
||||
|
||||
// issue 13423
|
||||
_ = C.fopen() // ERROR HERE
|
||||
|
||||
// issue 13467
|
||||
var x rune = '✈'
|
||||
var _ rune = C.transform(x) // ERROR HERE: C\.int
|
||||
|
||||
// issue 13635: used to output error about C.unsignedchar.
|
||||
// This test tests all such types.
|
||||
var (
|
||||
_ C.uchar = "uc" // ERROR HERE: C\.uchar
|
||||
_ C.schar = "sc" // ERROR HERE: C\.schar
|
||||
_ C.ushort = "us" // ERROR HERE: C\.ushort
|
||||
_ C.uint = "ui" // ERROR HERE: C\.uint
|
||||
_ C.ulong = "ul" // ERROR HERE: C\.ulong
|
||||
_ C.longlong = "ll" // ERROR HERE: C\.longlong
|
||||
_ C.ulonglong = "ull" // ERROR HERE: C\.ulonglong
|
||||
_ C.complexfloat = "cf" // ERROR HERE: C\.complexfloat
|
||||
_ C.complexdouble = "cd" // ERROR HERE: C\.complexdouble
|
||||
)
|
||||
|
||||
// issue 13830
|
||||
// cgo converts C void* to Go unsafe.Pointer, so despite appearances C
|
||||
// void** is Go *unsafe.Pointer. This test verifies that we detect the
|
||||
// problem at build time.
|
||||
{
|
||||
type v [0]byte
|
||||
|
||||
f := func(p **v) {
|
||||
C.F((**C.v)(unsafe.Pointer(p))) // ERROR HERE
|
||||
}
|
||||
var p *v
|
||||
f(&p)
|
||||
}
|
||||
|
||||
// issue 16116
|
||||
_ = C.fvi(1) // ERROR HERE
|
||||
|
||||
// Issue 16591: Test that we detect an invalid call that was being
|
||||
// hidden by a type conversion inserted by cgo checking.
|
||||
{
|
||||
type x *C.int
|
||||
var p *x
|
||||
C.fppi(p) // ERROR HERE
|
||||
}
|
||||
|
||||
// issue 26745
|
||||
_ = func(i int) int {
|
||||
return C.i + 1 // ERROR HERE: :13
|
||||
}
|
||||
_ = func(i int) {
|
||||
C.fi(i) // ERROR HERE: :6
|
||||
}
|
||||
|
||||
C.fi = C.fi // ERROR HERE
|
||||
|
||||
}
|
||||
|
18
misc/cgo/errors/testdata/err3.go
vendored
18
misc/cgo/errors/testdata/err3.go
vendored
@ -1,18 +0,0 @@
|
||||
// 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
|
||||
}
|
14
misc/cgo/errors/testdata/issue13129.go
vendored
14
misc/cgo/errors/testdata/issue13129.go
vendored
@ -1,14 +0,0 @@
|
||||
// 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 13129: used to output error about C.unsignedshort with CC=clang
|
||||
|
||||
package main
|
||||
|
||||
import "C"
|
||||
|
||||
func main() {
|
||||
var x C.ushort
|
||||
x = int(0) // ERROR HERE: C\.ushort
|
||||
}
|
12
misc/cgo/errors/testdata/issue13423.go
vendored
12
misc/cgo/errors/testdata/issue13423.go
vendored
@ -1,12 +0,0 @@
|
||||
// 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.
|
||||
|
||||
package main
|
||||
|
||||
// #include <stdio.h>
|
||||
import "C"
|
||||
|
||||
func main() {
|
||||
_ = C.fopen() // ERROR HERE
|
||||
}
|
15
misc/cgo/errors/testdata/issue13467.go
vendored
15
misc/cgo/errors/testdata/issue13467.go
vendored
@ -1,15 +0,0 @@
|
||||
// Copyright 2017 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 p
|
||||
|
||||
/*
|
||||
static int transform(int x) { return x; }
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func F() {
|
||||
var x rune = '✈'
|
||||
var _ rune = C.transform(x) // ERROR HERE: C\.int
|
||||
}
|
24
misc/cgo/errors/testdata/issue13635.go
vendored
24
misc/cgo/errors/testdata/issue13635.go
vendored
@ -1,24 +0,0 @@
|
||||
// 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 13635: used to output error about C.unsignedchar.
|
||||
// This test tests all such types.
|
||||
|
||||
package pkg
|
||||
|
||||
import "C"
|
||||
|
||||
func main() {
|
||||
var (
|
||||
_ C.uchar = "uc" // ERROR HERE: C\.uchar
|
||||
_ C.schar = "sc" // ERROR HERE: C\.schar
|
||||
_ C.ushort = "us" // ERROR HERE: C\.ushort
|
||||
_ C.uint = "ui" // ERROR HERE: C\.uint
|
||||
_ C.ulong = "ul" // ERROR HERE: C\.ulong
|
||||
_ C.longlong = "ll" // ERROR HERE: C\.longlong
|
||||
_ C.ulonglong = "ull" // ERROR HERE: C\.ulonglong
|
||||
_ C.complexfloat = "cf" // ERROR HERE: C\.complexfloat
|
||||
_ C.complexdouble = "cd" // ERROR HERE: C\.complexdouble
|
||||
)
|
||||
}
|
26
misc/cgo/errors/testdata/issue13830.go
vendored
26
misc/cgo/errors/testdata/issue13830.go
vendored
@ -1,26 +0,0 @@
|
||||
// Copyright 2016 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.
|
||||
|
||||
// cgo converts C void* to Go unsafe.Pointer, so despite appearances C
|
||||
// void** is Go *unsafe.Pointer. This test verifies that we detect the
|
||||
// problem at build time.
|
||||
|
||||
package main
|
||||
|
||||
// typedef void v;
|
||||
// void F(v** p) {}
|
||||
import "C"
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type v [0]byte
|
||||
|
||||
func f(p **v) {
|
||||
C.F((**C.v)(unsafe.Pointer(p))) // ERROR HERE
|
||||
}
|
||||
|
||||
func main() {
|
||||
var p *v
|
||||
f(&p)
|
||||
}
|
12
misc/cgo/errors/testdata/issue16116.go
vendored
12
misc/cgo/errors/testdata/issue16116.go
vendored
@ -1,12 +0,0 @@
|
||||
// Copyright 2016 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
|
||||
|
||||
// void f(void *p, int x) {}
|
||||
import "C"
|
||||
|
||||
func main() {
|
||||
_ = C.f(1) // ERROR HERE
|
||||
}
|
17
misc/cgo/errors/testdata/issue16591.go
vendored
17
misc/cgo/errors/testdata/issue16591.go
vendored
@ -1,17 +0,0 @@
|
||||
// Copyright 2016 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 16591: Test that we detect an invalid call that was being
|
||||
// hidden by a type conversion inserted by cgo checking.
|
||||
|
||||
package p
|
||||
|
||||
// void f(int** p) { }
|
||||
import "C"
|
||||
|
||||
type x *C.int
|
||||
|
||||
func F(p *x) {
|
||||
C.f(p) // ERROR HERE
|
||||
}
|
17
misc/cgo/errors/testdata/issue26745.go
vendored
17
misc/cgo/errors/testdata/issue26745.go
vendored
@ -1,17 +0,0 @@
|
||||
// Copyright 2018 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
|
||||
|
||||
// int a;
|
||||
// void CF(int i) {}
|
||||
import "C"
|
||||
|
||||
func F1(i int) int {
|
||||
return C.a + 1 // ERROR HERE: :13
|
||||
}
|
||||
|
||||
func F2(i int) {
|
||||
C.CF(i) // ERROR HERE: :6
|
||||
}
|
14
misc/cgo/errors/testdata/issue7757.go
vendored
14
misc/cgo/errors/testdata/issue7757.go
vendored
@ -1,14 +0,0 @@
|
||||
// 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
|
||||
|
||||
/*
|
||||
void foo() {}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func main() {
|
||||
C.foo = C.foo // ERROR HERE
|
||||
}
|
17
misc/cgo/errors/testdata/issue8442.go
vendored
17
misc/cgo/errors/testdata/issue8442.go
vendored
@ -1,17 +0,0 @@
|
||||
// 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
|
||||
|
||||
// Issue 8442. Cgo output unhelpful error messages for
|
||||
// invalid C preambles.
|
||||
|
||||
/*
|
||||
void issue8442foo(UNDEF*); // ERROR HERE
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func main() {
|
||||
C.issue8442foo(nil)
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
// Copyright 2010 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 <stdio.h>
|
||||
|
||||
typedef unsigned char Uint8;
|
||||
typedef unsigned short Uint16;
|
||||
|
||||
typedef enum {
|
||||
MOD1 = 0x0000,
|
||||
MODX = 0x8000
|
||||
} SDLMod;
|
||||
|
||||
typedef enum {
|
||||
A = 1,
|
||||
B = 322,
|
||||
SDLK_LAST
|
||||
} SDLKey;
|
||||
|
||||
typedef struct SDL_keysym {
|
||||
Uint8 scancode;
|
||||
SDLKey sym;
|
||||
SDLMod mod;
|
||||
Uint16 unicode;
|
||||
} SDL_keysym;
|
||||
|
||||
typedef struct SDL_KeyboardEvent {
|
||||
Uint8 typ;
|
||||
Uint8 which;
|
||||
Uint8 state;
|
||||
SDL_keysym keysym;
|
||||
} SDL_KeyboardEvent;
|
||||
|
||||
void makeEvent(SDL_KeyboardEvent *event) {
|
||||
unsigned char *p;
|
||||
int i;
|
||||
|
||||
p = (unsigned char*)event;
|
||||
for (i=0; i<sizeof *event; i++) {
|
||||
p[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
int same(SDL_KeyboardEvent* e, Uint8 typ, Uint8 which, Uint8 state, Uint8 scan, SDLKey sym, SDLMod mod, Uint16 uni) {
|
||||
return e->typ == typ && e->which == which && e->state == state && e->keysym.scancode == scan && e->keysym.sym == sym && e->keysym.mod == mod && e->keysym.unicode == uni;
|
||||
}
|
||||
|
||||
void cTest(SDL_KeyboardEvent *event) {
|
||||
printf("C: %#x %#x %#x %#x %#x %#x %#x\n", event->typ, event->which, event->state,
|
||||
event->keysym.scancode, event->keysym.sym, event->keysym.mod, event->keysym.unicode);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testAlign(t *testing.T) {
|
||||
var evt C.SDL_KeyboardEvent
|
||||
C.makeEvent(&evt)
|
||||
if C.same(&evt, evt.typ, evt.which, evt.state, evt.keysym.scancode, evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) == 0 {
|
||||
t.Error("*** bad alignment")
|
||||
C.cTest(&evt)
|
||||
t.Errorf("Go: %#x %#x %#x %#x %#x %#x %#x\n",
|
||||
evt.typ, evt.which, evt.state, evt.keysym.scancode,
|
||||
evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode)
|
||||
t.Error(evt)
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// API Compatibility Checks for cgo
|
||||
|
||||
package cgotest
|
||||
|
||||
// #include <stdlib.h>
|
||||
//
|
||||
// // Test for issue 17723.
|
||||
// typedef char *cstring_pointer;
|
||||
// static void cstring_pointer_fun(cstring_pointer dummy) { }
|
||||
//
|
||||
// const char *api_hello = "hello!";
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func testAPI() {
|
||||
var cs *C.char
|
||||
cs = C.CString("hello")
|
||||
defer C.free(unsafe.Pointer(cs))
|
||||
var s string
|
||||
s = C.GoString((*C.char)(C.api_hello))
|
||||
s = C.GoStringN((*C.char)(C.api_hello), C.int(6))
|
||||
var b []byte
|
||||
b = C.GoBytes(unsafe.Pointer(C.api_hello), C.int(6))
|
||||
_, _ = s, b
|
||||
C.cstring_pointer_fun(nil)
|
||||
}
|
@ -1,181 +0,0 @@
|
||||
// Copyright 2010 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.
|
||||
|
||||
// Basic test cases for cgo.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define SHIFT(x, y) ((x)<<(y))
|
||||
#define KILO SHIFT(1, 10)
|
||||
#define UINT32VAL 0xc008427bU
|
||||
|
||||
enum E {
|
||||
Enum1 = 1,
|
||||
Enum2 = 2,
|
||||
};
|
||||
|
||||
typedef unsigned char cgo_uuid_t[20];
|
||||
|
||||
void uuid_generate(cgo_uuid_t x) {
|
||||
x[0] = 0;
|
||||
}
|
||||
|
||||
struct S {
|
||||
int x;
|
||||
};
|
||||
|
||||
const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
|
||||
|
||||
extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter);
|
||||
|
||||
enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; }
|
||||
|
||||
// issue 1222
|
||||
typedef union {
|
||||
long align;
|
||||
} xxpthread_mutex_t;
|
||||
|
||||
struct ibv_async_event {
|
||||
union {
|
||||
int x;
|
||||
} element;
|
||||
};
|
||||
|
||||
struct ibv_context {
|
||||
xxpthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
int add(int x, int y) {
|
||||
return x+y;
|
||||
};
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"runtime"
|
||||
"syscall"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const EINVAL = C.EINVAL /* test #define */
|
||||
|
||||
var KILO = C.KILO
|
||||
|
||||
func uuidgen() {
|
||||
var uuid C.cgo_uuid_t
|
||||
C.uuid_generate(&uuid[0])
|
||||
}
|
||||
|
||||
func Strtol(s string, base int) (int, error) {
|
||||
p := C.CString(s)
|
||||
n, err := C.strtol(p, nil, C.int(base))
|
||||
C.free(unsafe.Pointer(p))
|
||||
return int(n), err
|
||||
}
|
||||
|
||||
func Atol(s string) int {
|
||||
p := C.CString(s)
|
||||
n := C.atol(p)
|
||||
C.free(unsafe.Pointer(p))
|
||||
return int(n)
|
||||
}
|
||||
|
||||
func testConst(t *testing.T) {
|
||||
C.myConstFunc(nil, 0, nil)
|
||||
}
|
||||
|
||||
func testEnum(t *testing.T) {
|
||||
if C.Enum1 != 1 || C.Enum2 != 2 {
|
||||
t.Error("bad enum", C.Enum1, C.Enum2)
|
||||
}
|
||||
}
|
||||
|
||||
func testAtol(t *testing.T) {
|
||||
l := Atol("123")
|
||||
if l != 123 {
|
||||
t.Error("Atol 123: ", l)
|
||||
}
|
||||
}
|
||||
|
||||
func testErrno(t *testing.T) {
|
||||
p := C.CString("no-such-file")
|
||||
m := C.CString("r")
|
||||
f, err := C.fopen(p, m)
|
||||
C.free(unsafe.Pointer(p))
|
||||
C.free(unsafe.Pointer(m))
|
||||
if err == nil {
|
||||
C.fclose(f)
|
||||
t.Fatalf("C.fopen: should fail")
|
||||
}
|
||||
if err != syscall.ENOENT {
|
||||
t.Fatalf("C.fopen: unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testMultipleAssign(t *testing.T) {
|
||||
p := C.CString("234")
|
||||
n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10)
|
||||
if runtime.GOOS == "openbsd" {
|
||||
// Bug in OpenBSD strtol(3) - base > 36 succeeds.
|
||||
if (n != 0 && n != 239089) || m != 234 {
|
||||
t.Fatal("Strtol x2: ", n, m)
|
||||
}
|
||||
} else if n != 0 || m != 234 {
|
||||
t.Fatal("Strtol x2: ", n, m)
|
||||
}
|
||||
C.free(unsafe.Pointer(p))
|
||||
}
|
||||
|
||||
var (
|
||||
cuint = (C.uint)(0)
|
||||
culong C.ulong
|
||||
cchar C.char
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
ctx *C.struct_ibv_context
|
||||
}
|
||||
|
||||
func benchCgoCall(b *testing.B) {
|
||||
const x = C.int(2)
|
||||
const y = C.int(3)
|
||||
for i := 0; i < b.N; i++ {
|
||||
C.add(x, y)
|
||||
}
|
||||
}
|
||||
|
||||
var sinkString string
|
||||
|
||||
func benchGoString(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
sinkString = C.GoString(C.cstr)
|
||||
}
|
||||
const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||
if sinkString != want {
|
||||
b.Fatalf("%q != %q", sinkString, want)
|
||||
}
|
||||
}
|
||||
|
||||
// Issue 2470.
|
||||
func testUnsignedInt(t *testing.T) {
|
||||
a := (int64)(C.UINT32VAL)
|
||||
b := (int64)(0xc008427b)
|
||||
if a != b {
|
||||
t.Errorf("Incorrect unsigned int - got %x, want %x", a, b)
|
||||
}
|
||||
}
|
||||
|
||||
// Static (build-time) test that syntax traversal visits all operands of s[i:j:k].
|
||||
func sliceOperands(array [2000]int) {
|
||||
_ = array[C.KILO:C.KILO:C.KILO] // no type error
|
||||
}
|
||||
|
||||
// set in cgo_thread_lock.go init
|
||||
var testThreadLockFunc = func(*testing.T) {}
|
@ -1,32 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// Test that the #cgo CFLAGS directive works,
|
||||
// with and without platform filters.
|
||||
// See https://golang.org/issue/5224 for details.
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -DCOMMON_VALUE=123
|
||||
#cgo windows CFLAGS: -DIS_WINDOWS=1
|
||||
#cgo !windows CFLAGS: -DIS_WINDOWS=0
|
||||
int common = COMMON_VALUE;
|
||||
int is_windows = IS_WINDOWS;
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testCflags(t *testing.T) {
|
||||
is_windows := C.is_windows == 1
|
||||
if is_windows != (runtime.GOOS == "windows") {
|
||||
t.Errorf("is_windows: %v, runtime.GOOS: %s", is_windows, runtime.GOOS)
|
||||
}
|
||||
if C.common != 123 {
|
||||
t.Errorf("common: %v (expected 123)", C.common)
|
||||
}
|
||||
}
|
@ -8,6 +8,5 @@ import "testing"
|
||||
|
||||
// Stubs for tests that fails to build on Android
|
||||
func test6997(t *testing.T) {}
|
||||
func test3775(t *testing.T) {}
|
||||
func test8694(t *testing.T) {}
|
||||
func testSigaltstack(t *testing.T) {}
|
||||
|
@ -1,33 +0,0 @@
|
||||
// Copyright 2016 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 a constant in conjunction with pointer checking.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CheckConstVal 0
|
||||
|
||||
typedef struct {
|
||||
int *p;
|
||||
} CheckConstStruct;
|
||||
|
||||
static void CheckConstFunc(CheckConstStruct *p, int e) {
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func testCheckConst(t *testing.T) {
|
||||
// The test is that this compiles successfully.
|
||||
p := C.malloc(C.size_t(unsafe.Sizeof(C.int(0))))
|
||||
defer C.free(p)
|
||||
C.CheckConstFunc(&C.CheckConstStruct{(*C.int)(p)}, C.CheckConstVal)
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
// Copyright 2016 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
|
||||
|
||||
/*
|
||||
struct {
|
||||
float x;
|
||||
_Complex float y;
|
||||
} cplxAlign = { 3.14, 2.17 };
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestComplexAlign(t *testing.T) {
|
||||
if C.cplxAlign.x != 3.14 {
|
||||
t.Errorf("got %v, expected 3.14", C.cplxAlign.x)
|
||||
}
|
||||
if C.cplxAlign.y != 2.17 {
|
||||
t.Errorf("got %v, expected 2.17", C.cplxAlign.y)
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// 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 void doAdd(int, int);
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var sum struct {
|
||||
sync.Mutex
|
||||
i int
|
||||
}
|
||||
|
||||
//export Add
|
||||
func Add(x int) {
|
||||
defer func() {
|
||||
recover()
|
||||
}()
|
||||
sum.Lock()
|
||||
sum.i += x
|
||||
sum.Unlock()
|
||||
var p *int
|
||||
*p = 2
|
||||
}
|
||||
|
||||
func testCthread(t *testing.T) {
|
||||
if runtime.GOOS == "darwin" && (runtime.GOARCH == "arm" || runtime.GOARCH == "arm64") {
|
||||
t.Skip("the iOS exec wrapper is unable to properly handle the panic from Add")
|
||||
}
|
||||
sum.i = 0
|
||||
C.doAdd(10, 6)
|
||||
|
||||
want := 10 * (10 - 1) / 2 * 6
|
||||
if sum.i != want {
|
||||
t.Fatalf("sum=%d, want %d", sum.i, want)
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2010 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 file contains test cases for cgo.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
int base_symbol = 0;
|
||||
|
||||
#define alias_one base_symbol
|
||||
#define alias_two base_symbol
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "fmt"
|
||||
|
||||
func duplicateSymbols() {
|
||||
fmt.Printf("%v %v %v\n", C.base_symbol, C.alias_one, C.alias_two)
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
// Copyright 2011 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 <stdlib.h>
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// This is really an os package test but here for convenience.
|
||||
func testSetEnv(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
// Go uses SetEnvironmentVariable on windows. However,
|
||||
// C runtime takes a *copy* at process startup of the
|
||||
// OS environment, and stores it in environ/envp.
|
||||
// It is this copy that getenv/putenv manipulate.
|
||||
t.Logf("skipping test")
|
||||
return
|
||||
}
|
||||
const key = "CGO_OS_TEST_KEY"
|
||||
const val = "CGO_OS_TEST_VALUE"
|
||||
os.Setenv(key, val)
|
||||
keyc := C.CString(key)
|
||||
defer C.free(unsafe.Pointer(keyc))
|
||||
v := C.getenv(keyc)
|
||||
if uintptr(unsafe.Pointer(v)) == 0 {
|
||||
t.Fatal("getenv returned NULL")
|
||||
}
|
||||
vs := C.GoString(v)
|
||||
if vs != val {
|
||||
t.Fatalf("getenv() = %q; want %q", vs, val)
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
// Copyright 2011 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 "C"
|
||||
import "runtime"
|
||||
|
||||
//export ReturnIntLong
|
||||
func ReturnIntLong() (int, C.long) {
|
||||
return 1, 2
|
||||
}
|
||||
|
||||
//export gc
|
||||
func gc() {
|
||||
runtime.GC()
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// This file contains test cases for cgo with function pointer variables.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
typedef int (*intFunc) ();
|
||||
|
||||
int
|
||||
bridge_int_func(intFunc f)
|
||||
{
|
||||
return f();
|
||||
}
|
||||
|
||||
int fortytwo()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import "testing"
|
||||
|
||||
func callBridge(f C.intFunc) int {
|
||||
return int(C.bridge_int_func(f))
|
||||
}
|
||||
|
||||
func callCBridge(f C.intFunc) C.int {
|
||||
return C.bridge_int_func(f)
|
||||
}
|
||||
|
||||
func testFpVar(t *testing.T) {
|
||||
const expected = 42
|
||||
f := C.intFunc(C.fortytwo)
|
||||
res1 := C.bridge_int_func(f)
|
||||
if r1 := int(res1); r1 != expected {
|
||||
t.Errorf("got %d, want %d", r1, expected)
|
||||
}
|
||||
res2 := callCBridge(f)
|
||||
if r2 := int(res2); r2 != expected {
|
||||
t.Errorf("got %d, want %d", r2, expected)
|
||||
}
|
||||
r3 := callBridge(f)
|
||||
if r3 != expected {
|
||||
t.Errorf("got %d, want %d", r3, expected)
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
// Copyright 2011 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
|
||||
|
||||
// const char *greeting = "hello, world";
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const greeting = "hello, world"
|
||||
|
||||
type testPair struct {
|
||||
Name string
|
||||
Got, Want interface{}
|
||||
}
|
||||
|
||||
var testPairs = []testPair{
|
||||
{"GoString", C.GoString(C.greeting), greeting},
|
||||
{"GoStringN", C.GoStringN(C.greeting, 5), greeting[:5]},
|
||||
{"GoBytes", C.GoBytes(unsafe.Pointer(C.greeting), 5), []byte(greeting[:5])},
|
||||
}
|
||||
|
||||
func testHelpers(t *testing.T) {
|
||||
for _, pair := range testPairs {
|
||||
if !reflect.DeepEqual(pair.Got, pair.Want) {
|
||||
t.Errorf("%s: got %#v, want %#v", pair.Name, pair.Got, pair.Want)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
// 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")
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
// 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 11925. Structs with zero-length trailing fields are now
|
||||
// padded by the Go compiler.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
struct a11925 {
|
||||
int i;
|
||||
char a[0];
|
||||
char b[0];
|
||||
};
|
||||
|
||||
struct b11925 {
|
||||
int i;
|
||||
char a[0];
|
||||
char b[];
|
||||
};
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func test11925(t *testing.T) {
|
||||
if C.sizeof_struct_a11925 != unsafe.Sizeof(C.struct_a11925{}) {
|
||||
t.Errorf("size of a changed: C %d, Go %d", C.sizeof_struct_a11925, unsafe.Sizeof(C.struct_a11925{}))
|
||||
}
|
||||
if C.sizeof_struct_b11925 != unsafe.Sizeof(C.struct_b11925{}) {
|
||||
t.Errorf("size of b changed: C %d, Go %d", C.sizeof_struct_b11925, unsafe.Sizeof(C.struct_b11925{}))
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
// 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 12030. sprintf is defined in both ntdll and msvcrt,
|
||||
// Normally we want the one in the msvcrt.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
void issue12030conv(char *buf, double x) {
|
||||
sprintf(buf, "d=%g", x);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func test12030(t *testing.T) {
|
||||
buf := (*C.char)(C.malloc(256))
|
||||
defer C.free(unsafe.Pointer(buf))
|
||||
for _, f := range []float64{1.0, 2.0, 3.14} {
|
||||
C.issue12030conv(buf, C.double(f))
|
||||
got := C.GoString(buf)
|
||||
if want := fmt.Sprintf("d=%g", f); got != want {
|
||||
t.Fatalf("C.sprintf failed for %g: %q != %q", f, got, want)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// Copyright 2010 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 file contains test cases for cgo.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
// issue 1222
|
||||
typedef union {
|
||||
long align;
|
||||
} xxpthread_mutex_t;
|
||||
|
||||
struct ibv_async_event {
|
||||
union {
|
||||
int x;
|
||||
} element;
|
||||
};
|
||||
|
||||
struct ibv_context {
|
||||
xxpthread_mutex_t mutex;
|
||||
};
|
||||
*/
|
||||
import "C"
|
||||
|
||||
type AsyncEvent struct {
|
||||
event C.struct_ibv_async_event
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
// Copyright 2011 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"
|
||||
|
||||
// extern void BackIntoGo(void);
|
||||
// void IntoC(void);
|
||||
import "C"
|
||||
|
||||
//export BackIntoGo
|
||||
func BackIntoGo() {
|
||||
x := 1
|
||||
|
||||
for i := 0; i < 10000; i++ {
|
||||
xvariadic(x)
|
||||
if x != 1 {
|
||||
panic("x is not 1?")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func xvariadic(x ...interface{}) {
|
||||
}
|
||||
|
||||
func test1328(t *testing.T) {
|
||||
C.IntoC()
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
// Copyright 2016 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 13930. Test that cgo's multiple-value special form for
|
||||
// C function calls works in variable declaration statements.
|
||||
|
||||
package cgotest
|
||||
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
|
||||
var _, _ = C.abs(0)
|
@ -1,37 +0,0 @@
|
||||
// Copyright 2016 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 14838. add CBytes function
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
|
||||
int check_cbytes(char *b, size_t l) {
|
||||
int i;
|
||||
for (i = 0; i < l; i++) {
|
||||
if (b[i] != i) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func test14838(t *testing.T) {
|
||||
data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
cData := C.CBytes(data)
|
||||
defer C.free(cData)
|
||||
|
||||
if C.check_cbytes((*C.char)(cData), C.size_t(len(data))) == 0 {
|
||||
t.Fatalf("mismatched data: expected %v, got %v", data, (*(*[10]byte)(unsafe.Pointer(cData)))[:])
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
// Copyright 2011 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
|
||||
|
||||
/*
|
||||
// mysleep returns the absolute start time in ms.
|
||||
long long mysleep(int seconds);
|
||||
|
||||
// twoSleep returns the absolute start time of the first sleep
|
||||
// in ms.
|
||||
long long twoSleep(int);
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var sleepDone = make(chan int64)
|
||||
|
||||
// parallelSleep returns the absolute difference between the start time
|
||||
// of the two sleeps.
|
||||
func parallelSleep(n int) int64 {
|
||||
t := int64(C.twoSleep(C.int(n))) - <-sleepDone
|
||||
if t < 0 {
|
||||
return -t
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
//export BackgroundSleep
|
||||
func BackgroundSleep(n int32) {
|
||||
go func() {
|
||||
sleepDone <- int64(C.mysleep(C.int(n)))
|
||||
}()
|
||||
}
|
||||
|
||||
func testParallelSleep(t *testing.T) {
|
||||
sleepSec := 1
|
||||
dt := time.Duration(parallelSleep(sleepSec)) * time.Millisecond
|
||||
t.Logf("difference in start time for two sleep(%d) is %v", sleepSec, dt)
|
||||
// bug used to run sleeps in serial, producing a 2*sleepSec-second delay.
|
||||
// we detect if the start times of those sleeps are > 0.5*sleepSec-second.
|
||||
if dt >= time.Duration(sleepSec)*time.Second/2 {
|
||||
t.Fatalf("parallel %d-second sleeps slept for %f seconds", sleepSec, dt.Seconds())
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2012 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
|
||||
|
||||
/*
|
||||
// Mac OS X's gcc will generate scattered relocation 2/1 for
|
||||
// this function on Darwin/386, and 8l couldn't handle it.
|
||||
// this example is in issue 1635
|
||||
#include <stdio.h>
|
||||
void scatter() {
|
||||
void *p = scatter;
|
||||
printf("scatter = %p\n", p);
|
||||
}
|
||||
|
||||
// Adding this explicit extern declaration makes this a test for
|
||||
// https://gcc.gnu.org/PR68072 aka https://golang.org/issue/13344 .
|
||||
// It used to cause a cgo error when building with GCC 6.
|
||||
extern int hola;
|
||||
|
||||
// this example is in issue 3253
|
||||
int hola = 0;
|
||||
int testHola() { return hola; }
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test1635(t *testing.T) {
|
||||
C.scatter()
|
||||
if v := C.hola; v != 0 {
|
||||
t.Fatalf("C.hola is %d, should be 0", v)
|
||||
}
|
||||
if v := C.testHola(); v != 0 {
|
||||
t.Fatalf("C.testHola() is %d, should be 0", v)
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// Copyright 2016 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
|
||||
|
||||
/*
|
||||
// Test that C symbols larger than a page play nicely with the race detector.
|
||||
// See issue 17065.
|
||||
|
||||
int ii[65537];
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var sink C.int
|
||||
|
||||
func test17065(t *testing.T) {
|
||||
if runtime.GOOS == "darwin" {
|
||||
t.Skip("broken on darwin; issue 17065")
|
||||
}
|
||||
for i := range C.ii {
|
||||
sink = C.ii[i]
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
// Copyright 2016 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 17537. The void* cast introduced by cgo to avoid problems
|
||||
// with const/volatile qualifiers breaks C preprocessor macros that
|
||||
// emulate functions.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
int i;
|
||||
} S17537;
|
||||
|
||||
int I17537(S17537 *p);
|
||||
|
||||
#define I17537(p) ((p)->i)
|
||||
|
||||
// Calling this function used to fail without the cast.
|
||||
const int F17537(const char **p) {
|
||||
return **p;
|
||||
}
|
||||
|
||||
// Calling this function used to trigger an error from the C compiler
|
||||
// (issue 18298).
|
||||
void F18298(const void *const *p) {
|
||||
}
|
||||
|
||||
// Test that conversions between typedefs work as they used to.
|
||||
typedef const void *T18298_1;
|
||||
struct S18298 { int i; };
|
||||
typedef const struct S18298 *T18298_2;
|
||||
void G18298(T18298_1 t) {
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test17537(t *testing.T) {
|
||||
v := C.S17537{i: 17537}
|
||||
if got, want := C.I17537(&v), C.int(17537); got != want {
|
||||
t.Errorf("got %d, want %d", got, want)
|
||||
}
|
||||
|
||||
p := (*C.char)(C.malloc(1))
|
||||
*p = 17
|
||||
if got, want := C.F17537(&p), C.int(17); got != want {
|
||||
t.Errorf("got %d, want %d", got, want)
|
||||
}
|
||||
|
||||
C.F18298(nil)
|
||||
var v18298 C.T18298_2
|
||||
C.G18298(C.T18298_1(v18298))
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2016 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 18126: cgo check of void function returning errno.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
|
||||
void Issue18126C(void **p) {
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func test18126(t *testing.T) {
|
||||
p := C.malloc(1)
|
||||
_, err := C.Issue18126C(&p)
|
||||
C.free(p)
|
||||
_ = err
|
||||
}
|
@ -8,8 +8,6 @@
|
||||
|
||||
package cgotest
|
||||
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
|
@ -1,54 +0,0 @@
|
||||
// Copyright 2017 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
|
||||
|
||||
/*
|
||||
#define HELLO "hello"
|
||||
#define WORLD "world"
|
||||
#define HELLO_WORLD HELLO "\000" WORLD
|
||||
|
||||
struct foo { char c; };
|
||||
#define SIZE_OF(x) sizeof(x)
|
||||
#define SIZE_OF_FOO SIZE_OF(struct foo)
|
||||
#define VAR1 VAR
|
||||
#define VAR var
|
||||
int var = 5;
|
||||
|
||||
#define ADDR &var
|
||||
|
||||
#define CALL fn()
|
||||
int fn(void) {
|
||||
return ++var;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import "testing"
|
||||
|
||||
func test18720(t *testing.T) {
|
||||
if got, want := C.HELLO_WORLD, "hello\000world"; got != want {
|
||||
t.Errorf("C.HELLO_WORLD == %q, expected %q", got, want)
|
||||
}
|
||||
|
||||
if got, want := C.VAR1, C.int(5); got != want {
|
||||
t.Errorf("C.VAR1 == %v, expected %v", got, want)
|
||||
}
|
||||
|
||||
if got, want := *C.ADDR, C.int(5); got != want {
|
||||
t.Errorf("*C.ADDR == %v, expected %v", got, want)
|
||||
}
|
||||
|
||||
if got, want := C.CALL, C.int(6); got != want {
|
||||
t.Errorf("C.CALL == %v, expected %v", got, want)
|
||||
}
|
||||
|
||||
if got, want := C.CALL, C.int(7); got != want {
|
||||
t.Errorf("C.CALL == %v, expected %v", got, want)
|
||||
}
|
||||
|
||||
// Issue 20125.
|
||||
if got, want := C.SIZE_OF_FOO, 1; got != want {
|
||||
t.Errorf("C.SIZE_OF_FOO == %v, expected %v", got, want)
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// Copyright 2017 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
|
||||
|
||||
/*
|
||||
int issue20129 = 0;
|
||||
typedef void issue20129Void;
|
||||
issue20129Void issue20129Foo() {
|
||||
issue20129 = 1;
|
||||
}
|
||||
typedef issue20129Void issue20129Void2;
|
||||
issue20129Void2 issue20129Bar() {
|
||||
issue20129 = 2;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import "testing"
|
||||
|
||||
func test20129(t *testing.T) {
|
||||
if C.issue20129 != 0 {
|
||||
t.Fatal("test is broken")
|
||||
}
|
||||
C.issue20129Foo()
|
||||
if C.issue20129 != 1 {
|
||||
t.Errorf("got %v but expected %v", C.issue20129, 1)
|
||||
}
|
||||
C.issue20129Bar()
|
||||
if C.issue20129 != 2 {
|
||||
t.Errorf("got %v but expected %v", C.issue20129, 2)
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// Copyright 2017 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
|
||||
|
||||
/*
|
||||
#define UINT64_MAX 18446744073709551615ULL
|
||||
*/
|
||||
import "C"
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func test20369(t *testing.T) {
|
||||
if C.UINT64_MAX != math.MaxUint64 {
|
||||
t.Fatalf("got %v, want %v", uint64(C.UINT64_MAX), uint64(math.MaxUint64))
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
// Copyright 2017 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
|
||||
|
||||
//void callMulti(void);
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
//export multi
|
||||
func multi() (*C.char, C.int) {
|
||||
return C.CString("multi"), 0
|
||||
}
|
||||
|
||||
func test20910(t *testing.T) {
|
||||
C.callMulti()
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
// Copyright 2017 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.
|
||||
|
||||
// Fail to guess the kind of the constant "x".
|
||||
// No runtime test; just make sure it compiles.
|
||||
|
||||
package cgotest
|
||||
|
||||
// const int x = 42;
|
||||
import "C"
|
||||
|
||||
var issue21668_X = C.x
|
@ -1,16 +0,0 @@
|
||||
// Copyright 2017 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>
|
||||
// #define CAST_TO_INT64 (int64_t)(-1)
|
||||
import "C"
|
||||
import "testing"
|
||||
|
||||
func test21708(t *testing.T) {
|
||||
if got, want := C.CAST_TO_INT64, -1; got != want {
|
||||
t.Errorf("C.CAST_TO_INT64 == %v, expected %v", got, want)
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
// Copyright 2017 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
|
||||
|
||||
// Issue 21809. Compile C `typedef` to go type aliases.
|
||||
|
||||
// typedef long MySigned_t;
|
||||
// /* tests alias-to-alias */
|
||||
// typedef MySigned_t MySigned2_t;
|
||||
//
|
||||
// long takes_long(long x) { return x * x; }
|
||||
// MySigned_t takes_typedef(MySigned_t x) { return x * x; }
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test21809(t *testing.T) {
|
||||
longVar := C.long(3)
|
||||
typedefVar := C.MySigned_t(4)
|
||||
typedefTypedefVar := C.MySigned2_t(5)
|
||||
|
||||
// all three should be considered identical to `long`
|
||||
if ret := C.takes_long(longVar); ret != 9 {
|
||||
t.Errorf("got %v but expected %v", ret, 9)
|
||||
}
|
||||
if ret := C.takes_long(typedefVar); ret != 16 {
|
||||
t.Errorf("got %v but expected %v", ret, 16)
|
||||
}
|
||||
if ret := C.takes_long(typedefTypedefVar); ret != 25 {
|
||||
t.Errorf("got %v but expected %v", ret, 25)
|
||||
}
|
||||
|
||||
// They should also be identical to the typedef'd type
|
||||
if ret := C.takes_typedef(longVar); ret != 9 {
|
||||
t.Errorf("got %v but expected %v", ret, 9)
|
||||
}
|
||||
if ret := C.takes_typedef(typedefVar); ret != 16 {
|
||||
t.Errorf("got %v but expected %v", ret, 16)
|
||||
}
|
||||
if ret := C.takes_typedef(typedefTypedefVar); ret != 25 {
|
||||
t.Errorf("got %v but expected %v", ret, 25)
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
// Copyright 2017 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
|
||||
|
||||
// Test handling of bitfields.
|
||||
|
||||
/*
|
||||
typedef struct {
|
||||
unsigned long long f8 : 8;
|
||||
unsigned long long f16 : 16;
|
||||
unsigned long long f24 : 24;
|
||||
unsigned long long f32 : 32;
|
||||
unsigned long long f40 : 40;
|
||||
unsigned long long f48 : 48;
|
||||
unsigned long long f56 : 56;
|
||||
unsigned long long f64 : 64;
|
||||
} issue22958Type;
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// Nothing to run, just make sure this compiles.
|
||||
var Vissue22958 C.issue22958Type
|
@ -1,19 +0,0 @@
|
||||
// Copyright 2018 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
|
||||
|
||||
// int a(void) { return 5; };
|
||||
// int r(void) { return 3; };
|
||||
import "C"
|
||||
import "testing"
|
||||
|
||||
func test23356(t *testing.T) {
|
||||
if got, want := C.a(), C.int(5); got != want {
|
||||
t.Errorf("C.a() == %v, expected %v", got, want)
|
||||
}
|
||||
if got, want := C.r(), C.int(3); got != want {
|
||||
t.Errorf("C.r() == %v, expected %v", got, want)
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2018 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 we can pass compatible typedefs.
|
||||
// No runtime test; just make sure it compiles.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
typedef int *issue23720A;
|
||||
|
||||
typedef const int *issue23720B;
|
||||
|
||||
void issue23720F(issue23720B a) {}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func Issue23720F() {
|
||||
var x C.issue23720A
|
||||
C.issue23720F(x)
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
// +build amd64,linux
|
||||
|
||||
// Copyright 2018 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
|
||||
|
||||
// Test that C.GoString uses IndexByte in safe manner.
|
||||
|
||||
/*
|
||||
#include <sys/mman.h>
|
||||
|
||||
// Returns string with null byte at the last valid address
|
||||
char* dangerousString1() {
|
||||
int pageSize = 4096;
|
||||
char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
|
||||
mprotect(data + pageSize,pageSize,PROT_NONE);
|
||||
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
|
||||
int i = start;
|
||||
for (; i < pageSize; i++) {
|
||||
data[i] = 'x';
|
||||
}
|
||||
data[pageSize -1 ] = 0;
|
||||
return data+start;
|
||||
}
|
||||
|
||||
char* dangerousString2() {
|
||||
int pageSize = 4096;
|
||||
char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
|
||||
mprotect(data + 2 * pageSize,pageSize,PROT_NONE);
|
||||
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
|
||||
int i = start;
|
||||
for (; i < 2 * pageSize; i++) {
|
||||
data[i] = 'x';
|
||||
}
|
||||
data[2*pageSize -1 ] = 0;
|
||||
return data+start;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func test24206(t *testing.T) {
|
||||
if l := len(C.GoString(C.dangerousString1())); l != 123 {
|
||||
t.Errorf("Incorrect string length - got %d, want 123", l)
|
||||
}
|
||||
if l := len(C.GoString(C.dangerousString2())); l != 4096+123 {
|
||||
t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123)
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
// +build !amd64 !linux
|
||||
|
||||
// Copyright 2018 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"
|
||||
|
||||
func test24206(t *testing.T) {
|
||||
t.Skip("Skipping on non-amd64 or non-linux system")
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
// Copyright 2011 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 "C"
|
||||
|
||||
//export exportbyte
|
||||
func exportbyte() byte {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportbool
|
||||
func exportbool() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
//export exportrune
|
||||
func exportrune() rune {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exporterror
|
||||
func exporterror() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//export exportint
|
||||
func exportint() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportuint
|
||||
func exportuint() uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportuintptr
|
||||
func exportuintptr() uintptr {
|
||||
return (uintptr)(0)
|
||||
}
|
||||
|
||||
//export exportint8
|
||||
func exportint8() int8 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportuint8
|
||||
func exportuint8() uint8 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportint16
|
||||
func exportint16() int16 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportuint16
|
||||
func exportuint16() uint16 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportint32
|
||||
func exportint32() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportuint32
|
||||
func exportuint32() uint32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportint64
|
||||
func exportint64() int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportuint64
|
||||
func exportuint64() uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportfloat32
|
||||
func exportfloat32() float32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportfloat64
|
||||
func exportfloat64() float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportcomplex64
|
||||
func exportcomplex64() complex64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
//export exportcomplex128
|
||||
func exportcomplex128() complex128 {
|
||||
return 0
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2018 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 "C"
|
||||
import "testing"
|
||||
|
||||
func issue25143sum(ns ...C.int) C.int {
|
||||
total := C.int(0)
|
||||
for _, n := range ns {
|
||||
total += n
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
func test25143(t *testing.T) {
|
||||
if got, want := issue25143sum(1, 2, 3), C.int(6); got != want {
|
||||
t.Errorf("issue25143sum(1, 2, 3) == %v, expected %v", got, want)
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// Wrong type of constant with GCC 8 and newer.
|
||||
|
||||
package cgotest
|
||||
|
||||
// const unsigned long long int issue26066 = (const unsigned long long) -1;
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test26066(t *testing.T) {
|
||||
var i = int64(C.issue26066)
|
||||
if i != -1 {
|
||||
t.Errorf("got %d, want -1", i)
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// Copyright 2018 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
|
||||
|
||||
// Introduce two pointer types which are distinct, but have the same
|
||||
// base type. Make sure that both of those pointer types get resolved
|
||||
// correctly. Before the fix for 26517 if one of these pointer types
|
||||
// was resolved before the other one was processed, the second one
|
||||
// would never be resolved.
|
||||
// Before this issue was fixed this test failed on Windows,
|
||||
// where va_list expands to a named char* type.
|
||||
|
||||
/*
|
||||
#include <stdarg.h>
|
||||
typedef va_list TypeOne;
|
||||
typedef char *TypeTwo;
|
||||
*/
|
||||
import "C"
|
||||
|
||||
var a C.TypeOne
|
||||
var b C.TypeTwo
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// Failed to add type conversion for negative constant.
|
||||
// Issue 28772: Failed to add type conversion for Go constant set to C constant.
|
||||
// No runtime test; just make sure it compiles.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <complex.h>
|
||||
|
||||
#define issue28772Constant 1
|
||||
|
||||
static void issue28545F(char **p, int n, complex double a) {}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
const issue28772Constant = C.issue28772Constant
|
||||
|
||||
func issue28545G(p **C.char) {
|
||||
C.issue28545F(p, -1, (0))
|
||||
C.issue28545F(p, 2+3, complex(1, 1))
|
||||
C.issue28545F(p, issue28772Constant, issue28772Constant2)
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
// Copyright 2018 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
|
||||
|
||||
// Constants didn't work if defined in different source file.
|
||||
|
||||
// #define issue28772Constant2 2
|
||||
import "C"
|
||||
|
||||
const issue28772Constant2 = C.issue28772Constant2
|
@ -1,83 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// cgo was incorrectly adding padding after a packed struct.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
void *f1;
|
||||
uint32_t f2;
|
||||
} __attribute__((__packed__)) innerPacked;
|
||||
|
||||
typedef struct {
|
||||
innerPacked g1;
|
||||
uint64_t g2;
|
||||
} outerPacked;
|
||||
|
||||
typedef struct {
|
||||
void *f1;
|
||||
uint32_t f2;
|
||||
} innerUnpacked;
|
||||
|
||||
typedef struct {
|
||||
innerUnpacked g1;
|
||||
uint64_t g2;
|
||||
} outerUnpacked;
|
||||
|
||||
size_t offset(int x) {
|
||||
switch (x) {
|
||||
case 0:
|
||||
return offsetof(innerPacked, f2);
|
||||
case 1:
|
||||
return offsetof(outerPacked, g2);
|
||||
case 2:
|
||||
return offsetof(innerUnpacked, f2);
|
||||
case 3:
|
||||
return offsetof(outerUnpacked, g2);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func offset(i int) uintptr {
|
||||
var pi C.innerPacked
|
||||
var po C.outerPacked
|
||||
var ui C.innerUnpacked
|
||||
var uo C.outerUnpacked
|
||||
switch i {
|
||||
case 0:
|
||||
return unsafe.Offsetof(pi.f2)
|
||||
case 1:
|
||||
return unsafe.Offsetof(po.g2)
|
||||
case 2:
|
||||
return unsafe.Offsetof(ui.f2)
|
||||
case 3:
|
||||
return unsafe.Offsetof(uo.g2)
|
||||
default:
|
||||
panic("can't happen")
|
||||
}
|
||||
}
|
||||
|
||||
func test28896(t *testing.T) {
|
||||
for i := 0; i < 4; i++ {
|
||||
c := uintptr(C.offset(C.int(i)))
|
||||
g := offset(i)
|
||||
if c != g {
|
||||
t.Errorf("%d: C: %d != Go %d", i, c, g)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// cgo's /*line*/ comments failed when inserted after '/',
|
||||
// because the result looked like a "//" comment.
|
||||
// No runtime test; just make sure it compiles.
|
||||
|
||||
package cgotest
|
||||
|
||||
// #include <stddef.h>
|
||||
import "C"
|
||||
|
||||
func Issue29383(n, size uint) int {
|
||||
if ^C.size_t(0)/C.size_t(n) < C.size_t(size) {
|
||||
return 0
|
||||
}
|
||||
return 0
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
// Error handling a struct initializer that requires pointer checking.
|
||||
// Compilation test only, nothing to run.
|
||||
|
||||
package cgotest
|
||||
|
||||
// typedef struct { char **p; } S29748;
|
||||
// static int f29748(S29748 *p) { return 0; }
|
||||
import "C"
|
||||
|
||||
var Vissue29748 = C.f29748(&C.S29748{
|
||||
nil,
|
||||
})
|
||||
|
||||
func Fissue299748() {
|
||||
C.f29748(&C.S29748{
|
||||
nil,
|
||||
})
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
// Error with newline inserted into constant expression.
|
||||
// Compilation test only, nothing to run.
|
||||
|
||||
package cgotest
|
||||
|
||||
// static void issue29781F(char **p, int n) {}
|
||||
// #define ISSUE29781C 0
|
||||
import "C"
|
||||
|
||||
var issue29781X struct{ X int }
|
||||
|
||||
func issue29781F(...int) int { return 0 }
|
||||
|
||||
func issue29781G() {
|
||||
var p *C.char
|
||||
C.issue29781F(&p, C.ISSUE29781C+1)
|
||||
C.issue29781F(nil, (C.int)(
|
||||
0))
|
||||
C.issue29781F(&p, (C.int)(0))
|
||||
C.issue29781F(&p, (C.int)(
|
||||
0))
|
||||
C.issue29781F(&p, (C.int)(issue29781X.
|
||||
X))
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// Copyright 2019 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>
|
||||
// uint64_t issue29878exported(int8_t); // prototype must match
|
||||
// int16_t issue29878function(uint32_t arg) { return issue29878exported(arg); }
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test29878(t *testing.T) {
|
||||
const arg uint32 = 123 // fits into all integer types
|
||||
var ret int16 = C.issue29878function(arg) // no conversions needed
|
||||
if int64(ret) != int64(arg) {
|
||||
t.Errorf("return value unexpected: got %d, want %d", ret, arg)
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2019 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.
|
||||
|
||||
// Don't make a private copy of an array when taking the address of an
|
||||
// element.
|
||||
|
||||
package cgotest
|
||||
|
||||
// #include <string.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func test30065(t *testing.T) {
|
||||
var a [256]byte
|
||||
b := []byte("a")
|
||||
C.memcpy(unsafe.Pointer(&a), unsafe.Pointer(&b[0]), 1)
|
||||
if a[0] != 'a' {
|
||||
t.Errorf("&a failed: got %c, want %c", a[0], 'a')
|
||||
}
|
||||
|
||||
b = []byte("b")
|
||||
C.memcpy(unsafe.Pointer(&a[0]), unsafe.Pointer(&b[0]), 1)
|
||||
if a[0] != 'b' {
|
||||
t.Errorf("&a[0] failed: got %c, want %c", a[0], 'b')
|
||||
}
|
||||
|
||||
d := make([]byte, 256)
|
||||
b = []byte("c")
|
||||
C.memcpy(unsafe.Pointer(&d[0]), unsafe.Pointer(&b[0]), 1)
|
||||
if d[0] != 'c' {
|
||||
t.Errorf("&d[0] failed: got %c, want %c", d[0], 'c')
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// +build !windows
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void *thread(void *p) {
|
||||
const int M = 100;
|
||||
int i;
|
||||
(void)p;
|
||||
for (i = 0; i < M; i++) {
|
||||
pthread_kill(pthread_self(), SIGCHLD);
|
||||
usleep(rand() % 20 + 5);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void testSendSIG() {
|
||||
const int N = 20;
|
||||
int i;
|
||||
pthread_t tid[N];
|
||||
for (i = 0; i < N; i++) {
|
||||
usleep(rand() % 200 + 100);
|
||||
pthread_create(&tid[i], 0, thread, NULL);
|
||||
}
|
||||
for (i = 0; i < N; i++)
|
||||
pthread_join(tid[i], 0);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func test3250(t *testing.T) {
|
||||
t.Skip("skipped, see golang.org/issue/5885")
|
||||
const (
|
||||
thres = 1
|
||||
sig = syscall.SIGCHLD
|
||||
)
|
||||
type result struct {
|
||||
n int
|
||||
sig os.Signal
|
||||
}
|
||||
var (
|
||||
sigCh = make(chan os.Signal, 10)
|
||||
waitStart = make(chan struct{})
|
||||
waitDone = make(chan result)
|
||||
)
|
||||
|
||||
signal.Notify(sigCh, sig)
|
||||
|
||||
go func() {
|
||||
n := 0
|
||||
alarm := time.After(time.Second * 3)
|
||||
for {
|
||||
select {
|
||||
case <-waitStart:
|
||||
waitStart = nil
|
||||
case v := <-sigCh:
|
||||
n++
|
||||
if v != sig || n > thres {
|
||||
waitDone <- result{n, v}
|
||||
return
|
||||
}
|
||||
case <-alarm:
|
||||
waitDone <- result{n, sig}
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
waitStart <- struct{}{}
|
||||
C.testSendSIG()
|
||||
r := <-waitDone
|
||||
if r.sig != sig {
|
||||
t.Fatalf("received signal %v, but want %v", r.sig, sig)
|
||||
}
|
||||
t.Logf("got %d signals\n", r.n)
|
||||
if r.n <= thres {
|
||||
t.Fatalf("expected more than %d", thres)
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package cgotest
|
||||
|
||||
import "testing"
|
||||
|
||||
func test3250(t *testing.T) {}
|
@ -1,49 +0,0 @@
|
||||
// Copyright 2012 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
|
||||
|
||||
/*
|
||||
// libgcc on ARM might be compiled as thumb code, but our 5l
|
||||
// can't handle that, so we have to disable this test on arm.
|
||||
#ifdef __ARMEL__
|
||||
#include <stdio.h>
|
||||
int vabs(int x) {
|
||||
puts("testLibgcc is disabled on ARM because 5l cannot handle thumb library.");
|
||||
return (x < 0) ? -x : x;
|
||||
}
|
||||
#elif defined(__arm64__) && defined(__clang__)
|
||||
#include <stdio.h>
|
||||
int vabs(int x) {
|
||||
puts("testLibgcc is disabled on ARM64 with clang due to lack of libgcc.");
|
||||
return (x < 0) ? -x : x;
|
||||
}
|
||||
#else
|
||||
int __absvsi2(int); // dummy prototype for libgcc function
|
||||
// we shouldn't name the function abs, as gcc might use
|
||||
// the builtin one.
|
||||
int vabs(int x) { return __absvsi2(x); }
|
||||
#endif
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func testLibgcc(t *testing.T) {
|
||||
var table = []struct {
|
||||
in, out C.int
|
||||
}{
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{-42, 42},
|
||||
{1000300, 1000300},
|
||||
{1 - 1<<31, 1<<31 - 1},
|
||||
}
|
||||
for _, v := range table {
|
||||
if o := C.vabs(v.in); o != v.out {
|
||||
t.Fatalf("abs(%d) got %d, should be %d", v.in, o, v.out)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
// Copyright 2012 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 3729: cmd/cgo: access errno from void C function
|
||||
// void f(void) returns [0]byte, error in Go world.
|
||||
|
||||
// +build !windows
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <errno.h>
|
||||
|
||||
void g(void) {
|
||||
errno = E2BIG;
|
||||
}
|
||||
|
||||
// try to pass some non-trivial arguments to function g2
|
||||
const char _expA = 0x42;
|
||||
const float _expB = 3.14159;
|
||||
const short _expC = 0x55aa;
|
||||
const int _expD = 0xdeadbeef;
|
||||
void g2(int x, char a, float b, short c, int d) {
|
||||
if (a == _expA && b == _expB && c == _expC && d == _expD)
|
||||
errno = x;
|
||||
else
|
||||
errno = -1;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func test3729(t *testing.T) {
|
||||
_, e := C.g()
|
||||
if e != syscall.E2BIG {
|
||||
t.Errorf("got %q, expect %q", e, syscall.E2BIG)
|
||||
}
|
||||
_, e = C.g2(C.EINVAL, C._expA, C._expB, C._expC, C._expD)
|
||||
if e != syscall.EINVAL {
|
||||
t.Errorf("got %q, expect %q", e, syscall.EINVAL)
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
// Copyright 2012 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 3729: cmd/cgo: access errno from void C function
|
||||
// void f(void) returns [0]byte, error in Go world.
|
||||
|
||||
// +build windows
|
||||
|
||||
package cgotest
|
||||
|
||||
import "testing"
|
||||
|
||||
func test3729(t *testing.T) {
|
||||
t.Log("skip errno test on Windows")
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2012 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 "C"
|
||||
|
||||
//export exportSliceIn
|
||||
func exportSliceIn(s []byte) bool {
|
||||
return len(s) == cap(s)
|
||||
}
|
||||
|
||||
//export exportSliceOut
|
||||
func exportSliceOut() []byte {
|
||||
return []byte{1}
|
||||
}
|
||||
|
||||
//export exportSliceInOut
|
||||
func exportSliceInOut(s []byte) []byte {
|
||||
return s
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
// +build !android
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
void lockOSThreadCallback(void);
|
||||
inline static void lockOSThreadC(void)
|
||||
{
|
||||
lockOSThreadCallback();
|
||||
}
|
||||
int usleep(unsigned usec);
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Same as test3775 but run during init so that
|
||||
// there are two levels of internal runtime lock
|
||||
// (1 for init, 1 for cgo).
|
||||
// This would have been broken by CL 11663043.
|
||||
C.lockOSThreadC()
|
||||
}
|
||||
|
||||
func test3775(t *testing.T) {
|
||||
// Used to panic because of the UnlockOSThread below.
|
||||
C.lockOSThreadC()
|
||||
}
|
||||
|
||||
//export lockOSThreadCallback
|
||||
func lockOSThreadCallback() {
|
||||
runtime.LockOSThread()
|
||||
runtime.UnlockOSThread()
|
||||
go C.usleep(10000)
|
||||
runtime.Gosched()
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// Copyright 2012 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
|
||||
|
||||
// Test that cgo reserves enough stack space during cgo call.
|
||||
// See https://golang.org/issue/3945 for details.
|
||||
|
||||
// #include <stdio.h>
|
||||
//
|
||||
// void say() {
|
||||
// printf("%s from C\n", "hello");
|
||||
// }
|
||||
//
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func testPrintf(t *testing.T) {
|
||||
C.say()
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// Copyright 2012 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
|
||||
|
||||
/*
|
||||
typedef enum {
|
||||
A = 0,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
} issue4054a;
|
||||
*/
|
||||
import "C"
|
||||
|
||||
var issue4054a = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J}
|
@ -1,23 +0,0 @@
|
||||
// Copyright 2012 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
|
||||
|
||||
/*
|
||||
typedef enum {
|
||||
A = 0,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
} issue4054b;
|
||||
*/
|
||||
import "C"
|
||||
|
||||
var issue4054b = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J}
|
@ -1,17 +0,0 @@
|
||||
// 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
|
||||
|
||||
/*
|
||||
// We've historically permitted #include <>, so test it here. Issue 29333.
|
||||
#include <issue4339.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test4339(t *testing.T) {
|
||||
C.handle4339(&C.exported4339)
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
// Copyright 2012 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 4417: cmd/cgo: bool alignment/padding issue.
|
||||
// bool alignment is wrong and causing wrong arguments when calling functions.
|
||||
//
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <stdbool.h>
|
||||
|
||||
static int c_bool(bool a, bool b, int c, bool d, bool e) {
|
||||
return c;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import "testing"
|
||||
|
||||
func testBoolAlign(t *testing.T) {
|
||||
b := C.c_bool(true, true, 10, true, false)
|
||||
if b != 10 {
|
||||
t.Fatalf("found %d expected 10\n", b)
|
||||
}
|
||||
b = C.c_bool(true, true, 5, true, true)
|
||||
if b != 5 {
|
||||
t.Fatalf("found %d expected 5\n", b)
|
||||
}
|
||||
b = C.c_bool(true, true, 3, true, false)
|
||||
if b != 3 {
|
||||
t.Fatalf("found %d expected 3\n", b)
|
||||
}
|
||||
b = C.c_bool(false, false, 1, true, false)
|
||||
if b != 1 {
|
||||
t.Fatalf("found %d expected 1\n", b)
|
||||
}
|
||||
b = C.c_bool(false, true, 200, true, false)
|
||||
if b != 200 {
|
||||
t.Fatalf("found %d expected 200\n", b)
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
// 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
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -Werror
|
||||
const struct { int a; } *issue4857() { return (void *)0; }
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func test4857() {
|
||||
_ = C.issue4857()
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
// 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 5227: linker incorrectly treats common symbols and
|
||||
// leaves them undefined.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
typedef struct {
|
||||
int Count;
|
||||
} Fontinfo;
|
||||
|
||||
Fontinfo SansTypeface;
|
||||
|
||||
extern void init();
|
||||
|
||||
Fontinfo loadfont() {
|
||||
Fontinfo f = {0};
|
||||
return f;
|
||||
}
|
||||
|
||||
void init() {
|
||||
SansTypeface = loadfont();
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test5227(t *testing.T) {
|
||||
C.init()
|
||||
}
|
||||
|
||||
func selectfont() C.Fontinfo {
|
||||
return C.SansTypeface
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
// 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 5242. Cgo incorrectly computed the alignment of structs
|
||||
// with no Go accessible fields as 0, and then panicked on
|
||||
// modulo-by-zero computations.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
typedef struct {
|
||||
} foo;
|
||||
|
||||
typedef struct {
|
||||
int x : 1;
|
||||
} bar;
|
||||
|
||||
int issue5242(foo f, bar b) {
|
||||
return 5242;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test5242(t *testing.T) {
|
||||
if got := C.issue5242(C.foo{}, C.bar{}); got != 5242 {
|
||||
t.Errorf("got %v", got)
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// +build !windows
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
|
||||
static void *thread1(void *p) {
|
||||
(void)p;
|
||||
pthread_kill(pthread_self(), SIGPROF);
|
||||
return NULL;
|
||||
}
|
||||
void test5337() {
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, 0, thread1, NULL);
|
||||
pthread_join(tid, 0);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
// Verify that we can withstand SIGPROF received on foreign threads
|
||||
func test5337(t *testing.T) {
|
||||
C.test5337()
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// +build windows
|
||||
|
||||
package cgotest
|
||||
|
||||
import "testing"
|
||||
|
||||
func test5337(t *testing.T) {}
|
@ -1,27 +0,0 @@
|
||||
// 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"
|
||||
|
||||
/*
|
||||
extern int issue5548_in_c(void);
|
||||
*/
|
||||
import "C"
|
||||
|
||||
//export issue5548FromC
|
||||
func issue5548FromC(s string, i int) int {
|
||||
if len(s) == 4 && s == "test" && i == 42 {
|
||||
return 12345
|
||||
}
|
||||
println("got", len(s), i)
|
||||
return 9876
|
||||
}
|
||||
|
||||
func test5548(t *testing.T) {
|
||||
if x := C.issue5548_in_c(); x != 12345 {
|
||||
t.Errorf("issue5548_in_c = %d, want %d", x, 12345)
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
// 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
|
||||
|
||||
/*
|
||||
const long long issue5603exp = 0x12345678;
|
||||
long long issue5603foo0() { return issue5603exp; }
|
||||
long long issue5603foo1(void *p) { return issue5603exp; }
|
||||
long long issue5603foo2(void *p, void *q) { return issue5603exp; }
|
||||
long long issue5603foo3(void *p, void *q, void *r) { return issue5603exp; }
|
||||
long long issue5603foo4(void *p, void *q, void *r, void *s) { return issue5603exp; }
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test5603(t *testing.T) {
|
||||
var x [5]int64
|
||||
exp := int64(C.issue5603exp)
|
||||
x[0] = int64(C.issue5603foo0())
|
||||
x[1] = int64(C.issue5603foo1(nil))
|
||||
x[2] = int64(C.issue5603foo2(nil, nil))
|
||||
x[3] = int64(C.issue5603foo3(nil, nil, nil))
|
||||
x[4] = int64(C.issue5603foo4(nil, nil, nil, nil))
|
||||
for i, v := range x {
|
||||
if v != exp {
|
||||
t.Errorf("issue5603foo%d() returns %v, expected %v", i, v, exp)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
// 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
|
||||
|
||||
// int test5740a(void), test5740b(void);
|
||||
import "C"
|
||||
import "testing"
|
||||
|
||||
func test5740(t *testing.T) {
|
||||
if v := C.test5740a() + C.test5740b(); v != 5 {
|
||||
t.Errorf("expected 5, got %v", v)
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// 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
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -lm
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
static void output5986()
|
||||
{
|
||||
int current_row = 0, row_count = 0;
|
||||
double sum_squares = 0;
|
||||
double d;
|
||||
do {
|
||||
if (current_row == 10) {
|
||||
current_row = 0;
|
||||
}
|
||||
++row_count;
|
||||
}
|
||||
while (current_row++ != 1);
|
||||
d = sqrt(sum_squares / row_count);
|
||||
printf("sqrt is: %g\n", d);
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
import "testing"
|
||||
|
||||
func test5986(t *testing.T) {
|
||||
C.output5986()
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// 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
|
||||
|
||||
// Test handling of #defined names in clang.
|
||||
// golang.org/issue/6128.
|
||||
|
||||
/*
|
||||
// NOTE: Must use hex, or else a shortcut for decimals
|
||||
// in cgo avoids trying to pass this to clang.
|
||||
#define X 0x1
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func test6128() {
|
||||
// nothing to run, just make sure this compiles.
|
||||
_ = C.X
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// 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
|
||||
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test6390(t *testing.T) {
|
||||
p1 := C.malloc(1024)
|
||||
if p1 == nil {
|
||||
t.Fatalf("C.malloc(1024) returned nil")
|
||||
}
|
||||
p2 := C.malloc(0)
|
||||
if p2 == nil {
|
||||
t.Fatalf("C.malloc(0) returned nil")
|
||||
}
|
||||
C.free(p1)
|
||||
C.free(p2)
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// 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
|
||||
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
int x;
|
||||
} y[16];
|
||||
} z;
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func test6472() {
|
||||
// nothing to run, just make sure this compiles
|
||||
s := new(C.z)
|
||||
println(s.y[0].x)
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
// 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
|
||||
|
||||
// Test handling of size_t in the face of incorrect clang debug information.
|
||||
// golang.org/issue/6506.
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
func test6506() {
|
||||
// nothing to run, just make sure this compiles
|
||||
var x C.size_t
|
||||
|
||||
C.calloc(x, x)
|
||||
C.malloc(x)
|
||||
C.realloc(nil, x)
|
||||
C.memcpy(nil, nil, x)
|
||||
C.memcmp(nil, nil, x)
|
||||
C.memmove(nil, nil, x)
|
||||
C.strncpy(nil, nil, x)
|
||||
C.strncmp(nil, nil, x)
|
||||
C.strncat(nil, nil, x)
|
||||
x = C.strxfrm(nil, nil, x)
|
||||
C.memchr(nil, 0, x)
|
||||
x = C.strcspn(nil, nil)
|
||||
x = C.strspn(nil, nil)
|
||||
C.memset(nil, 0, x)
|
||||
x = C.strlen(nil)
|
||||
_ = x
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
// 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.
|
||||
|
||||
// golang.org/issue/6612
|
||||
// Test new scheme for deciding whether C.name is an expression, type, constant.
|
||||
// Clang silences some warnings when the name is a #defined macro, so test those too
|
||||
// (even though we now use errors exclusively, not warnings).
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
void myfunc(void) {}
|
||||
int myvar = 5;
|
||||
const char *mytext = "abcdef";
|
||||
typedef int mytype;
|
||||
enum {
|
||||
myenum = 1234,
|
||||
};
|
||||
|
||||
#define myfunc_def myfunc
|
||||
#define myvar_def myvar
|
||||
#define mytext_def mytext
|
||||
#define mytype_def mytype
|
||||
#define myenum_def myenum
|
||||
#define myint_def 12345
|
||||
#define myfloat_def 1.5
|
||||
#define mystring_def "hello"
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func testNaming(t *testing.T) {
|
||||
C.myfunc()
|
||||
C.myfunc_def()
|
||||
if v := C.myvar; v != 5 {
|
||||
t.Errorf("C.myvar = %d, want 5", v)
|
||||
}
|
||||
if v := C.myvar_def; v != 5 {
|
||||
t.Errorf("C.myvar_def = %d, want 5", v)
|
||||
}
|
||||
if s := C.GoString(C.mytext); s != "abcdef" {
|
||||
t.Errorf("C.mytext = %q, want %q", s, "abcdef")
|
||||
}
|
||||
if s := C.GoString(C.mytext_def); s != "abcdef" {
|
||||
t.Errorf("C.mytext_def = %q, want %q", s, "abcdef")
|
||||
}
|
||||
if c := C.myenum; c != 1234 {
|
||||
t.Errorf("C.myenum = %v, want 1234", c)
|
||||
}
|
||||
if c := C.myenum_def; c != 1234 {
|
||||
t.Errorf("C.myenum_def = %v, want 1234", c)
|
||||
}
|
||||
{
|
||||
const c = C.myenum
|
||||
if c != 1234 {
|
||||
t.Errorf("C.myenum as const = %v, want 1234", c)
|
||||
}
|
||||
}
|
||||
{
|
||||
const c = C.myenum_def
|
||||
if c != 1234 {
|
||||
t.Errorf("C.myenum as const = %v, want 1234", c)
|
||||
}
|
||||
}
|
||||
if c := C.myint_def; c != 12345 {
|
||||
t.Errorf("C.myint_def = %v, want 12345", c)
|
||||
}
|
||||
{
|
||||
const c = C.myint_def
|
||||
if c != 12345 {
|
||||
t.Errorf("C.myint as const = %v, want 12345", c)
|
||||
}
|
||||
}
|
||||
|
||||
if c := C.myfloat_def; c != 1.5 {
|
||||
t.Errorf("C.myint_def = %v, want 1.5", c)
|
||||
}
|
||||
{
|
||||
const c = C.myfloat_def
|
||||
if c != 1.5 {
|
||||
t.Errorf("C.myint as const = %v, want 1.5", c)
|
||||
}
|
||||
}
|
||||
|
||||
if s := C.mystring_def; s != "hello" {
|
||||
t.Errorf("C.mystring_def = %q, want %q", s, "hello")
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
// 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)
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// Copyright 2017 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
char* Issue6907CopyString(_GoString_ s) {
|
||||
size_t n;
|
||||
const char *p;
|
||||
char *r;
|
||||
|
||||
n = _GoStringLen(s);
|
||||
p = _GoStringPtr(s);
|
||||
r = malloc(n + 1);
|
||||
memmove(r, p, n);
|
||||
r[n] = '\0';
|
||||
return r;
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test6907(t *testing.T) {
|
||||
want := "yarn"
|
||||
if got := C.GoString(C.Issue6907CopyString(want)); got != want {
|
||||
t.Errorf("C.GoString(C.Issue6907CopyString(%q)) == %q, want %q", want, got, want)
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
// Copyright 2017 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 int CheckIssue6907C(_GoString_);
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
const CString = "C string"
|
||||
|
||||
//export CheckIssue6907Go
|
||||
func CheckIssue6907Go(s string) C.int {
|
||||
if s == CString {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func test6907Go(t *testing.T) {
|
||||
if got := C.CheckIssue6907C(CString); got != 1 {
|
||||
t.Errorf("C.CheckIssue6907C() == %d, want %d", got, 1)
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// 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))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// 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 || uintptr(bad7665) != good7665 {
|
||||
t.Errorf("ptrs = %p, %#x, want same non-nil pointer", bad7665, good7665)
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
// 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)
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
// 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 7978. Stack tracing didn't work during cgo code after calling a Go
|
||||
// callback. Make sure GC works and the stack trace is correct.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
#include <stdint.h>
|
||||
|
||||
void issue7978cb(void);
|
||||
|
||||
#if defined(__APPLE__) && defined(__arm__)
|
||||
// on Darwin/ARM, libSystem doesn't provide implementation of the __sync_fetch_and_add
|
||||
// primitive, and although gcc supports it, it doesn't inline its definition.
|
||||
// Clang could inline its definition, so we require clang on Darwin/ARM.
|
||||
#if defined(__clang__)
|
||||
#define HAS_SYNC_FETCH_AND_ADD 1
|
||||
#else
|
||||
#define HAS_SYNC_FETCH_AND_ADD 0
|
||||
#endif
|
||||
#else
|
||||
#define HAS_SYNC_FETCH_AND_ADD 1
|
||||
#endif
|
||||
|
||||
// use ugly atomic variable sync since that doesn't require calling back into
|
||||
// Go code or OS dependencies
|
||||
static void issue7978c(uint32_t *sync) {
|
||||
#if HAS_SYNC_FETCH_AND_ADD
|
||||
while(__sync_fetch_and_add(sync, 0) != 0)
|
||||
;
|
||||
__sync_fetch_and_add(sync, 1);
|
||||
while(__sync_fetch_and_add(sync, 0) != 2)
|
||||
;
|
||||
issue7978cb();
|
||||
__sync_fetch_and_add(sync, 1);
|
||||
while(__sync_fetch_and_add(sync, 0) != 6)
|
||||
;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var issue7978sync uint32
|
||||
|
||||
func issue7978check(t *testing.T, wantFunc string, badFunc string, depth int) {
|
||||
runtime.GC()
|
||||
buf := make([]byte, 65536)
|
||||
trace := string(buf[:runtime.Stack(buf, true)])
|
||||
for _, goroutine := range strings.Split(trace, "\n\n") {
|
||||
if strings.Contains(goroutine, "test.issue7978go") {
|
||||
trace := strings.Split(goroutine, "\n")
|
||||
// look for the expected function in the stack
|
||||
for i := 0; i < depth; i++ {
|
||||
if badFunc != "" && strings.Contains(trace[1+2*i], badFunc) {
|
||||
t.Errorf("bad stack: found %s in the stack:\n%s", badFunc, goroutine)
|
||||
return
|
||||
}
|
||||
if strings.Contains(trace[1+2*i], wantFunc) {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Errorf("bad stack: didn't find %s in the stack:\n%s", wantFunc, goroutine)
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Errorf("bad stack: goroutine not found. Full stack dump:\n%s", trace)
|
||||
}
|
||||
|
||||
func issue7978wait(store uint32, wait uint32) {
|
||||
if store != 0 {
|
||||
atomic.StoreUint32(&issue7978sync, store)
|
||||
}
|
||||
for atomic.LoadUint32(&issue7978sync) != wait {
|
||||
runtime.Gosched()
|
||||
}
|
||||
}
|
||||
|
||||
//export issue7978cb
|
||||
func issue7978cb() {
|
||||
// Force a stack growth from the callback to put extra
|
||||
// pressure on the runtime. See issue #17785.
|
||||
growStack(64)
|
||||
issue7978wait(3, 4)
|
||||
}
|
||||
|
||||
func growStack(n int) int {
|
||||
var buf [128]int
|
||||
if n == 0 {
|
||||
return 0
|
||||
}
|
||||
return buf[growStack(n-1)]
|
||||
}
|
||||
|
||||
func issue7978go() {
|
||||
C.issue7978c((*C.uint32_t)(&issue7978sync))
|
||||
issue7978wait(7, 8)
|
||||
}
|
||||
|
||||
func test7978(t *testing.T) {
|
||||
if runtime.Compiler == "gccgo" {
|
||||
t.Skip("gccgo can not do stack traces of C code")
|
||||
}
|
||||
if C.HAS_SYNC_FETCH_AND_ADD == 0 {
|
||||
t.Skip("clang required for __sync_fetch_and_add support on darwin/arm")
|
||||
}
|
||||
debug.SetTraceback("2")
|
||||
issue7978sync = 0
|
||||
go issue7978go()
|
||||
// test in c code, before callback
|
||||
issue7978wait(0, 1)
|
||||
issue7978check(t, "_Cfunc_issue7978c(", "", 1)
|
||||
// test in go code, during callback
|
||||
issue7978wait(2, 3)
|
||||
issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3)
|
||||
// test in c code, after callback
|
||||
issue7978wait(4, 5)
|
||||
issue7978check(t, "_Cfunc_issue7978c(", "_cgoexpwrap", 1)
|
||||
// test in go code, after return from cgo
|
||||
issue7978wait(6, 7)
|
||||
issue7978check(t, "test.issue7978go(", "", 3)
|
||||
atomic.StoreUint32(&issue7978sync, 8)
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
// 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 8092. Test that linker defined symbols (e.g., text, data) don't
|
||||
// conflict with C symbols.
|
||||
|
||||
package cgotest
|
||||
|
||||
/*
|
||||
char text[] = "text";
|
||||
char data[] = "data";
|
||||
char *ctext(void) { return text; }
|
||||
char *cdata(void) { return data; }
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import "testing"
|
||||
|
||||
func test8092(t *testing.T) {
|
||||
tests := []struct {
|
||||
s string
|
||||
a, b *C.char
|
||||
}{
|
||||
{"text", &C.text[0], C.ctext()},
|
||||
{"data", &C.data[0], C.cdata()},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if test.a != test.b {
|
||||
t.Errorf("%s: pointer mismatch: %v != %v", test.s, test.a, test.b)
|
||||
}
|
||||
if got := C.GoString(test.a); got != test.s {
|
||||
t.Errorf("%s: points at %#v, want %#v", test.s, got, test.s)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
// 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
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user