1
0
mirror of https://github.com/golang/go synced 2024-09-29 18:24:29 -06:00
go/misc/cgo/test/test.go
Russ Cox b0e238add5 misc/cgo/test: consolidate tests into fewer cgo source files
Each different file that does import "C" must be compiled
and analyzed separately by cgo. Having fewer files import "C"
reduces the cost of building the test. This is especially important
because this test is built and run four different times (with different
settings) during all.bash.

go test -c in this directory used to take over 20 seconds on my laptop.
Now it takes under 5 seconds.

Removes 23.4r 29.0u 21.5s from all.bash.

For #26473.

Change-Id: Ie7cb7b0d9d6138ebd2eb548d0d8ea6e409ae10b9
Reviewed-on: https://go-review.googlesource.com/c/go/+/177558
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2019-05-22 12:52:33 +00:00

2088 lines
42 KiB
Go

// 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.
// Test cases for cgo.
// Both the import "C" prologue and the main file are sorted by issue number.
// This file contains C definitions (not just declarations)
// and so it must NOT contain any //export directives on Go functions.
// See testx.go for exports.
package cgotest
/*
#include <complex.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <errno.h>
#cgo LDFLAGS: -lm
#ifndef WIN32
#include <pthread.h>
#include <signal.h>
#endif
// alignment tests
typedef unsigned char Uint8;
typedef unsigned short Uint16;
typedef enum {
MOD1 = 0x0000,
MODX = 0x8000
} SDLMod;
typedef enum {
A1 = 1,
B1 = 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);
}
// api
const char *greeting = "hello, world";
// basic test cases
#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; }
int add(int x, int y) {
return x+y;
};
// complex alignment
struct {
float x;
_Complex float y;
} cplxAlign = { 3.14, 2.17 };
// constants and pointer checking
#define CheckConstVal 0
typedef struct {
int *p;
} CheckConstStruct;
static void CheckConstFunc(CheckConstStruct *p, int e) {}
// duplicate symbol
int base_symbol = 0;
#define alias_one base_symbol
#define alias_two base_symbol
// function pointer variables
typedef int (*intFunc) ();
int
bridge_int_func(intFunc f)
{
return f();
}
int fortytwo()
{
return 42;
}
// issue 1222
typedef union {
long align;
} xxpthread_mutex_t;
struct ibv_async_event {
union {
int x;
} element;
};
struct ibv_context {
xxpthread_mutex_t mutex;
};
// issue 1635
// 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
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; }
// issue 3250
#ifdef WIN32
void testSendSIG() {}
#else
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);
}
#endif
// issue 3261
// 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__
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__)
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
// issue 3729
// access errno from void C function
const char _expA = 0x42;
const float _expB = 3.14159;
const short _expC = 0x55aa;
const int _expD = 0xdeadbeef;
#ifdef WIN32
void g(void) {}
void g2(int x, char a, float b, short c, int d) {}
#else
void g(void) {
errno = E2BIG;
}
// try to pass some non-trivial arguments to function g2
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;
}
#endif
// issue 3945
// Test that cgo reserves enough stack space during cgo call.
// See https://golang.org/issue/3945 for details.
void say() {
printf("%s from C\n", "hello");
}
// issue 4054 part 1 - other half in testx.go
typedef enum {
A = 0,
B,
C,
D,
E,
F,
G,
H,
II,
J,
} issue4054a;
// issue 4339
// We've historically permitted #include <>, so test it here. Issue 29333.
#include <issue4339.h>
// issue 4417
// cmd/cgo: bool alignment/padding issue.
// bool alignment is wrong and causing wrong arguments when calling functions.
static int c_bool(bool a, bool b, int c, bool d, bool e) {
return c;
}
// issue 4857
#cgo CFLAGS: -Werror
const struct { int a; } *issue4857() { return (void *)0; }
// issue 5224
// Test that the #cgo CFLAGS directive works,
// with and without platform filters.
#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;
// issue 5227
// linker incorrectly treats common symbols and
// leaves them undefined.
typedef struct {
int Count;
} Fontinfo;
Fontinfo SansTypeface;
extern void init();
Fontinfo loadfont() {
Fontinfo f = {0};
return f;
}
void init() {
SansTypeface = loadfont();
}
// issue 5242
// Cgo incorrectly computed the alignment of structs
// with no Go accessible fields as 0, and then panicked on
// modulo-by-zero computations.
typedef struct {
} foo;
typedef struct {
int x : 1;
} bar;
int issue5242(foo f, bar b) {
return 5242;
}
// issue 5337
// Verify that we can withstand SIGPROF received on foreign threads
#ifdef WIN32
void test5337() {}
#else
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);
}
#endif
// issue 5603
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; }
// issue 5740
int test5740a(void), test5740b(void);
// issue 5986
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);
}
// issue 6128
// Test handling of #defined names in clang.
// NOTE: Must use hex, or else a shortcut for decimals
// in cgo avoids trying to pass this to clang.
#define X 0x1
// issue 6472
typedef struct
{
struct
{
int x;
} y[16];
} z;
// 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).
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"
// issue 6907
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;
}
// issue 7560
typedef struct {
char x;
long y;
} __attribute__((__packed__)) misaligned;
int
offset7560(void)
{
return (uintptr_t)&((misaligned*)0)->y;
}
// issue 7786
// No runtime test, just make sure that typedef and struct/union/class are interchangeable at compile time.
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) {}
// issue 8092
// Test that linker defined symbols (e.g., text, data) don't
// conflict with C symbols.
char text[] = "text";
char data[] = "data";
char *ctext(void) { return text; }
char *cdata(void) { return data; }
// issue 8428
// Cgo inconsistently translated zero size arrays.
struct issue8428one {
char b;
char rest[];
};
struct issue8428two {
void *p;
char b;
char rest[0];
char pad;
};
struct issue8428three {
char w[1][2][3][0];
char x[2][3][0][1];
char y[3][0][1][2];
char z[0][1][2][3];
};
// issue 8331 part 1 - part 2 in testx.go
// A typedef of an unnamed struct is the same struct when
// #include'd twice. No runtime test; just make sure it compiles.
#include "issue8331.h"
// issue 8368 and 8441
// Recursive struct definitions didn't work.
// No runtime test; just make sure it compiles.
typedef struct one one;
typedef struct two two;
struct one {
two *x;
};
struct two {
one *x;
};
// issue 8811
extern int issue8811Initialized;
extern void issue8811Init();
void issue8811Execute() {
if(!issue8811Initialized)
issue8811Init();
}
// issue 9557
struct issue9557_t {
int a;
} test9557bar = { 42 };
struct issue9557_t *issue9557foo = &test9557bar;
// issue 10303
// Pointers passed to C were not marked as escaping (bug in cgo).
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;
}
// issue 11925
// Structs with zero-length trailing fields are now padded by the Go compiler.
struct a11925 {
int i;
char a[0];
char b[0];
};
struct b11925 {
int i;
char a[0];
char b[];
};
// issue 12030
void issue12030conv(char *buf, double x) {
sprintf(buf, "d=%g", x);
}
// issue 14838
int check_cbytes(char *b, size_t l) {
int i;
for (i = 0; i < l; i++) {
if (b[i] != i) {
return 0;
}
}
return 1;
}
// issue 17065
// Test that C symbols larger than a page play nicely with the race detector.
int ii[65537];
// issue 17537
// The void* cast introduced by cgo to avoid problems
// with const/volatile qualifiers breaks C preprocessor macros that
// emulate functions.
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;
}
// issue 17723
// API compatibility checks
typedef char *cstring_pointer;
static void cstring_pointer_fun(cstring_pointer dummy) { }
const char *api_hello = "hello!";
// 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) {
}
// issue 18126
// cgo check of void function returning errno.
void Issue18126C(void **p) {}
// issue 18720
#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;
}
// issue 20129
int issue20129 = 0;
typedef void issue20129Void;
issue20129Void issue20129Foo() {
issue20129 = 1;
}
typedef issue20129Void issue20129Void2;
issue20129Void2 issue20129Bar() {
issue20129 = 2;
}
// issue 20369
#define XUINT64_MAX 18446744073709551615ULL
// issue 21668
// Fail to guess the kind of the constant "x".
// No runtime test; just make sure it compiles.
const int x21668 = 42;
// issue 21708
#define CAST_TO_INT64 (int64_t)(-1)
// 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; }
// issue 22906
// It's going to be hard to include a whole real JVM to test this.
// So we'll simulate a really easy JVM using just the parts we need.
// This is the relevant part of jni.h.
struct _jobject;
typedef struct _jobject *jobject;
typedef jobject jclass;
typedef jobject jthrowable;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jarray jobjectArray;
typedef jobject jweak;
// Note: jvalue is already a non-pointer type due to it being a C union.
// issue 22958
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;
// issue 23356
int a(void) { return 5; };
int r(void) { return 3; };
// issue 23720
typedef int *issue23720A;
typedef const int *issue23720B;
void issue23720F(issue23720B a) {}
// issue 24206
#if defined(__linux__) && defined(__x86_64__)
#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;
}
#else
char *dangerousString1() { return NULL; }
char *dangerousString2() { return NULL; }
#endif
// issue 26066
const unsigned long long int issue26066 = (const unsigned long long) -1;
// issue 26517
// 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.
typedef va_list TypeOne;
typedef char *TypeTwo;
// issue 28540
static void twoargs1(void *p, int n) {}
static void *twoargs2() { return 0; }
static int twoargs3(void * p) { return 0; }
// issue 28545
// Failed to add type conversion for negative constant.
static void issue28545F(char **p, int n, complex double a) {}
// issue 28772 part 1 - part 2 in testx.go
// Failed to add type conversion for Go constant set to C constant.
// No runtime test; just make sure it compiles.
#define issue28772Constant 1
// issue 28896
// cgo was incorrectly adding padding after a packed struct.
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();
}
}
// issue 29748
typedef struct { char **p; } S29748;
static int f29748(S29748 *p) { return 0; }
// issue 29781
// Error with newline inserted into constant expression.
// Compilation test only, nothing to run.
static void issue29781F(char **p, int n) {}
#define ISSUE29781C 0
// issue 29878
uint64_t issue29878exported(int8_t); // prototype must match
int16_t issue29878function(uint32_t arg) { return issue29878exported(arg); }
*/
import "C"
import (
"context"
"fmt"
"math"
"math/rand"
"os"
"os/signal"
"reflect"
"runtime"
"sync"
"syscall"
"testing"
"time"
"unsafe"
)
// alignment
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)
}
}
// api
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)
}
}
}
// basic test cases
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)
}
}
// 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) {}
// complex alignment
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)
}
}
// constants and pointer checking
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)
}
// duplicate symbol
func duplicateSymbols() {
fmt.Printf("%v %v %v\n", C.base_symbol, C.alias_one, C.alias_two)
}
// environment
// 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)
}
}
// function pointer variables
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)
}
}
// issue 1222
type AsyncEvent struct {
event C.struct_ibv_async_event
}
// issue 1635
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)
}
}
// 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)
}
}
// issue 3250
func test3250(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("not applicable on windows")
}
t.Skip("skipped, see golang.org/issue/5885")
var (
thres = 1
sig = syscall_dot_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)
}
}
// issue 3261
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
}
}
}
// issue 3729
func test3729(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("skipping on windows")
}
_, 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)
}
}
// issue 3945
func testPrintf(t *testing.T) {
C.say()
}
// issue 4054
var issue4054a = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J}
// issue 4339
func test4339(t *testing.T) {
C.handle4339(&C.exported4339)
}
// issue 4417
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)
}
}
// issue 4857
func test4857() {
_ = C.issue4857()
}
// issue 5224
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)
}
}
// issue 5227
func test5227(t *testing.T) {
C.init()
}
func selectfont() C.Fontinfo {
return C.SansTypeface
}
// issue 5242
func test5242(t *testing.T) {
if got := C.issue5242(C.foo{}, C.bar{}); got != 5242 {
t.Errorf("got %v", got)
}
}
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)
}
}
}
// issue 5337
func test5337(t *testing.T) {
C.test5337()
}
// issue 5740
func test5740(t *testing.T) {
if v := C.test5740a() + C.test5740b(); v != 5 {
t.Errorf("expected 5, got %v", v)
}
}
// issue 5986
func test5986(t *testing.T) {
C.output5986()
}
// issue 6128
func test6128() {
// nothing to run, just make sure this compiles.
_ = C.X
}
// issue 6390
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)
}
func test6472() {
// nothing to run, just make sure this compiles
s := new(C.z)
println(s.y[0].x)
}
// issue 6506
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
}
// issue 6612
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")
}
}
// issue 6907
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)
}
}
// issue 7560
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))
}
}
}
// issue 7786
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)
}
// issue 8092
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)
}
}
}
// issues 8368 and 8441
func issue8368(one *C.struct_one, two *C.struct_two) {
}
func issue8441(one *C.one, two *C.two) {
issue8441(two.x, one.x)
}
// issue 8428
var _ = C.struct_issue8428one{
b: C.char(0),
// The trailing rest field is not available in cgo.
// See issue 11925.
// rest: [0]C.char{},
}
var _ = C.struct_issue8428two{
p: unsafe.Pointer(nil),
b: C.char(0),
rest: [0]C.char{},
}
var _ = C.struct_issue8428three{
w: [1][2][3][0]C.char{},
x: [2][3][0][1]C.char{},
y: [3][0][1][2]C.char{},
z: [0][1][2][3]C.char{},
}
// issue 8811
func test8811(t *testing.T) {
C.issue8811Execute()
}
// issue 9557
func test9557(t *testing.T) {
// implicitly dereference a Go variable
foo := C.issue9557foo
if v := foo.a; v != 42 {
t.Fatalf("foo.a expected 42, but got %d", v)
}
// explicitly dereference a C variable
if v := (*C.issue9557foo).a; v != 42 {
t.Fatalf("(*C.issue9557foo).a expected 42, but is %d", v)
}
// implicitly dereference a C variable
if v := C.issue9557foo.a; v != 42 {
t.Fatalf("C.issue9557foo.a expected 42, but is %d", v)
}
}
// issue 8331 part 1
func issue8331a() C.issue8331 {
return issue8331Var
}
// issue 10303
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")
}
}
// issue 11925
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{}))
}
}
// issue 12030
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)
}
}
}
// issue 13402
var _ C.complexfloat
var _ C.complexdouble
// issue 13930
// Test that cgo's multiple-value special form for
// C function calls works in variable declaration statements.
var _, _ = C.abs(0)
// issue 14838
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)))[:])
}
}
// issue 17065
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]
}
}
// issue 17537
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))
}
// issue 17723
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)
}
// issue 18126
func test18126(t *testing.T) {
p := C.malloc(1)
_, err := C.Issue18126C(&p)
C.free(p)
_ = err
}
// issue 18720
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)
}
}
// issue 20129
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)
}
}
// issue 20369
func test20369(t *testing.T) {
if C.XUINT64_MAX != math.MaxUint64 {
t.Fatalf("got %v, want %v", uint64(C.XUINT64_MAX), uint64(math.MaxUint64))
}
}
// issue 21668
var issue21668_X = C.x21668
// issue 21708
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)
}
}
// issue 21809
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)
}
}
// issue 22906
func test22906(t *testing.T) {
var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types.
_ = x1
var x2 C.jclass = 0
_ = x2
var x3 C.jthrowable = 0
_ = x3
var x4 C.jstring = 0
_ = x4
var x5 C.jarray = 0
_ = x5
var x6 C.jbooleanArray = 0
_ = x6
var x7 C.jbyteArray = 0
_ = x7
var x8 C.jcharArray = 0
_ = x8
var x9 C.jshortArray = 0
_ = x9
var x10 C.jintArray = 0
_ = x10
var x11 C.jlongArray = 0
_ = x11
var x12 C.jfloatArray = 0
_ = x12
var x13 C.jdoubleArray = 0
_ = x13
var x14 C.jobjectArray = 0
_ = x14
var x15 C.jweak = 0
_ = x15
}
// issue 22958
// Nothing to run, just make sure this compiles.
var Vissue22958 C.issue22958Type
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)
}
}
// issue 23720
func Issue23720F() {
var x C.issue23720A
C.issue23720F(x)
}
// issue 24206
func test24206(t *testing.T) {
if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
t.Skipf("skipping on %s/%s", runtime.GOOS, runtime.GOARCH)
}
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)
}
}
// issue 25143
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)
}
}
// issue 26066
// Wrong type of constant with GCC 8 and newer.
func test26066(t *testing.T) {
var i = int64(C.issue26066)
if i != -1 {
t.Errorf("got %d, want -1", i)
}
}
// issue 26517
var a C.TypeOne
var b C.TypeTwo
// issue 27660
// Stress the interaction between the race detector and cgo in an
// attempt to reproduce the memory corruption described in #27660.
// The bug was very timing sensitive; at the time of writing this
// test would only trigger the bug about once out of every five runs.
func test27660(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
ints := make([]int, 100)
locks := make([]sync.Mutex, 100)
// Slowly create threads so that ThreadSanitizer is forced to
// frequently resize its SyncClocks.
for i := 0; i < 100; i++ {
go func() {
for ctx.Err() == nil {
// Sleep in C for long enough that it is likely that the runtime
// will retake this goroutine's currently wired P.
C.usleep(1000 /* 1ms */)
runtime.Gosched() // avoid starvation (see #28701)
}
}()
go func() {
// Trigger lots of synchronization and memory reads/writes to
// increase the likelihood that the race described in #27660
// results in corruption of ThreadSanitizer's internal state
// and thus an assertion failure or segfault.
for ctx.Err() == nil {
j := rand.Intn(100)
locks[j].Lock()
ints[j]++
locks[j].Unlock()
}
}()
time.Sleep(time.Millisecond)
}
}
// issue 28540
func twoargsF() {
v := []string{}
C.twoargs1(C.twoargs2(), C.twoargs3(unsafe.Pointer(&v)))
}
// issue 28545
func issue28545G(p **C.char) {
C.issue28545F(p, -1, (0))
C.issue28545F(p, 2+3, complex(1, 1))
C.issue28545F(p, issue28772Constant, issue28772Constant2)
}
// issue 28772 part 1 - part 2 in testx.go
const issue28772Constant = C.issue28772Constant
// issue 28896
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)
}
}
}
// issue 29383
// cgo's /*line*/ comments failed when inserted after '/',
// because the result looked like a "//" comment.
// No runtime test; just make sure it compiles.
func Issue29383(n, size uint) int {
if ^C.size_t(0)/C.size_t(n) < C.size_t(size) {
return 0
}
return 0
}
// issue 29748
// Error handling a struct initializer that requires pointer checking.
// Compilation test only, nothing to run.
var Vissue29748 = C.f29748(&C.S29748{
nil,
})
func Fissue299748() {
C.f29748(&C.S29748{
nil,
})
}
// issue 29781
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))
}
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)
}
}
// issue 30065
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')
}
}