1// Copyright 2010 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Test cases for cgo. 6// Both the import "C" prologue and the main file are sorted by issue number. 7// This file contains C definitions (not just declarations) 8// and so it must NOT contain any //export directives on Go functions. 9// See testx.go for exports. 10 11package cgotest 12 13/* 14#include <complex.h> 15#include <math.h> 16#include <stdarg.h> 17#include <stdbool.h> 18#include <stddef.h> 19#include <stdint.h> 20#include <stdio.h> 21#include <stdlib.h> 22#include <string.h> 23#include <unistd.h> 24#include <sys/stat.h> 25#include <errno.h> 26#cgo LDFLAGS: -lm 27 28#ifndef WIN32 29#include <pthread.h> 30#include <signal.h> 31#endif 32 33// alignment tests 34 35typedef unsigned char Uint8; 36typedef unsigned short Uint16; 37 38typedef enum { 39 MOD1 = 0x0000, 40 MODX = 0x8000 41} SDLMod; 42 43typedef enum { 44 A1 = 1, 45 B1 = 322, 46 SDLK_LAST 47} SDLKey; 48 49typedef struct SDL_keysym { 50 Uint8 scancode; 51 SDLKey sym; 52 SDLMod mod; 53 Uint16 unicode; 54} SDL_keysym; 55 56typedef struct SDL_KeyboardEvent { 57 Uint8 typ; 58 Uint8 which; 59 Uint8 state; 60 SDL_keysym keysym; 61} SDL_KeyboardEvent; 62 63void makeEvent(SDL_KeyboardEvent *event) { 64 unsigned char *p; 65 int i; 66 67 p = (unsigned char*)event; 68 for (i=0; i<sizeof *event; i++) { 69 p[i] = i; 70 } 71} 72 73int same(SDL_KeyboardEvent* e, Uint8 typ, Uint8 which, Uint8 state, Uint8 scan, SDLKey sym, SDLMod mod, Uint16 uni) { 74 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; 75} 76 77void cTest(SDL_KeyboardEvent *event) { 78 printf("C: %#x %#x %#x %#x %#x %#x %#x\n", event->typ, event->which, event->state, 79 event->keysym.scancode, event->keysym.sym, event->keysym.mod, event->keysym.unicode); 80 fflush(stdout); 81} 82 83// api 84 85const char *greeting = "hello, world"; 86 87// basic test cases 88 89#define SHIFT(x, y) ((x)<<(y)) 90#define KILO SHIFT(1, 10) 91#define UINT32VAL 0xc008427bU 92 93enum E { 94 Enum1 = 1, 95 Enum2 = 2, 96}; 97 98typedef unsigned char cgo_uuid_t[20]; 99 100void uuid_generate(cgo_uuid_t x) { 101 x[0] = 0; 102} 103 104struct S { 105 int x; 106}; 107 108const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"; 109 110extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter); 111 112enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; } 113 114int add(int x, int y) { 115 return x+y; 116}; 117 118// Following mimicks vulkan complex definitions for benchmarking cgocheck overhead. 119 120typedef uint32_t VkFlags; 121typedef VkFlags VkDeviceQueueCreateFlags; 122typedef uint32_t VkStructureType; 123 124typedef struct VkDeviceQueueCreateInfo { 125 VkStructureType sType; 126 const void* pNext; 127 VkDeviceQueueCreateFlags flags; 128 uint32_t queueFamilyIndex; 129 uint32_t queueCount; 130 const float* pQueuePriorities; 131} VkDeviceQueueCreateInfo; 132 133typedef struct VkPhysicalDeviceFeatures { 134 uint32_t bools[56]; 135} VkPhysicalDeviceFeatures; 136 137typedef struct VkDeviceCreateInfo { 138 VkStructureType sType; 139 const void* pNext; 140 VkFlags flags; 141 uint32_t queueCreateInfoCount; 142 const VkDeviceQueueCreateInfo* pQueueCreateInfos; 143 uint32_t enabledLayerCount; 144 const char* const* ppEnabledLayerNames; 145 uint32_t enabledExtensionCount; 146 const char* const* ppEnabledExtensionNames; 147 const VkPhysicalDeviceFeatures* pEnabledFeatures; 148} VkDeviceCreateInfo; 149 150void handleComplexPointer(VkDeviceCreateInfo *a0) {} 151void handleComplexPointer8( 152 VkDeviceCreateInfo *a0, VkDeviceCreateInfo *a1, VkDeviceCreateInfo *a2, VkDeviceCreateInfo *a3, 153 VkDeviceCreateInfo *a4, VkDeviceCreateInfo *a5, VkDeviceCreateInfo *a6, VkDeviceCreateInfo *a7 154) {} 155 156// complex alignment 157 158struct { 159 float x; 160 _Complex float y; 161} cplxAlign = { 3.14, 2.17 }; 162 163// constants and pointer checking 164 165#define CheckConstVal 0 166 167typedef struct { 168 int *p; 169} CheckConstStruct; 170 171static void CheckConstFunc(CheckConstStruct *p, int e) {} 172 173// duplicate symbol 174 175int base_symbol = 0; 176#define alias_one base_symbol 177#define alias_two base_symbol 178 179// function pointer variables 180 181typedef int (*intFunc) (); 182 183int 184bridge_int_func(intFunc f) 185{ 186 return f(); 187} 188 189int fortytwo() 190{ 191 return 42; 192} 193 194// issue 1222 195typedef union { 196 long align; 197} xxpthread_mutex_t; 198struct ibv_async_event { 199 union { 200 int x; 201 } element; 202}; 203struct ibv_context { 204 xxpthread_mutex_t mutex; 205}; 206 207// issue 1635 208// Mac OS X's gcc will generate scattered relocation 2/1 for 209// this function on Darwin/386, and 8l couldn't handle it. 210// this example is in issue 1635 211void scatter() { 212 void *p = scatter; 213 printf("scatter = %p\n", p); 214} 215 216// Adding this explicit extern declaration makes this a test for 217// https://gcc.gnu.org/PR68072 aka https://golang.org/issue/13344 . 218// It used to cause a cgo error when building with GCC 6. 219extern int hola; 220 221// this example is in issue 3253 222int hola = 0; 223int testHola() { return hola; } 224 225// issue 3250 226#ifdef WIN32 227void testSendSIG() {} 228#else 229static void *thread(void *p) { 230 const int M = 100; 231 int i; 232 (void)p; 233 for (i = 0; i < M; i++) { 234 pthread_kill(pthread_self(), SIGCHLD); 235 usleep(rand() % 20 + 5); 236 } 237 return NULL; 238} 239void testSendSIG() { 240 const int N = 20; 241 int i; 242 pthread_t tid[N]; 243 for (i = 0; i < N; i++) { 244 usleep(rand() % 200 + 100); 245 pthread_create(&tid[i], 0, thread, NULL); 246 } 247 for (i = 0; i < N; i++) 248 pthread_join(tid[i], 0); 249} 250#endif 251 252// issue 3261 253// libgcc on ARM might be compiled as thumb code, but our 5l 254// can't handle that, so we have to disable this test on arm. 255#ifdef __ARMEL__ 256int vabs(int x) { 257 puts("testLibgcc is disabled on ARM because 5l cannot handle thumb library."); 258 return (x < 0) ? -x : x; 259} 260#elif defined(__arm64__) && defined(__clang__) 261int vabs(int x) { 262 puts("testLibgcc is disabled on ARM64 with clang due to lack of libgcc."); 263 return (x < 0) ? -x : x; 264} 265#else 266int __absvsi2(int); // dummy prototype for libgcc function 267// we shouldn't name the function abs, as gcc might use 268// the builtin one. 269int vabs(int x) { return __absvsi2(x); } 270#endif 271 272 273// issue 3729 274// access errno from void C function 275const char _expA = 0x42; 276const float _expB = 3.14159; 277const short _expC = 0x55aa; 278const int _expD = 0xdeadbeef; 279 280#ifdef WIN32 281void g(void) {} 282void g2(int x, char a, float b, short c, int d) {} 283#else 284 285void g(void) { 286 errno = E2BIG; 287} 288 289// try to pass some non-trivial arguments to function g2 290void g2(int x, char a, float b, short c, int d) { 291 if (a == _expA && b == _expB && c == _expC && d == _expD) 292 errno = x; 293 else 294 errno = -1; 295} 296#endif 297 298// issue 3945 299// Test that cgo reserves enough stack space during cgo call. 300// See https://golang.org/issue/3945 for details. 301void say() { 302 printf("%s from C\n", "hello"); 303} 304 305// issue 4054 part 1 - other half in testx.go 306 307typedef enum { 308 A = 0, 309 B, 310 C, 311 D, 312 E, 313 F, 314 G, 315 H, 316 II, 317 J, 318} issue4054a; 319 320// issue 4339 321// We've historically permitted #include <>, so test it here. Issue 29333. 322#include <issue4339.h> 323 324// issue 4417 325// cmd/cgo: bool alignment/padding issue. 326// bool alignment is wrong and causing wrong arguments when calling functions. 327static int c_bool(bool a, bool b, int c, bool d, bool e) { 328 return c; 329} 330 331// issue 4857 332#cgo CFLAGS: -Werror 333const struct { int a; } *issue4857() { return (void *)0; } 334 335// issue 5224 336// Test that the #cgo CFLAGS directive works, 337// with and without platform filters. 338#cgo CFLAGS: -DCOMMON_VALUE=123 339#cgo windows CFLAGS: -DIS_WINDOWS=1 340#cgo !windows CFLAGS: -DIS_WINDOWS=0 341int common = COMMON_VALUE; 342int is_windows = IS_WINDOWS; 343 344// issue 5227 345// linker incorrectly treats common symbols and 346// leaves them undefined. 347 348typedef struct { 349 int Count; 350} Fontinfo; 351 352Fontinfo SansTypeface; 353 354extern void init(); 355 356Fontinfo loadfont() { 357 Fontinfo f = {0}; 358 return f; 359} 360 361void init() { 362 SansTypeface = loadfont(); 363} 364 365// issue 5242 366// Cgo incorrectly computed the alignment of structs 367// with no Go accessible fields as 0, and then panicked on 368// modulo-by-zero computations. 369typedef struct { 370} foo; 371 372typedef struct { 373 int x : 1; 374} bar; 375 376int issue5242(foo f, bar b) { 377 return 5242; 378} 379 380// issue 5337 381// Verify that we can withstand SIGPROF received on foreign threads 382 383#ifdef WIN32 384void test5337() {} 385#else 386static void *thread1(void *p) { 387 (void)p; 388 pthread_kill(pthread_self(), SIGPROF); 389 return NULL; 390} 391void test5337() { 392 pthread_t tid; 393 pthread_create(&tid, 0, thread1, NULL); 394 pthread_join(tid, 0); 395} 396#endif 397 398// issue 5603 399 400const long long issue5603exp = 0x12345678; 401long long issue5603foo0() { return issue5603exp; } 402long long issue5603foo1(void *p) { return issue5603exp; } 403long long issue5603foo2(void *p, void *q) { return issue5603exp; } 404long long issue5603foo3(void *p, void *q, void *r) { return issue5603exp; } 405long long issue5603foo4(void *p, void *q, void *r, void *s) { return issue5603exp; } 406 407// issue 5740 408 409int test5740a(void), test5740b(void); 410 411// issue 5986 412static void output5986() 413{ 414 int current_row = 0, row_count = 0; 415 double sum_squares = 0; 416 double d; 417 do { 418 if (current_row == 10) { 419 current_row = 0; 420 } 421 ++row_count; 422 } 423 while (current_row++ != 1); 424 d = sqrt(sum_squares / row_count); 425 printf("sqrt is: %g\n", d); 426} 427 428// issue 6128 429// Test handling of #defined names in clang. 430// NOTE: Must use hex, or else a shortcut for decimals 431// in cgo avoids trying to pass this to clang. 432#define X 0x1 433 434// issue 6472 435typedef struct 436{ 437 struct 438 { 439 int x; 440 } y[16]; 441} z; 442 443// issue 6612 444// Test new scheme for deciding whether C.name is an expression, type, constant. 445// Clang silences some warnings when the name is a #defined macro, so test those too 446// (even though we now use errors exclusively, not warnings). 447 448void myfunc(void) {} 449int myvar = 5; 450const char *mytext = "abcdef"; 451typedef int mytype; 452enum { 453 myenum = 1234, 454}; 455 456#define myfunc_def myfunc 457#define myvar_def myvar 458#define mytext_def mytext 459#define mytype_def mytype 460#define myenum_def myenum 461#define myint_def 12345 462#define myfloat_def 1.5 463#define mystring_def "hello" 464 465// issue 6907 466char* Issue6907CopyString(_GoString_ s) { 467 size_t n; 468 const char *p; 469 char *r; 470 471 n = _GoStringLen(s); 472 p = _GoStringPtr(s); 473 r = malloc(n + 1); 474 memmove(r, p, n); 475 r[n] = '\0'; 476 return r; 477} 478 479// issue 7560 480typedef struct { 481 char x; 482 long y; 483} __attribute__((__packed__)) misaligned; 484 485int 486offset7560(void) 487{ 488 return (uintptr_t)&((misaligned*)0)->y; 489} 490 491// issue 7786 492// No runtime test, just make sure that typedef and struct/union/class are interchangeable at compile time. 493 494struct test7786; 495typedef struct test7786 typedef_test7786; 496void f7786(struct test7786 *ctx) {} 497void g7786(typedef_test7786 *ctx) {} 498 499typedef struct body7786 typedef_body7786; 500struct body7786 { int x; }; 501void b7786(struct body7786 *ctx) {} 502void c7786(typedef_body7786 *ctx) {} 503 504typedef union union7786 typedef_union7786; 505void u7786(union union7786 *ctx) {} 506void v7786(typedef_union7786 *ctx) {} 507 508// issue 8092 509// Test that linker defined symbols (e.g., text, data) don't 510// conflict with C symbols. 511char text[] = "text"; 512char data[] = "data"; 513char *ctext(void) { return text; } 514char *cdata(void) { return data; } 515 516// issue 8428 517// Cgo inconsistently translated zero size arrays. 518 519struct issue8428one { 520 char b; 521 char rest[]; 522}; 523 524struct issue8428two { 525 void *p; 526 char b; 527 char rest[0]; 528 char pad; 529}; 530 531struct issue8428three { 532 char w[1][2][3][0]; 533 char x[2][3][0][1]; 534 char y[3][0][1][2]; 535 char z[0][1][2][3]; 536}; 537 538// issue 8331 part 1 - part 2 in testx.go 539// A typedef of an unnamed struct is the same struct when 540// #include'd twice. No runtime test; just make sure it compiles. 541#include "issue8331.h" 542 543// issue 8368 and 8441 544// Recursive struct definitions didn't work. 545// No runtime test; just make sure it compiles. 546typedef struct one one; 547typedef struct two two; 548struct one { 549 two *x; 550}; 551struct two { 552 one *x; 553}; 554 555// issue 8811 556 557extern int issue8811Initialized; 558extern void issue8811Init(); 559 560void issue8811Execute() { 561 if(!issue8811Initialized) 562 issue8811Init(); 563} 564 565// issue 8945 566 567typedef void (*PFunc8945)(); 568PFunc8945 func8945; 569 570// issue 9557 571 572struct issue9557_t { 573 int a; 574} test9557bar = { 42 }; 575struct issue9557_t *issue9557foo = &test9557bar; 576 577// issue 10303 578// Pointers passed to C were not marked as escaping (bug in cgo). 579 580typedef int *intptr; 581 582void setintstar(int *x) { 583 *x = 1; 584} 585 586void setintptr(intptr x) { 587 *x = 1; 588} 589 590void setvoidptr(void *x) { 591 *(int*)x = 1; 592} 593 594typedef struct Struct Struct; 595struct Struct { 596 int *P; 597}; 598 599void setstruct(Struct s) { 600 *s.P = 1; 601} 602 603// issue 11925 604// Structs with zero-length trailing fields are now padded by the Go compiler. 605 606struct a11925 { 607 int i; 608 char a[0]; 609 char b[0]; 610}; 611 612struct b11925 { 613 int i; 614 char a[0]; 615 char b[]; 616}; 617 618// issue 12030 619void issue12030conv(char *buf, double x) { 620 sprintf(buf, "d=%g", x); 621} 622 623// issue 14838 624 625int check_cbytes(char *b, size_t l) { 626 int i; 627 for (i = 0; i < l; i++) { 628 if (b[i] != i) { 629 return 0; 630 } 631 } 632 return 1; 633} 634 635// issue 17065 636// Test that C symbols larger than a page play nicely with the race detector. 637int ii[65537]; 638 639// issue 17537 640// The void* cast introduced by cgo to avoid problems 641// with const/volatile qualifiers breaks C preprocessor macros that 642// emulate functions. 643 644typedef struct { 645 int i; 646} S17537; 647 648int I17537(S17537 *p); 649 650#define I17537(p) ((p)->i) 651 652// Calling this function used to fail without the cast. 653const int F17537(const char **p) { 654 return **p; 655} 656 657// issue 17723 658// API compatibility checks 659 660typedef char *cstring_pointer; 661static void cstring_pointer_fun(cstring_pointer dummy) { } 662const char *api_hello = "hello!"; 663 664// Calling this function used to trigger an error from the C compiler 665// (issue 18298). 666void F18298(const void *const *p) { 667} 668 669// Test that conversions between typedefs work as they used to. 670typedef const void *T18298_1; 671struct S18298 { int i; }; 672typedef const struct S18298 *T18298_2; 673void G18298(T18298_1 t) { 674} 675 676// issue 18126 677// cgo check of void function returning errno. 678void Issue18126C(void **p) {} 679 680// issue 18720 681 682#define HELLO "hello" 683#define WORLD "world" 684#define HELLO_WORLD HELLO "\000" WORLD 685 686struct foo { char c; }; 687#define SIZE_OF(x) sizeof(x) 688#define SIZE_OF_FOO SIZE_OF(struct foo) 689#define VAR1 VAR 690#define VAR var 691int var = 5; 692 693#define ADDR &var 694 695#define CALL fn() 696int fn(void) { 697 return ++var; 698} 699 700// issue 20129 701 702int issue20129 = 0; 703typedef void issue20129Void; 704issue20129Void issue20129Foo() { 705 issue20129 = 1; 706} 707typedef issue20129Void issue20129Void2; 708issue20129Void2 issue20129Bar() { 709 issue20129 = 2; 710} 711 712// issue 20369 713#define XUINT64_MAX 18446744073709551615ULL 714 715// issue 21668 716// Fail to guess the kind of the constant "x". 717// No runtime test; just make sure it compiles. 718const int x21668 = 42; 719 720// issue 21708 721#define CAST_TO_INT64 (int64_t)(-1) 722 723// issue 21809 724// Compile C `typedef` to go type aliases. 725 726typedef long MySigned_t; 727// tests alias-to-alias 728typedef MySigned_t MySigned2_t; 729long takes_long(long x) { return x * x; } 730MySigned_t takes_typedef(MySigned_t x) { return x * x; } 731 732// issue 22906 733 734// It's going to be hard to include a whole real JVM to test this. 735// So we'll simulate a really easy JVM using just the parts we need. 736// This is the relevant part of jni.h. 737 738struct _jobject; 739 740typedef struct _jobject *jobject; 741typedef jobject jclass; 742typedef jobject jthrowable; 743typedef jobject jstring; 744typedef jobject jarray; 745typedef jarray jbooleanArray; 746typedef jarray jbyteArray; 747typedef jarray jcharArray; 748typedef jarray jshortArray; 749typedef jarray jintArray; 750typedef jarray jlongArray; 751typedef jarray jfloatArray; 752typedef jarray jdoubleArray; 753typedef jarray jobjectArray; 754 755typedef jobject jweak; 756 757// Note: jvalue is already a non-pointer type due to it being a C union. 758 759// issue 22958 760 761typedef struct { 762 unsigned long long f8 : 8; 763 unsigned long long f16 : 16; 764 unsigned long long f24 : 24; 765 unsigned long long f32 : 32; 766 unsigned long long f40 : 40; 767 unsigned long long f48 : 48; 768 unsigned long long f56 : 56; 769 unsigned long long f64 : 64; 770} issue22958Type; 771 772// issue 23356 773int a(void) { return 5; }; 774int r(void) { return 3; }; 775 776// issue 23720 777typedef int *issue23720A; 778typedef const int *issue23720B; 779void issue23720F(issue23720B a) {} 780 781// issue 24206 782#if defined(__linux__) && defined(__x86_64__) 783#include <sys/mman.h> 784// Returns string with null byte at the last valid address 785char* dangerousString1() { 786 int pageSize = 4096; 787 char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); 788 mprotect(data + pageSize,pageSize,PROT_NONE); 789 int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte 790 int i = start; 791 for (; i < pageSize; i++) { 792 data[i] = 'x'; 793 } 794 data[pageSize -1 ] = 0; 795 return data+start; 796} 797 798char* dangerousString2() { 799 int pageSize = 4096; 800 char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0); 801 mprotect(data + 2 * pageSize,pageSize,PROT_NONE); 802 int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte 803 int i = start; 804 for (; i < 2 * pageSize; i++) { 805 data[i] = 'x'; 806 } 807 data[2*pageSize -1 ] = 0; 808 return data+start; 809} 810#else 811char *dangerousString1() { return NULL; } 812char *dangerousString2() { return NULL; } 813#endif 814 815// issue 26066 816const unsigned long long int issue26066 = (const unsigned long long) -1; 817 818// issue 26517 819// Introduce two pointer types which are distinct, but have the same 820// base type. Make sure that both of those pointer types get resolved 821// correctly. Before the fix for 26517 if one of these pointer types 822// was resolved before the other one was processed, the second one 823// would never be resolved. 824// Before this issue was fixed this test failed on Windows, 825// where va_list expands to a named char* type. 826typedef va_list TypeOne; 827typedef char *TypeTwo; 828 829// issue 28540 830 831static void twoargs1(void *p, int n) {} 832static void *twoargs2() { return 0; } 833static int twoargs3(void * p) { return 0; } 834 835// issue 28545 836// Failed to add type conversion for negative constant. 837 838static void issue28545F(char **p, int n, complex double a) {} 839 840// issue 28772 part 1 - part 2 in testx.go 841// Failed to add type conversion for Go constant set to C constant. 842// No runtime test; just make sure it compiles. 843 844#define issue28772Constant 1 845 846// issue 28896 847// cgo was incorrectly adding padding after a packed struct. 848typedef struct { 849 void *f1; 850 uint32_t f2; 851} __attribute__((__packed__)) innerPacked; 852 853typedef struct { 854 innerPacked g1; 855 uint64_t g2; 856} outerPacked; 857 858typedef struct { 859 void *f1; 860 uint32_t f2; 861} innerUnpacked; 862 863typedef struct { 864 innerUnpacked g1; 865 uint64_t g2; 866} outerUnpacked; 867 868size_t offset(int x) { 869 switch (x) { 870 case 0: 871 return offsetof(innerPacked, f2); 872 case 1: 873 return offsetof(outerPacked, g2); 874 case 2: 875 return offsetof(innerUnpacked, f2); 876 case 3: 877 return offsetof(outerUnpacked, g2); 878 default: 879 abort(); 880 } 881} 882 883// issue 29748 884 885typedef struct { char **p; } S29748; 886static int f29748(S29748 *p) { return 0; } 887 888// issue 29781 889// Error with newline inserted into constant expression. 890// Compilation test only, nothing to run. 891 892static void issue29781F(char **p, int n) {} 893#define ISSUE29781C 0 894 895// issue 31093 896static uint16_t issue31093F(uint16_t v) { return v; } 897 898// issue 32579 899typedef struct S32579 { unsigned char data[1]; } S32579; 900*/ 901import "C" 902 903import ( 904 "context" 905 "fmt" 906 "math" 907 "math/rand" 908 "os" 909 "os/signal" 910 "reflect" 911 "runtime" 912 "sync" 913 "syscall" 914 "testing" 915 "time" 916 "unsafe" 917) 918 919// alignment 920 921func testAlign(t *testing.T) { 922 var evt C.SDL_KeyboardEvent 923 C.makeEvent(&evt) 924 if C.same(&evt, evt.typ, evt.which, evt.state, evt.keysym.scancode, evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) == 0 { 925 t.Error("*** bad alignment") 926 C.cTest(&evt) 927 t.Errorf("Go: %#x %#x %#x %#x %#x %#x %#x\n", 928 evt.typ, evt.which, evt.state, evt.keysym.scancode, 929 evt.keysym.sym, evt.keysym.mod, evt.keysym.unicode) 930 t.Error(evt) 931 } 932} 933 934// api 935 936const greeting = "hello, world" 937 938type testPair struct { 939 Name string 940 Got, Want interface{} 941} 942 943var testPairs = []testPair{ 944 {"GoString", C.GoString(C.greeting), greeting}, 945 {"GoStringN", C.GoStringN(C.greeting, 5), greeting[:5]}, 946 {"GoBytes", C.GoBytes(unsafe.Pointer(C.greeting), 5), []byte(greeting[:5])}, 947} 948 949func testHelpers(t *testing.T) { 950 for _, pair := range testPairs { 951 if !reflect.DeepEqual(pair.Got, pair.Want) { 952 t.Errorf("%s: got %#v, want %#v", pair.Name, pair.Got, pair.Want) 953 } 954 } 955} 956 957// basic test cases 958 959const EINVAL = C.EINVAL /* test #define */ 960 961var KILO = C.KILO 962 963func uuidgen() { 964 var uuid C.cgo_uuid_t 965 C.uuid_generate(&uuid[0]) 966} 967 968func Strtol(s string, base int) (int, error) { 969 p := C.CString(s) 970 n, err := C.strtol(p, nil, C.int(base)) 971 C.free(unsafe.Pointer(p)) 972 return int(n), err 973} 974 975func Atol(s string) int { 976 p := C.CString(s) 977 n := C.atol(p) 978 C.free(unsafe.Pointer(p)) 979 return int(n) 980} 981 982func testConst(t *testing.T) { 983 C.myConstFunc(nil, 0, nil) 984} 985 986func testEnum(t *testing.T) { 987 if C.Enum1 != 1 || C.Enum2 != 2 { 988 t.Error("bad enum", C.Enum1, C.Enum2) 989 } 990} 991 992func testAtol(t *testing.T) { 993 l := Atol("123") 994 if l != 123 { 995 t.Error("Atol 123: ", l) 996 } 997} 998 999func testErrno(t *testing.T) { 1000 p := C.CString("no-such-file") 1001 m := C.CString("r") 1002 f, err := C.fopen(p, m) 1003 C.free(unsafe.Pointer(p)) 1004 C.free(unsafe.Pointer(m)) 1005 if err == nil { 1006 C.fclose(f) 1007 t.Fatalf("C.fopen: should fail") 1008 } 1009 if err != syscall.ENOENT { 1010 t.Fatalf("C.fopen: unexpected error: %v", err) 1011 } 1012} 1013 1014func testMultipleAssign(t *testing.T) { 1015 p := C.CString("234") 1016 n, m := C.strtol(p, nil, 345), C.strtol(p, nil, 10) 1017 if runtime.GOOS == "openbsd" { 1018 // Bug in OpenBSD strtol(3) - base > 36 succeeds. 1019 if (n != 0 && n != 239089) || m != 234 { 1020 t.Fatal("Strtol x2: ", n, m) 1021 } 1022 } else if n != 0 || m != 234 { 1023 t.Fatal("Strtol x2: ", n, m) 1024 } 1025 C.free(unsafe.Pointer(p)) 1026} 1027 1028var ( 1029 cuint = (C.uint)(0) 1030 culong C.ulong 1031 cchar C.char 1032) 1033 1034type Context struct { 1035 ctx *C.struct_ibv_context 1036} 1037 1038func benchCgoCall(b *testing.B) { 1039 b.Run("add-int", func(b *testing.B) { 1040 const x = C.int(2) 1041 const y = C.int(3) 1042 1043 for i := 0; i < b.N; i++ { 1044 C.add(x, y) 1045 } 1046 }) 1047 1048 b.Run("one-pointer", func(b *testing.B) { 1049 var a0 C.VkDeviceCreateInfo 1050 for i := 0; i < b.N; i++ { 1051 C.handleComplexPointer(&a0) 1052 } 1053 }) 1054 b.Run("eight-pointers", func(b *testing.B) { 1055 var a0, a1, a2, a3, a4, a5, a6, a7 C.VkDeviceCreateInfo 1056 for i := 0; i < b.N; i++ { 1057 C.handleComplexPointer8(&a0, &a1, &a2, &a3, &a4, &a5, &a6, &a7) 1058 } 1059 }) 1060 b.Run("eight-pointers-nil", func(b *testing.B) { 1061 var a0, a1, a2, a3, a4, a5, a6, a7 *C.VkDeviceCreateInfo 1062 for i := 0; i < b.N; i++ { 1063 C.handleComplexPointer8(a0, a1, a2, a3, a4, a5, a6, a7) 1064 } 1065 }) 1066 b.Run("eight-pointers-array", func(b *testing.B) { 1067 var a [8]C.VkDeviceCreateInfo 1068 for i := 0; i < b.N; i++ { 1069 C.handleComplexPointer8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]) 1070 } 1071 }) 1072 b.Run("eight-pointers-slice", func(b *testing.B) { 1073 a := make([]C.VkDeviceCreateInfo, 8) 1074 for i := 0; i < b.N; i++ { 1075 C.handleComplexPointer8(&a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]) 1076 } 1077 }) 1078} 1079 1080// Benchmark measuring overhead from Go to C and back to Go (via a callback) 1081func benchCallback(b *testing.B) { 1082 var x = false 1083 for i := 0; i < b.N; i++ { 1084 nestedCall(func() { x = true }) 1085 } 1086 if !x { 1087 b.Fatal("nestedCall was not invoked") 1088 } 1089} 1090 1091var sinkString string 1092 1093func benchGoString(b *testing.B) { 1094 for i := 0; i < b.N; i++ { 1095 sinkString = C.GoString(C.cstr) 1096 } 1097 const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890" 1098 if sinkString != want { 1099 b.Fatalf("%q != %q", sinkString, want) 1100 } 1101} 1102 1103// Static (build-time) test that syntax traversal visits all operands of s[i:j:k]. 1104func sliceOperands(array [2000]int) { 1105 _ = array[C.KILO:C.KILO:C.KILO] // no type error 1106} 1107 1108// set in cgo_thread_lock.go init 1109var testThreadLockFunc = func(*testing.T) {} 1110 1111// complex alignment 1112 1113func TestComplexAlign(t *testing.T) { 1114 if C.cplxAlign.x != 3.14 { 1115 t.Errorf("got %v, expected 3.14", C.cplxAlign.x) 1116 } 1117 if C.cplxAlign.y != 2.17 { 1118 t.Errorf("got %v, expected 2.17", C.cplxAlign.y) 1119 } 1120} 1121 1122// constants and pointer checking 1123 1124func testCheckConst(t *testing.T) { 1125 // The test is that this compiles successfully. 1126 p := C.malloc(C.size_t(unsafe.Sizeof(C.int(0)))) 1127 defer C.free(p) 1128 C.CheckConstFunc(&C.CheckConstStruct{(*C.int)(p)}, C.CheckConstVal) 1129} 1130 1131// duplicate symbol 1132 1133func duplicateSymbols() { 1134 fmt.Printf("%v %v %v\n", C.base_symbol, C.alias_one, C.alias_two) 1135} 1136 1137// environment 1138 1139// This is really an os package test but here for convenience. 1140func testSetEnv(t *testing.T) { 1141 if runtime.GOOS == "windows" { 1142 // Go uses SetEnvironmentVariable on windows. However, 1143 // C runtime takes a *copy* at process startup of the 1144 // OS environment, and stores it in environ/envp. 1145 // It is this copy that getenv/putenv manipulate. 1146 t.Logf("skipping test") 1147 return 1148 } 1149 const key = "CGO_OS_TEST_KEY" 1150 const val = "CGO_OS_TEST_VALUE" 1151 os.Setenv(key, val) 1152 keyc := C.CString(key) 1153 defer C.free(unsafe.Pointer(keyc)) 1154 v := C.getenv(keyc) 1155 if uintptr(unsafe.Pointer(v)) == 0 { 1156 t.Fatal("getenv returned NULL") 1157 } 1158 vs := C.GoString(v) 1159 if vs != val { 1160 t.Fatalf("getenv() = %q; want %q", vs, val) 1161 } 1162} 1163 1164// function pointer variables 1165 1166func callBridge(f C.intFunc) int { 1167 return int(C.bridge_int_func(f)) 1168} 1169 1170func callCBridge(f C.intFunc) C.int { 1171 return C.bridge_int_func(f) 1172} 1173 1174func testFpVar(t *testing.T) { 1175 const expected = 42 1176 f := C.intFunc(C.fortytwo) 1177 res1 := C.bridge_int_func(f) 1178 if r1 := int(res1); r1 != expected { 1179 t.Errorf("got %d, want %d", r1, expected) 1180 } 1181 res2 := callCBridge(f) 1182 if r2 := int(res2); r2 != expected { 1183 t.Errorf("got %d, want %d", r2, expected) 1184 } 1185 r3 := callBridge(f) 1186 if r3 != expected { 1187 t.Errorf("got %d, want %d", r3, expected) 1188 } 1189} 1190 1191// issue 1222 1192type AsyncEvent struct { 1193 event C.struct_ibv_async_event 1194} 1195 1196// issue 1635 1197 1198func test1635(t *testing.T) { 1199 C.scatter() 1200 if v := C.hola; v != 0 { 1201 t.Fatalf("C.hola is %d, should be 0", v) 1202 } 1203 if v := C.testHola(); v != 0 { 1204 t.Fatalf("C.testHola() is %d, should be 0", v) 1205 } 1206} 1207 1208// issue 2470 1209 1210func testUnsignedInt(t *testing.T) { 1211 a := (int64)(C.UINT32VAL) 1212 b := (int64)(0xc008427b) 1213 if a != b { 1214 t.Errorf("Incorrect unsigned int - got %x, want %x", a, b) 1215 } 1216} 1217 1218// issue 3250 1219 1220func test3250(t *testing.T) { 1221 if runtime.GOOS == "windows" { 1222 t.Skip("not applicable on windows") 1223 } 1224 1225 t.Skip("skipped, see golang.org/issue/5885") 1226 var ( 1227 thres = 1 1228 sig = syscall_dot_SIGCHLD 1229 ) 1230 type result struct { 1231 n int 1232 sig os.Signal 1233 } 1234 var ( 1235 sigCh = make(chan os.Signal, 10) 1236 waitStart = make(chan struct{}) 1237 waitDone = make(chan result) 1238 ) 1239 1240 signal.Notify(sigCh, sig) 1241 1242 go func() { 1243 n := 0 1244 alarm := time.After(time.Second * 3) 1245 for { 1246 select { 1247 case <-waitStart: 1248 waitStart = nil 1249 case v := <-sigCh: 1250 n++ 1251 if v != sig || n > thres { 1252 waitDone <- result{n, v} 1253 return 1254 } 1255 case <-alarm: 1256 waitDone <- result{n, sig} 1257 return 1258 } 1259 } 1260 }() 1261 1262 waitStart <- struct{}{} 1263 C.testSendSIG() 1264 r := <-waitDone 1265 if r.sig != sig { 1266 t.Fatalf("received signal %v, but want %v", r.sig, sig) 1267 } 1268 t.Logf("got %d signals\n", r.n) 1269 if r.n <= thres { 1270 t.Fatalf("expected more than %d", thres) 1271 } 1272} 1273 1274// issue 3261 1275 1276func testLibgcc(t *testing.T) { 1277 var table = []struct { 1278 in, out C.int 1279 }{ 1280 {0, 0}, 1281 {1, 1}, 1282 {-42, 42}, 1283 {1000300, 1000300}, 1284 {1 - 1<<31, 1<<31 - 1}, 1285 } 1286 for _, v := range table { 1287 if o := C.vabs(v.in); o != v.out { 1288 t.Fatalf("abs(%d) got %d, should be %d", v.in, o, v.out) 1289 return 1290 } 1291 } 1292} 1293 1294// issue 3729 1295 1296func test3729(t *testing.T) { 1297 if runtime.GOOS == "windows" { 1298 t.Skip("skipping on windows") 1299 } 1300 1301 _, e := C.g() 1302 if e != syscall.E2BIG { 1303 t.Errorf("got %q, expect %q", e, syscall.E2BIG) 1304 } 1305 _, e = C.g2(C.EINVAL, C._expA, C._expB, C._expC, C._expD) 1306 if e != syscall.EINVAL { 1307 t.Errorf("got %q, expect %q", e, syscall.EINVAL) 1308 } 1309} 1310 1311// issue 3945 1312 1313func testPrintf(t *testing.T) { 1314 C.say() 1315} 1316 1317// issue 4054 1318 1319var issue4054a = []int{C.A, C.B, C.C, C.D, C.E, C.F, C.G, C.H, C.I, C.J} 1320 1321// issue 4339 1322 1323func test4339(t *testing.T) { 1324 C.handle4339(&C.exported4339) 1325} 1326 1327// issue 4417 1328 1329func testBoolAlign(t *testing.T) { 1330 b := C.c_bool(true, true, 10, true, false) 1331 if b != 10 { 1332 t.Fatalf("found %d expected 10\n", b) 1333 } 1334 b = C.c_bool(true, true, 5, true, true) 1335 if b != 5 { 1336 t.Fatalf("found %d expected 5\n", b) 1337 } 1338 b = C.c_bool(true, true, 3, true, false) 1339 if b != 3 { 1340 t.Fatalf("found %d expected 3\n", b) 1341 } 1342 b = C.c_bool(false, false, 1, true, false) 1343 if b != 1 { 1344 t.Fatalf("found %d expected 1\n", b) 1345 } 1346 b = C.c_bool(false, true, 200, true, false) 1347 if b != 200 { 1348 t.Fatalf("found %d expected 200\n", b) 1349 } 1350} 1351 1352// issue 4857 1353 1354func test4857() { 1355 _ = C.issue4857() 1356} 1357 1358// issue 5224 1359 1360func testCflags(t *testing.T) { 1361 is_windows := C.is_windows == 1 1362 if is_windows != (runtime.GOOS == "windows") { 1363 t.Errorf("is_windows: %v, runtime.GOOS: %s", is_windows, runtime.GOOS) 1364 } 1365 if C.common != 123 { 1366 t.Errorf("common: %v (expected 123)", C.common) 1367 } 1368} 1369 1370// issue 5227 1371 1372func test5227(t *testing.T) { 1373 C.init() 1374} 1375 1376func selectfont() C.Fontinfo { 1377 return C.SansTypeface 1378} 1379 1380// issue 5242 1381 1382func test5242(t *testing.T) { 1383 if got := C.issue5242(C.foo{}, C.bar{}); got != 5242 { 1384 t.Errorf("got %v", got) 1385 } 1386} 1387 1388func test5603(t *testing.T) { 1389 var x [5]int64 1390 exp := int64(C.issue5603exp) 1391 x[0] = int64(C.issue5603foo0()) 1392 x[1] = int64(C.issue5603foo1(nil)) 1393 x[2] = int64(C.issue5603foo2(nil, nil)) 1394 x[3] = int64(C.issue5603foo3(nil, nil, nil)) 1395 x[4] = int64(C.issue5603foo4(nil, nil, nil, nil)) 1396 for i, v := range x { 1397 if v != exp { 1398 t.Errorf("issue5603foo%d() returns %v, expected %v", i, v, exp) 1399 } 1400 } 1401} 1402 1403// issue 5337 1404 1405func test5337(t *testing.T) { 1406 C.test5337() 1407} 1408 1409// issue 5740 1410 1411func test5740(t *testing.T) { 1412 if v := C.test5740a() + C.test5740b(); v != 5 { 1413 t.Errorf("expected 5, got %v", v) 1414 } 1415} 1416 1417// issue 5986 1418 1419func test5986(t *testing.T) { 1420 C.output5986() 1421} 1422 1423// issue 6128 1424 1425func test6128() { 1426 // nothing to run, just make sure this compiles. 1427 _ = C.X 1428} 1429 1430// issue 6390 1431 1432func test6390(t *testing.T) { 1433 p1 := C.malloc(1024) 1434 if p1 == nil { 1435 t.Fatalf("C.malloc(1024) returned nil") 1436 } 1437 p2 := C.malloc(0) 1438 if p2 == nil { 1439 t.Fatalf("C.malloc(0) returned nil") 1440 } 1441 C.free(p1) 1442 C.free(p2) 1443} 1444 1445func test6472() { 1446 // nothing to run, just make sure this compiles 1447 s := new(C.z) 1448 println(s.y[0].x) 1449} 1450 1451// issue 6506 1452 1453func test6506() { 1454 // nothing to run, just make sure this compiles 1455 var x C.size_t 1456 1457 C.calloc(x, x) 1458 C.malloc(x) 1459 C.realloc(nil, x) 1460 C.memcpy(nil, nil, x) 1461 C.memcmp(nil, nil, x) 1462 C.memmove(nil, nil, x) 1463 C.strncpy(nil, nil, x) 1464 C.strncmp(nil, nil, x) 1465 C.strncat(nil, nil, x) 1466 x = C.strxfrm(nil, nil, x) 1467 C.memchr(nil, 0, x) 1468 x = C.strcspn(nil, nil) 1469 x = C.strspn(nil, nil) 1470 C.memset(nil, 0, x) 1471 x = C.strlen(nil) 1472 _ = x 1473} 1474 1475// issue 6612 1476 1477func testNaming(t *testing.T) { 1478 C.myfunc() 1479 C.myfunc_def() 1480 if v := C.myvar; v != 5 { 1481 t.Errorf("C.myvar = %d, want 5", v) 1482 } 1483 if v := C.myvar_def; v != 5 { 1484 t.Errorf("C.myvar_def = %d, want 5", v) 1485 } 1486 if s := C.GoString(C.mytext); s != "abcdef" { 1487 t.Errorf("C.mytext = %q, want %q", s, "abcdef") 1488 } 1489 if s := C.GoString(C.mytext_def); s != "abcdef" { 1490 t.Errorf("C.mytext_def = %q, want %q", s, "abcdef") 1491 } 1492 if c := C.myenum; c != 1234 { 1493 t.Errorf("C.myenum = %v, want 1234", c) 1494 } 1495 if c := C.myenum_def; c != 1234 { 1496 t.Errorf("C.myenum_def = %v, want 1234", c) 1497 } 1498 { 1499 const c = C.myenum 1500 if c != 1234 { 1501 t.Errorf("C.myenum as const = %v, want 1234", c) 1502 } 1503 } 1504 { 1505 const c = C.myenum_def 1506 if c != 1234 { 1507 t.Errorf("C.myenum as const = %v, want 1234", c) 1508 } 1509 } 1510 if c := C.myint_def; c != 12345 { 1511 t.Errorf("C.myint_def = %v, want 12345", c) 1512 } 1513 { 1514 const c = C.myint_def 1515 if c != 12345 { 1516 t.Errorf("C.myint as const = %v, want 12345", c) 1517 } 1518 } 1519 1520 if c := C.myfloat_def; c != 1.5 { 1521 t.Errorf("C.myint_def = %v, want 1.5", c) 1522 } 1523 { 1524 const c = C.myfloat_def 1525 if c != 1.5 { 1526 t.Errorf("C.myint as const = %v, want 1.5", c) 1527 } 1528 } 1529 1530 if s := C.mystring_def; s != "hello" { 1531 t.Errorf("C.mystring_def = %q, want %q", s, "hello") 1532 } 1533} 1534 1535// issue 6907 1536 1537func test6907(t *testing.T) { 1538 want := "yarn" 1539 if got := C.GoString(C.Issue6907CopyString(want)); got != want { 1540 t.Errorf("C.GoString(C.Issue6907CopyString(%q)) == %q, want %q", want, got, want) 1541 } 1542} 1543 1544// issue 7560 1545 1546func test7560(t *testing.T) { 1547 // some mingw don't implement __packed__ correctly. 1548 if C.offset7560() != 1 { 1549 t.Skip("C compiler did not pack struct") 1550 } 1551 1552 // C.misaligned should have x but then a padding field to get to the end of the struct. 1553 // There should not be a field named 'y'. 1554 var v C.misaligned 1555 rt := reflect.TypeOf(&v).Elem() 1556 if rt.NumField() != 2 || rt.Field(0).Name != "x" || rt.Field(1).Name != "_" { 1557 t.Errorf("unexpected fields in C.misaligned:\n") 1558 for i := 0; i < rt.NumField(); i++ { 1559 t.Logf("%+v\n", rt.Field(i)) 1560 } 1561 } 1562} 1563 1564// issue 7786 1565 1566func f() { 1567 var x1 *C.typedef_test7786 1568 var x2 *C.struct_test7786 1569 x1 = x2 1570 x2 = x1 1571 C.f7786(x1) 1572 C.f7786(x2) 1573 C.g7786(x1) 1574 C.g7786(x2) 1575 1576 var b1 *C.typedef_body7786 1577 var b2 *C.struct_body7786 1578 b1 = b2 1579 b2 = b1 1580 C.b7786(b1) 1581 C.b7786(b2) 1582 C.c7786(b1) 1583 C.c7786(b2) 1584 1585 var u1 *C.typedef_union7786 1586 var u2 *C.union_union7786 1587 u1 = u2 1588 u2 = u1 1589 C.u7786(u1) 1590 C.u7786(u2) 1591 C.v7786(u1) 1592 C.v7786(u2) 1593} 1594 1595// issue 8092 1596 1597func test8092(t *testing.T) { 1598 tests := []struct { 1599 s string 1600 a, b *C.char 1601 }{ 1602 {"text", &C.text[0], C.ctext()}, 1603 {"data", &C.data[0], C.cdata()}, 1604 } 1605 for _, test := range tests { 1606 if test.a != test.b { 1607 t.Errorf("%s: pointer mismatch: %v != %v", test.s, test.a, test.b) 1608 } 1609 if got := C.GoString(test.a); got != test.s { 1610 t.Errorf("%s: points at %#v, want %#v", test.s, got, test.s) 1611 } 1612 } 1613} 1614 1615// issues 8368 and 8441 1616 1617func issue8368(one *C.struct_one, two *C.struct_two) { 1618} 1619 1620func issue8441(one *C.one, two *C.two) { 1621 issue8441(two.x, one.x) 1622} 1623 1624// issue 8428 1625 1626var _ = C.struct_issue8428one{ 1627 b: C.char(0), 1628 // The trailing rest field is not available in cgo. 1629 // See issue 11925. 1630 // rest: [0]C.char{}, 1631} 1632 1633var _ = C.struct_issue8428two{ 1634 p: unsafe.Pointer(nil), 1635 b: C.char(0), 1636 rest: [0]C.char{}, 1637} 1638 1639var _ = C.struct_issue8428three{ 1640 w: [1][2][3][0]C.char{}, 1641 x: [2][3][0][1]C.char{}, 1642 y: [3][0][1][2]C.char{}, 1643 z: [0][1][2][3]C.char{}, 1644} 1645 1646// issue 8811 1647 1648func test8811(t *testing.T) { 1649 C.issue8811Execute() 1650} 1651 1652// issue 9557 1653 1654func test9557(t *testing.T) { 1655 // implicitly dereference a Go variable 1656 foo := C.issue9557foo 1657 if v := foo.a; v != 42 { 1658 t.Fatalf("foo.a expected 42, but got %d", v) 1659 } 1660 1661 // explicitly dereference a C variable 1662 if v := (*C.issue9557foo).a; v != 42 { 1663 t.Fatalf("(*C.issue9557foo).a expected 42, but is %d", v) 1664 } 1665 1666 // implicitly dereference a C variable 1667 if v := C.issue9557foo.a; v != 42 { 1668 t.Fatalf("C.issue9557foo.a expected 42, but is %d", v) 1669 } 1670} 1671 1672// issue 8331 part 1 1673 1674func issue8331a() C.issue8331 { 1675 return issue8331Var 1676} 1677 1678// issue 10303 1679 1680func test10303(t *testing.T, n int) { 1681 if runtime.Compiler == "gccgo" { 1682 t.Skip("gccgo permits C pointers on the stack") 1683 } 1684 1685 // Run at a few different stack depths just to avoid an unlucky pass 1686 // due to variables ending up on different pages. 1687 if n > 0 { 1688 test10303(t, n-1) 1689 } 1690 if t.Failed() { 1691 return 1692 } 1693 var x, y, z, v, si C.int 1694 var s C.Struct 1695 C.setintstar(&x) 1696 C.setintptr(&y) 1697 C.setvoidptr(unsafe.Pointer(&v)) 1698 s.P = &si 1699 C.setstruct(s) 1700 1701 if uintptr(unsafe.Pointer(&x))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { 1702 t.Error("C int* argument on stack") 1703 } 1704 if uintptr(unsafe.Pointer(&y))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { 1705 t.Error("C intptr argument on stack") 1706 } 1707 if uintptr(unsafe.Pointer(&v))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { 1708 t.Error("C void* argument on stack") 1709 } 1710 if uintptr(unsafe.Pointer(&si))&^0xfff == uintptr(unsafe.Pointer(&z))&^0xfff { 1711 t.Error("C struct field pointer on stack") 1712 } 1713} 1714 1715// issue 11925 1716 1717func test11925(t *testing.T) { 1718 if C.sizeof_struct_a11925 != unsafe.Sizeof(C.struct_a11925{}) { 1719 t.Errorf("size of a changed: C %d, Go %d", C.sizeof_struct_a11925, unsafe.Sizeof(C.struct_a11925{})) 1720 } 1721 if C.sizeof_struct_b11925 != unsafe.Sizeof(C.struct_b11925{}) { 1722 t.Errorf("size of b changed: C %d, Go %d", C.sizeof_struct_b11925, unsafe.Sizeof(C.struct_b11925{})) 1723 } 1724} 1725 1726// issue 12030 1727 1728func test12030(t *testing.T) { 1729 buf := (*C.char)(C.malloc(256)) 1730 defer C.free(unsafe.Pointer(buf)) 1731 for _, f := range []float64{1.0, 2.0, 3.14} { 1732 C.issue12030conv(buf, C.double(f)) 1733 got := C.GoString(buf) 1734 if want := fmt.Sprintf("d=%g", f); got != want { 1735 t.Fatalf("C.sprintf failed for %g: %q != %q", f, got, want) 1736 } 1737 } 1738} 1739 1740// issue 13402 1741 1742var _ C.complexfloat 1743var _ C.complexdouble 1744 1745// issue 13930 1746// Test that cgo's multiple-value special form for 1747// C function calls works in variable declaration statements. 1748 1749var _, _ = C.abs(0) 1750 1751// issue 14838 1752 1753func test14838(t *testing.T) { 1754 data := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} 1755 cData := C.CBytes(data) 1756 defer C.free(cData) 1757 1758 if C.check_cbytes((*C.char)(cData), C.size_t(len(data))) == 0 { 1759 t.Fatalf("mismatched data: expected %v, got %v", data, (*(*[10]byte)(unsafe.Pointer(cData)))[:]) 1760 } 1761} 1762 1763// issue 17065 1764 1765var sink C.int 1766 1767func test17065(t *testing.T) { 1768 if runtime.GOOS == "darwin" { 1769 t.Skip("broken on darwin; issue 17065") 1770 } 1771 for i := range C.ii { 1772 sink = C.ii[i] 1773 } 1774} 1775 1776// issue 17537 1777 1778func test17537(t *testing.T) { 1779 v := C.S17537{i: 17537} 1780 if got, want := C.I17537(&v), C.int(17537); got != want { 1781 t.Errorf("got %d, want %d", got, want) 1782 } 1783 1784 p := (*C.char)(C.malloc(1)) 1785 *p = 17 1786 if got, want := C.F17537(&p), C.int(17); got != want { 1787 t.Errorf("got %d, want %d", got, want) 1788 } 1789 1790 C.F18298(nil) 1791 var v18298 C.T18298_2 1792 C.G18298(C.T18298_1(v18298)) 1793} 1794 1795// issue 17723 1796 1797func testAPI() { 1798 var cs *C.char 1799 cs = C.CString("hello") 1800 defer C.free(unsafe.Pointer(cs)) 1801 var s string 1802 s = C.GoString((*C.char)(C.api_hello)) 1803 s = C.GoStringN((*C.char)(C.api_hello), C.int(6)) 1804 var b []byte 1805 b = C.GoBytes(unsafe.Pointer(C.api_hello), C.int(6)) 1806 _, _ = s, b 1807 C.cstring_pointer_fun(nil) 1808} 1809 1810// issue 18126 1811 1812func test18126(t *testing.T) { 1813 p := C.malloc(1) 1814 _, err := C.Issue18126C(&p) 1815 C.free(p) 1816 _ = err 1817} 1818 1819// issue 18720 1820 1821func test18720(t *testing.T) { 1822 if got, want := C.HELLO_WORLD, "hello\000world"; got != want { 1823 t.Errorf("C.HELLO_WORLD == %q, expected %q", got, want) 1824 } 1825 1826 if got, want := C.VAR1, C.int(5); got != want { 1827 t.Errorf("C.VAR1 == %v, expected %v", got, want) 1828 } 1829 1830 if got, want := *C.ADDR, C.int(5); got != want { 1831 t.Errorf("*C.ADDR == %v, expected %v", got, want) 1832 } 1833 1834 if got, want := C.CALL, C.int(6); got != want { 1835 t.Errorf("C.CALL == %v, expected %v", got, want) 1836 } 1837 1838 if got, want := C.CALL, C.int(7); got != want { 1839 t.Errorf("C.CALL == %v, expected %v", got, want) 1840 } 1841 1842 // Issue 20125. 1843 if got, want := C.SIZE_OF_FOO, 1; got != want { 1844 t.Errorf("C.SIZE_OF_FOO == %v, expected %v", got, want) 1845 } 1846} 1847 1848// issue 20129 1849 1850func test20129(t *testing.T) { 1851 if C.issue20129 != 0 { 1852 t.Fatal("test is broken") 1853 } 1854 C.issue20129Foo() 1855 if C.issue20129 != 1 { 1856 t.Errorf("got %v but expected %v", C.issue20129, 1) 1857 } 1858 C.issue20129Bar() 1859 if C.issue20129 != 2 { 1860 t.Errorf("got %v but expected %v", C.issue20129, 2) 1861 } 1862} 1863 1864// issue 20369 1865 1866func test20369(t *testing.T) { 1867 if C.XUINT64_MAX != math.MaxUint64 { 1868 t.Fatalf("got %v, want %v", uint64(C.XUINT64_MAX), uint64(math.MaxUint64)) 1869 } 1870} 1871 1872// issue 21668 1873 1874var issue21668_X = C.x21668 1875 1876// issue 21708 1877 1878func test21708(t *testing.T) { 1879 if got, want := C.CAST_TO_INT64, -1; got != want { 1880 t.Errorf("C.CAST_TO_INT64 == %v, expected %v", got, want) 1881 } 1882} 1883 1884// issue 21809 1885 1886func test21809(t *testing.T) { 1887 longVar := C.long(3) 1888 typedefVar := C.MySigned_t(4) 1889 typedefTypedefVar := C.MySigned2_t(5) 1890 1891 // all three should be considered identical to `long` 1892 if ret := C.takes_long(longVar); ret != 9 { 1893 t.Errorf("got %v but expected %v", ret, 9) 1894 } 1895 if ret := C.takes_long(typedefVar); ret != 16 { 1896 t.Errorf("got %v but expected %v", ret, 16) 1897 } 1898 if ret := C.takes_long(typedefTypedefVar); ret != 25 { 1899 t.Errorf("got %v but expected %v", ret, 25) 1900 } 1901 1902 // They should also be identical to the typedef'd type 1903 if ret := C.takes_typedef(longVar); ret != 9 { 1904 t.Errorf("got %v but expected %v", ret, 9) 1905 } 1906 if ret := C.takes_typedef(typedefVar); ret != 16 { 1907 t.Errorf("got %v but expected %v", ret, 16) 1908 } 1909 if ret := C.takes_typedef(typedefTypedefVar); ret != 25 { 1910 t.Errorf("got %v but expected %v", ret, 25) 1911 } 1912} 1913 1914// issue 22906 1915 1916func test22906(t *testing.T) { 1917 var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types. 1918 _ = x1 1919 var x2 C.jclass = 0 1920 _ = x2 1921 var x3 C.jthrowable = 0 1922 _ = x3 1923 var x4 C.jstring = 0 1924 _ = x4 1925 var x5 C.jarray = 0 1926 _ = x5 1927 var x6 C.jbooleanArray = 0 1928 _ = x6 1929 var x7 C.jbyteArray = 0 1930 _ = x7 1931 var x8 C.jcharArray = 0 1932 _ = x8 1933 var x9 C.jshortArray = 0 1934 _ = x9 1935 var x10 C.jintArray = 0 1936 _ = x10 1937 var x11 C.jlongArray = 0 1938 _ = x11 1939 var x12 C.jfloatArray = 0 1940 _ = x12 1941 var x13 C.jdoubleArray = 0 1942 _ = x13 1943 var x14 C.jobjectArray = 0 1944 _ = x14 1945 var x15 C.jweak = 0 1946 _ = x15 1947} 1948 1949// issue 22958 1950// Nothing to run, just make sure this compiles. 1951var Vissue22958 C.issue22958Type 1952 1953func test23356(t *testing.T) { 1954 if got, want := C.a(), C.int(5); got != want { 1955 t.Errorf("C.a() == %v, expected %v", got, want) 1956 } 1957 if got, want := C.r(), C.int(3); got != want { 1958 t.Errorf("C.r() == %v, expected %v", got, want) 1959 } 1960} 1961 1962// issue 23720 1963 1964func Issue23720F() { 1965 var x C.issue23720A 1966 C.issue23720F(x) 1967} 1968 1969// issue 24206 1970 1971func test24206(t *testing.T) { 1972 if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { 1973 t.Skipf("skipping on %s/%s", runtime.GOOS, runtime.GOARCH) 1974 } 1975 1976 if l := len(C.GoString(C.dangerousString1())); l != 123 { 1977 t.Errorf("Incorrect string length - got %d, want 123", l) 1978 } 1979 if l := len(C.GoString(C.dangerousString2())); l != 4096+123 { 1980 t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123) 1981 } 1982} 1983 1984// issue 25143 1985 1986func issue25143sum(ns ...C.int) C.int { 1987 total := C.int(0) 1988 for _, n := range ns { 1989 total += n 1990 } 1991 return total 1992} 1993 1994func test25143(t *testing.T) { 1995 if got, want := issue25143sum(1, 2, 3), C.int(6); got != want { 1996 t.Errorf("issue25143sum(1, 2, 3) == %v, expected %v", got, want) 1997 } 1998} 1999 2000// issue 26066 2001// Wrong type of constant with GCC 8 and newer. 2002 2003func test26066(t *testing.T) { 2004 var i = int64(C.issue26066) 2005 if i != -1 { 2006 t.Errorf("got %d, want -1", i) 2007 } 2008} 2009 2010// issue 26517 2011var a C.TypeOne 2012var b C.TypeTwo 2013 2014// issue 27660 2015// Stress the interaction between the race detector and cgo in an 2016// attempt to reproduce the memory corruption described in #27660. 2017// The bug was very timing sensitive; at the time of writing this 2018// test would only trigger the bug about once out of every five runs. 2019 2020func test27660(t *testing.T) { 2021 ctx, cancel := context.WithCancel(context.Background()) 2022 defer cancel() 2023 ints := make([]int, 100) 2024 locks := make([]sync.Mutex, 100) 2025 // Slowly create threads so that ThreadSanitizer is forced to 2026 // frequently resize its SyncClocks. 2027 for i := 0; i < 100; i++ { 2028 go func() { 2029 for ctx.Err() == nil { 2030 // Sleep in C for long enough that it is likely that the runtime 2031 // will retake this goroutine's currently wired P. 2032 C.usleep(1000 /* 1ms */) 2033 runtime.Gosched() // avoid starvation (see #28701) 2034 } 2035 }() 2036 go func() { 2037 // Trigger lots of synchronization and memory reads/writes to 2038 // increase the likelihood that the race described in #27660 2039 // results in corruption of ThreadSanitizer's internal state 2040 // and thus an assertion failure or segfault. 2041 i := 0 2042 for ctx.Err() == nil { 2043 j := rand.Intn(100) 2044 locks[j].Lock() 2045 ints[j]++ 2046 locks[j].Unlock() 2047 // needed for gccgo, to avoid creation of an 2048 // unpreemptible "fast path" in this loop. Choice 2049 // of (1<<24) is somewhat arbitrary. 2050 if i%(1<<24) == 0 { 2051 runtime.Gosched() 2052 } 2053 i++ 2054 2055 } 2056 }() 2057 time.Sleep(time.Millisecond) 2058 } 2059} 2060 2061// issue 28540 2062 2063func twoargsF() { 2064 v := []string{} 2065 C.twoargs1(C.twoargs2(), C.twoargs3(unsafe.Pointer(&v))) 2066} 2067 2068// issue 28545 2069 2070func issue28545G(p **C.char) { 2071 C.issue28545F(p, -1, (0)) 2072 C.issue28545F(p, 2+3, complex(1, 1)) 2073 C.issue28545F(p, issue28772Constant, issue28772Constant2) 2074} 2075 2076// issue 28772 part 1 - part 2 in testx.go 2077 2078const issue28772Constant = C.issue28772Constant 2079 2080// issue 28896 2081 2082func offset(i int) uintptr { 2083 var pi C.innerPacked 2084 var po C.outerPacked 2085 var ui C.innerUnpacked 2086 var uo C.outerUnpacked 2087 switch i { 2088 case 0: 2089 return unsafe.Offsetof(pi.f2) 2090 case 1: 2091 return unsafe.Offsetof(po.g2) 2092 case 2: 2093 return unsafe.Offsetof(ui.f2) 2094 case 3: 2095 return unsafe.Offsetof(uo.g2) 2096 default: 2097 panic("can't happen") 2098 } 2099} 2100 2101func test28896(t *testing.T) { 2102 for i := 0; i < 4; i++ { 2103 c := uintptr(C.offset(C.int(i))) 2104 g := offset(i) 2105 if c != g { 2106 t.Errorf("%d: C: %d != Go %d", i, c, g) 2107 } 2108 } 2109} 2110 2111// issue 29383 2112// cgo's /*line*/ comments failed when inserted after '/', 2113// because the result looked like a "//" comment. 2114// No runtime test; just make sure it compiles. 2115 2116func Issue29383(n, size uint) int { 2117 if ^C.size_t(0)/C.size_t(n) < C.size_t(size) { 2118 return 0 2119 } 2120 return 0 2121} 2122 2123// issue 29748 2124// Error handling a struct initializer that requires pointer checking. 2125// Compilation test only, nothing to run. 2126 2127var Vissue29748 = C.f29748(&C.S29748{ 2128 nil, 2129}) 2130 2131func Fissue299748() { 2132 C.f29748(&C.S29748{ 2133 nil, 2134 }) 2135} 2136 2137// issue 29781 2138 2139var issue29781X struct{ X int } 2140 2141func issue29781F(...int) int { return 0 } 2142 2143func issue29781G() { 2144 var p *C.char 2145 C.issue29781F(&p, C.ISSUE29781C+1) 2146 C.issue29781F(nil, (C.int)( 2147 0)) 2148 C.issue29781F(&p, (C.int)(0)) 2149 C.issue29781F(&p, (C.int)( 2150 0)) 2151 C.issue29781F(&p, (C.int)(issue29781X. 2152 X)) 2153} 2154 2155// issue 30065 2156 2157func test30065(t *testing.T) { 2158 var a [256]byte 2159 b := []byte("a") 2160 C.memcpy(unsafe.Pointer(&a), unsafe.Pointer(&b[0]), 1) 2161 if a[0] != 'a' { 2162 t.Errorf("&a failed: got %c, want %c", a[0], 'a') 2163 } 2164 2165 b = []byte("b") 2166 C.memcpy(unsafe.Pointer(&a[0]), unsafe.Pointer(&b[0]), 1) 2167 if a[0] != 'b' { 2168 t.Errorf("&a[0] failed: got %c, want %c", a[0], 'b') 2169 } 2170 2171 d := make([]byte, 256) 2172 b = []byte("c") 2173 C.memcpy(unsafe.Pointer(&d[0]), unsafe.Pointer(&b[0]), 1) 2174 if d[0] != 'c' { 2175 t.Errorf("&d[0] failed: got %c, want %c", d[0], 'c') 2176 } 2177} 2178 2179// issue 31093 2180// No runtime test; just make sure it compiles. 2181 2182func Issue31093() { 2183 C.issue31093F(C.ushort(0)) 2184} 2185 2186// issue 32579 2187 2188func test32579(t *testing.T) { 2189 var s [1]C.struct_S32579 2190 C.memset(unsafe.Pointer(&s[0].data[0]), 1, 1) 2191 if s[0].data[0] != 1 { 2192 t.Errorf("&s[0].data[0] failed: got %d, want %d", s[0].data[0], 1) 2193 } 2194} 2195