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