github.com/gotranspile/cxgo@v0.3.7/pointers_test.go (about) 1 package cxgo 2 3 import "testing" 4 5 var casesTranslatePtrs = []parseCase{ 6 { 7 name: "if ptr", 8 src: ` 9 void foo() { 10 int* a; 11 if (a) return; 12 } 13 `, 14 exp: ` 15 func foo() { 16 var a *int32 17 if a != nil { 18 return 19 } 20 } 21 `, 22 }, 23 { 24 name: "if not ptr", 25 src: ` 26 void foo() { 27 int* a; 28 if (!a) return; 29 } 30 `, 31 exp: ` 32 func foo() { 33 var a *int32 34 if a == nil { 35 return 36 } 37 } 38 `, 39 }, 40 { 41 name: "if unsafe ptr", 42 src: ` 43 void foo() { 44 void* a; 45 if (a) return; 46 } 47 `, 48 exp: ` 49 func foo() { 50 var a unsafe.Pointer 51 if a != nil { 52 return 53 } 54 } 55 `, 56 }, 57 { 58 name: "if not unsafe ptr", 59 src: ` 60 void foo() { 61 void* a; 62 if (!a) return; 63 } 64 `, 65 exp: ` 66 func foo() { 67 var a unsafe.Pointer 68 if a == nil { 69 return 70 } 71 } 72 `, 73 }, 74 { 75 name: "if func", 76 src: ` 77 void foo() { 78 void(*a)(void); 79 if (a) return; 80 } 81 `, 82 exp: ` 83 func foo() { 84 var a func() 85 if a != nil { 86 return 87 } 88 } 89 `, 90 }, 91 { 92 name: "if not func", 93 src: ` 94 void foo() { 95 void(*a)(void); 96 if (!a) return; 97 } 98 `, 99 exp: ` 100 func foo() { 101 var a func() 102 if a == nil { 103 return 104 } 105 } 106 `, 107 }, 108 { 109 name: "bool -> ptr", 110 src: ` 111 #include <stdbool.h> 112 113 void foo() { 114 bool a; 115 int* b; 116 b = a; 117 } 118 `, 119 exp: ` 120 func foo() { 121 var ( 122 a bool 123 b *int32 124 ) 125 _ = b 126 b = (*int32)(unsafe.Pointer(uintptr(libc.BoolToInt(a)))) 127 } 128 `, 129 }, 130 { 131 name: "uintptr", 132 builtins: true, 133 src: ` 134 void bar(_cxgo_go_uintptr a) { 135 bar(a); 136 } 137 void foo(unsigned int a, int b) { 138 _cxgo_go_uintptr c; 139 c = a; 140 c = b; 141 bar(a); 142 bar(b); 143 bar(c); 144 } 145 `, 146 exp: ` 147 func bar(a uintptr) { 148 bar(a) 149 } 150 func foo(a uint32, b int32) { 151 var c uintptr 152 c = uintptr(a) 153 c = uintptr(b) 154 bar(uintptr(a)) 155 bar(uintptr(b)) 156 bar(c) 157 } 158 `, 159 }, 160 { 161 name: "inc ptr", 162 src: ` 163 void foo() { 164 char* a; 165 a++; 166 a--; 167 } 168 `, 169 exp: ` 170 func foo() { 171 var a *byte 172 a = (*byte)(unsafe.Add(unsafe.Pointer(a), 1)) 173 a = (*byte)(unsafe.Add(unsafe.Pointer(a), -1)) 174 } 175 `, 176 }, 177 { 178 name: "unsafe ptr add", 179 src: ` 180 void foo() { 181 int a = 2; 182 void* pa; 183 pa = pa + a; 184 pa = pa + 3; 185 pa += a; 186 pa += 5; 187 } 188 `, 189 exp: ` 190 func foo() { 191 var ( 192 a int32 = 2 193 pa unsafe.Pointer 194 ) 195 pa = unsafe.Add(pa, a) 196 pa = unsafe.Add(pa, 3) 197 pa = unsafe.Add(pa, a) 198 pa = unsafe.Add(pa, 5) 199 } 200 `, 201 }, 202 { 203 name: "named ptr -> named ptr", 204 src: ` 205 typedef struct{} A; 206 typedef struct{} B; 207 void foo(A* a) { 208 B *b = a; 209 } 210 `, 211 exp: ` 212 type A struct { 213 } 214 type B struct { 215 } 216 217 func foo(a *A) { 218 var b *B = (*B)(unsafe.Pointer(a)) 219 _ = b 220 } 221 `, 222 }, 223 { 224 name: "cast ptr to func ptr", 225 src: ` 226 void foo(void* a) { 227 (*(void (**)(void))a)(); 228 } 229 `, 230 exp: ` 231 func foo(a unsafe.Pointer) { 232 (*(*func())(a))() 233 } 234 `, 235 }, 236 { 237 name: "cast ptr to func", 238 src: ` 239 void foo(int* a) { 240 ((void (*)(void))a)(); 241 } 242 `, 243 exp: ` 244 func foo(a *int32) { 245 (libc.AsFunc(a, (*func())(nil)).(func()))() 246 } 247 `, 248 }, 249 { 250 name: "cast ptr to int", 251 src: ` 252 void foo(int* a) { 253 int b = a; 254 } 255 `, 256 exp: ` 257 func foo(a *int32) { 258 var b int32 = int32(uintptr(unsafe.Pointer(a))) 259 _ = b 260 } 261 `, 262 }, 263 { 264 name: "cast struct ptr to int", 265 src: ` 266 typedef struct A {} A; 267 268 void foo(A* a) { 269 int b = a; 270 } 271 `, 272 exp: ` 273 type A struct { 274 } 275 276 func foo(a *A) { 277 var b int32 = int32(uintptr(unsafe.Pointer(a))) 278 _ = b 279 } 280 `, 281 }, 282 { 283 name: "cast func to int", 284 src: ` 285 void foo(int a) { 286 a = foo; 287 } 288 `, 289 exp: ` 290 func foo(a int32) { 291 a = int32(libc.FuncAddr(foo)) 292 } 293 `, 294 }, 295 { 296 name: "ptr multi cast", 297 src: ` 298 typedef int* PT; 299 300 void foo(PT a) { 301 char b; 302 foo((PT)&b); 303 } 304 `, 305 exp: ` 306 type PT *int32 307 308 func foo(a PT) { 309 var b int8 310 foo(PT(unsafe.Pointer(&b))) 311 } 312 `, 313 }, 314 { 315 name: "ptr add", 316 src: ` 317 void foo() { 318 int a = 2; 319 int* pa; 320 pa = pa + a; 321 pa = pa + 3; 322 pa += a; 323 pa += 5; 324 } 325 `, 326 exp: ` 327 func foo() { 328 var ( 329 a int32 = 2 330 pa *int32 331 ) 332 pa = (*int32)(unsafe.Add(unsafe.Pointer(pa), unsafe.Sizeof(int32(0))*uintptr(a))) 333 pa = (*int32)(unsafe.Add(unsafe.Pointer(pa), unsafe.Sizeof(int32(0))*3)) 334 pa = (*int32)(unsafe.Add(unsafe.Pointer(pa), unsafe.Sizeof(int32(0))*uintptr(a))) 335 pa = (*int32)(unsafe.Add(unsafe.Pointer(pa), unsafe.Sizeof(int32(0))*5)) 336 } 337 `, 338 }, 339 { 340 name: "int add ptr", 341 src: ` 342 void foo() { 343 int a = 2; 344 int* pa; 345 pa = a + 4; 346 } 347 `, 348 exp: ` 349 func foo() { 350 var ( 351 a int32 = 2 352 pa *int32 353 ) 354 _ = pa 355 pa = (*int32)(unsafe.Pointer(uintptr(a + 4))) 356 } 357 `, 358 }, 359 { 360 name: "int add short ptr", 361 src: ` 362 void foo() { 363 int a = 2; 364 short* pa; 365 pa = a + 748; 366 } 367 `, 368 exp: ` 369 func foo() { 370 var ( 371 a int32 = 2 372 pa *int16 373 ) 374 _ = pa 375 pa = (*int16)(unsafe.Pointer(uintptr(a + 748))) 376 } 377 `, 378 }, 379 { 380 name: "int add short ptr unaligned", 381 src: ` 382 void foo() { 383 int a = 2; 384 short* pa; 385 pa = a + 3; 386 } 387 `, 388 exp: ` 389 func foo() { 390 var ( 391 a int32 = 2 392 pa *int16 393 ) 394 _ = pa 395 pa = (*int16)(unsafe.Pointer(uintptr(a + 3))) 396 } 397 `, 398 }, 399 { 400 name: "int add byte ptr", 401 src: ` 402 void foo() { 403 int a = 2; 404 char* pa; 405 pa = a + 4; 406 } 407 `, 408 exp: ` 409 func foo() { 410 var ( 411 a int32 = 2 412 pa *byte 413 ) 414 _ = pa 415 pa = (*byte)(unsafe.Pointer(uintptr(a + 4))) 416 } 417 `, 418 }, 419 { 420 name: "int add byte ptr unaligned", 421 src: ` 422 void foo() { 423 int a = 2; 424 char* pa; 425 pa = a + 3; 426 } 427 `, 428 exp: ` 429 func foo() { 430 var ( 431 a int32 = 2 432 pa *byte 433 ) 434 _ = pa 435 pa = (*byte)(unsafe.Pointer(uintptr(a + 3))) 436 } 437 `, 438 }, 439 { 440 name: "int -> unsafe ptr", 441 src: ` 442 void foo() { 443 int a; 444 void* b; 445 b = a; 446 } 447 `, 448 exp: ` 449 func foo() { 450 var ( 451 a int32 452 b unsafe.Pointer 453 ) 454 _ = b 455 b = unsafe.Pointer(uintptr(a)) 456 } 457 `, 458 }, 459 { 460 name: "unsafe ptr -> int", 461 src: ` 462 void foo() { 463 void* a; 464 int b; 465 b = a; 466 } 467 `, 468 exp: ` 469 func foo() { 470 var ( 471 a unsafe.Pointer 472 b int32 473 ) 474 _ = b 475 b = int32(uintptr(a)) 476 } 477 `, 478 }, 479 { 480 name: "int -> ptr", 481 src: ` 482 void foo() { 483 int a; 484 int* b; 485 b = a; 486 } 487 `, 488 exp: ` 489 func foo() { 490 var ( 491 a int32 492 b *int32 493 ) 494 _ = b 495 b = (*int32)(unsafe.Pointer(uintptr(a))) 496 } 497 `, 498 }, 499 { 500 name: "ptr -> int", 501 src: ` 502 void foo() { 503 int* a; 504 int b; 505 b = a; 506 } 507 `, 508 exp: ` 509 func foo() { 510 var ( 511 a *int32 512 b int32 513 ) 514 _ = b 515 b = int32(uintptr(unsafe.Pointer(a))) 516 } 517 `, 518 }, 519 { 520 name: "array -> ptr", 521 src: ` 522 void foo() { 523 char a[5]; 524 int* b; 525 b = a; 526 } 527 `, 528 exp: ` 529 func foo() { 530 var ( 531 a [5]byte 532 b *int32 533 ) 534 _ = b 535 b = (*int32)(unsafe.Pointer(&a[0])) 536 } 537 `, 538 }, 539 { 540 name: "array -> unsafe ptr", 541 src: ` 542 void foo() { 543 char a[5]; 544 void* b; 545 b = a; 546 } 547 `, 548 exp: ` 549 func foo() { 550 var ( 551 a [5]byte 552 b unsafe.Pointer 553 ) 554 _ = b 555 b = unsafe.Pointer(&a[0]) 556 } 557 `, 558 }, 559 { 560 name: "store func ptr", 561 src: ` 562 void foo() { 563 char a[8]; 564 *(void**)& a[4] = &foo; 565 } 566 `, 567 exp: ` 568 func foo() { 569 var a [8]byte 570 *(*unsafe.Pointer)(unsafe.Pointer(&a[4])) = unsafe.Pointer(libc.FuncAddr(foo)) 571 } 572 `, 573 }, 574 { 575 name: "get func pointer", 576 src: ` 577 void foo() { 578 char a[8]; 579 (*(void(**)(int)) &a)(1); 580 } 581 `, 582 exp: ` 583 func foo() { 584 var a [8]byte 585 (*(*func(int32))(unsafe.Pointer(&a[0])))(1) 586 } 587 `, 588 }, 589 { 590 name: "call func ptr", 591 src: ` 592 void foo(void(***a)(void)) { 593 void(**b)(void); 594 b = *a; 595 (*b)(); 596 } 597 `, 598 exp: ` 599 func foo(a **func()) { 600 var b *func() 601 b = *a 602 (*b)() 603 } 604 `, 605 }, 606 { 607 name: "post inc and set ptr", 608 src: ` 609 void foo() { 610 int* a; 611 int b; 612 *a++ = b; 613 } 614 `, 615 exp: ` 616 func foo() { 617 var ( 618 a *int32 619 b int32 620 ) 621 *func() *int32 { 622 p := &a 623 x := *p 624 *p = (*int32)(unsafe.Add(unsafe.Pointer(*p), unsafe.Sizeof(int32(0))*1)) 625 return x 626 }() = b 627 } 628 `, 629 }, 630 { 631 name: "ptr decr size", 632 src: ` 633 void foo() { 634 int *ptr = 0; 635 ptr -= 3; 636 } 637 `, 638 exp: ` 639 func foo() { 640 var ptr *int32 = nil 641 ptr = (*int32)(unsafe.Add(unsafe.Pointer(ptr), -int(unsafe.Sizeof(int32(0))*3))) 642 } 643 `, 644 }, 645 { 646 name: "negative ptr", 647 src: ` 648 void foo() { 649 const char* a; 650 a = -1; 651 a = -2; 652 if (a == (const char*)-1) { 653 return; 654 } 655 } 656 `, 657 exp: ` 658 func foo() { 659 var a *byte 660 a = (*byte)(unsafe.Pointer(uintptr(math.MaxUint32))) 661 a = (*byte)(unsafe.Pointer(uintptr(0xFFFFFFFE))) 662 if uintptr(unsafe.Pointer(a)) == uintptr(math.MaxUint32) { 663 return 664 } 665 } 666 `, 667 }, 668 { 669 name: "negative void ptr", 670 src: ` 671 void foo() { 672 void* a; 673 a = -1; 674 a = (void*)-1; 675 a = -2; 676 if (a == -1) { 677 return; 678 } 679 } 680 `, 681 exp: ` 682 func foo() { 683 var a unsafe.Pointer 684 a = unsafe.Pointer(uintptr(math.MaxUint32)) 685 a = unsafe.Pointer(uintptr(math.MaxUint32)) 686 a = unsafe.Pointer(uintptr(0xFFFFFFFE)) 687 if uintptr(a) == uintptr(math.MaxUint32) { 688 return 689 } 690 } 691 `, 692 }, 693 { 694 name: "return zero ptr", 695 src: ` 696 int* foo() { 697 return 0; 698 } 699 `, 700 exp: ` 701 func foo() *int32 { 702 return nil 703 } 704 `, 705 }, 706 { 707 name: "return zero ptr named", 708 inc: `typedef int my_size_t;`, 709 src: ` 710 my_size_t* foo() { 711 return 0; 712 } 713 `, 714 exp: ` 715 func foo() *my_size_t { 716 return nil 717 } 718 `, 719 }, 720 { 721 name: "compare unsafe pointers", 722 src: ` 723 void foo(void* a, void* b) { 724 if (a < b) return; 725 } 726 `, 727 exp: ` 728 func foo(a unsafe.Pointer, b unsafe.Pointer) { 729 if uintptr(a) < uintptr(b) { 730 return 731 } 732 } 733 `, 734 }, 735 { 736 name: "compare pointers", 737 src: ` 738 void foo(int* a, int* b) { 739 if (a < b) return; 740 } 741 `, 742 exp: ` 743 func foo(a *int32, b *int32) { 744 if uintptr(unsafe.Pointer(a)) < uintptr(unsafe.Pointer(b)) { 745 return 746 } 747 } 748 `, 749 }, 750 { 751 name: "compare diff pointers", 752 src: ` 753 void foo(int* a, void* b) { 754 if (a < b) return; 755 } 756 `, 757 exp: ` 758 func foo(a *int32, b unsafe.Pointer) { 759 if uintptr(unsafe.Pointer(a)) < uintptr(b) { 760 return 761 } 762 } 763 `, 764 }, 765 { 766 name: "equal unsafe pointers", 767 src: ` 768 void foo(void* a, void* b) { 769 if (a == b) return; 770 } 771 `, 772 exp: ` 773 func foo(a unsafe.Pointer, b unsafe.Pointer) { 774 if a == b { 775 return 776 } 777 } 778 `, 779 }, 780 { 781 name: "equal pointers", 782 src: ` 783 void foo(int* a, int* b) { 784 if (a == b) return; 785 } 786 `, 787 exp: ` 788 func foo(a *int32, b *int32) { 789 if a == b { 790 return 791 } 792 } 793 `, 794 }, 795 { 796 name: "equal diff pointers", 797 src: ` 798 void foo(int* a, void* b) { 799 if (a == b) return; 800 } 801 `, 802 exp: ` 803 func foo(a *int32, b unsafe.Pointer) { 804 if unsafe.Pointer(a) == b { 805 return 806 } 807 } 808 `, 809 }, 810 { 811 name: "equal pointer and const", 812 src: ` 813 void foo(int* a, void* b) { 814 if (a == 1 && b == 1) return; 815 } 816 `, 817 exp: ` 818 func foo(a *int32, b unsafe.Pointer) { 819 if uintptr(unsafe.Pointer(a)) == uintptr(1) && uintptr(b) == uintptr(1) { 820 return 821 } 822 } 823 `, 824 }, 825 { 826 name: "diff pointers", 827 src: ` 828 #include <stddef.h> 829 void foo(int* a, int* b) { 830 int c = a - b; 831 } 832 `, 833 exp: ` 834 func foo(a *int32, b *int32) { 835 var c int32 = int32(uintptr(unsafe.Pointer(a)) - uintptr(unsafe.Pointer(b))) 836 _ = c 837 } 838 `, 839 }, 840 { 841 name: "array ptr equal", 842 src: ` 843 void foo() { 844 int a[10]; 845 if (a == 0x1000) { 846 return; 847 } 848 } 849 `, 850 exp: ` 851 func foo() { 852 var a [10]int32 853 if uintptr(unsafe.Pointer(&a[0])) == uintptr(4096) { 854 return 855 } 856 } 857 `, 858 }, 859 { 860 name: "equal func", 861 src: ` 862 void foo() { 863 void(*a)(void); 864 if (a == foo) { 865 return; 866 } 867 } 868 `, 869 exp: ` 870 func foo() { 871 var a func() 872 if libc.FuncAddr(a) == libc.FuncAddr(foo) { 873 return 874 } 875 } 876 `, 877 }, 878 { 879 name: "array reinterpret", 880 inc: `unsigned char bytes[124];`, 881 src: ` 882 void foo() { 883 unsigned char* a; 884 a = *(unsigned char**)& bytes[4]; 885 } 886 `, 887 exp: ` 888 func foo() { 889 var a *uint8 890 _ = a 891 a = *(**uint8)(unsafe.Pointer(&bytes[4])) 892 } 893 `, 894 }, 895 { 896 name: "malloc and free", 897 src: ` 898 #include <stdlib.h> 899 void foo() { 900 void* a; 901 a = malloc(124); 902 free(a); 903 } 904 `, 905 exp: ` 906 func foo() { 907 var a unsafe.Pointer 908 _ = a 909 a = libc.Malloc(124) 910 a = nil 911 } 912 `, 913 }, 914 { 915 name: "malloc sizeof", 916 src: ` 917 #include <stdlib.h> 918 void foo() { 919 int* a = malloc(sizeof(int)); 920 } 921 `, 922 exp: ` 923 func foo() { 924 var a *int32 = new(int32) 925 _ = a 926 } 927 `, 928 }, 929 { 930 name: "memset sizeof", 931 src: ` 932 #include <stdlib.h> 933 void foo(int* a) { 934 memset(a, 0, sizeof(int)); 935 } 936 `, 937 exp: ` 938 func foo(a *int32) { 939 *a = 0 940 } 941 `, 942 }, 943 { 944 skip: true, // TODO 945 name: "memset slice", 946 src: ` 947 #include <stdlib.h> 948 void foo(int* a) { 949 memset(a, 0, 10*sizeof(int)); 950 } 951 `, 952 exp: ` 953 func foo(a []int32) { 954 copy(a[:10], make([]int32, 10)) 955 } 956 `, 957 configFuncs: []configFunc{ 958 withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}), 959 }, 960 }, 961 { 962 name: "memset sizeof struct", 963 src: ` 964 #include <stdlib.h> 965 966 typedef struct { 967 int x; 968 } A; 969 970 void foo(A* a) { 971 memset(a, 0, sizeof(A)); 972 } 973 `, 974 exp: ` 975 type A struct { 976 X int32 977 } 978 979 func foo(a *A) { 980 *a = A{} 981 } 982 `, 983 }, 984 { 985 name: "array ptr assign", 986 src: ` 987 void foo() { 988 char bytes[10]; 989 *(void**)& bytes[1] = &bytes[2]; 990 } 991 `, 992 exp: ` 993 func foo() { 994 var bytes [10]byte 995 *(*unsafe.Pointer)(unsafe.Pointer(&bytes[1])) = unsafe.Pointer(&bytes[2]) 996 } 997 `, 998 }, 999 { 1000 name: "addr of field", 1001 src: ` 1002 typedef struct { 1003 int field; 1004 } A; 1005 1006 void foo() { 1007 A a; 1008 int* b; 1009 b = &a.field; 1010 } 1011 `, 1012 exp: ` 1013 type A struct { 1014 Field int32 1015 } 1016 1017 func foo() { 1018 var ( 1019 a A 1020 b *int32 1021 ) 1022 _ = b 1023 b = &a.Field 1024 } 1025 `, 1026 }, 1027 { 1028 name: "implicit 0 field ptr", 1029 src: ` 1030 typedef struct { 1031 int x; 1032 } A; 1033 typedef struct { 1034 A a; 1035 A b; 1036 } B; 1037 1038 void bar(A* arg) { 1039 int x = arg->x; 1040 } 1041 1042 void foo(B* arg) { 1043 bar(arg); 1044 } 1045 `, 1046 exp: ` 1047 type A struct { 1048 X int32 1049 } 1050 type B struct { 1051 A A 1052 B A 1053 } 1054 1055 func bar(arg *A) { 1056 var x int32 = arg.X 1057 _ = x 1058 } 1059 func foo(arg *B) { 1060 bar(&arg.A) 1061 } 1062 `, 1063 }, 1064 { 1065 name: "implicit array access", 1066 src: ` 1067 struct s { 1068 int i; 1069 }; 1070 1071 struct s ss[] = { 1072 {0}, 1073 }; 1074 1075 1076 void foo() { 1077 int i = ss->i; 1078 } 1079 `, 1080 exp: ` 1081 type s struct { 1082 I int32 1083 } 1084 1085 var ss [1]s = [1]s{} 1086 1087 func foo() { 1088 var i int32 = ss[0].I 1089 _ = i 1090 } 1091 `, 1092 }, 1093 { 1094 name: "named ptr call", 1095 src: ` 1096 typedef int H; 1097 typedef struct F {} F; 1098 void foo(F* a); 1099 void bar(void) { 1100 H a; 1101 foo(((F*)a)); 1102 } 1103 `, 1104 exp: ` 1105 type H int32 1106 type F struct { 1107 } 1108 1109 func foo(a *F) 1110 func bar() { 1111 var a H 1112 foo((*F)(unsafe.Pointer(uintptr(a)))) 1113 } 1114 `, 1115 }, 1116 { 1117 name: "sizeof int conv", 1118 src: ` 1119 #include <stddef.h> 1120 1121 typedef struct { 1122 int x; 1123 } A; 1124 1125 void foo () { 1126 int x = sizeof(A); 1127 } 1128 `, 1129 exp: ` 1130 type A struct { 1131 X int32 1132 } 1133 1134 func foo() { 1135 var x int32 = int32(unsafe.Sizeof(A{})) 1136 _ = x 1137 } 1138 `, 1139 }, 1140 { 1141 name: "ptr add size mult", 1142 src: ` 1143 #include <stddef.h> 1144 1145 typedef struct { 1146 int x; 1147 int y; 1148 } A; 1149 1150 void foo() { 1151 int* ptr; 1152 ptr += 20 * (sizeof(A)/2); 1153 } 1154 `, 1155 exp: ` 1156 1157 type A struct { 1158 X int32 1159 Y int32 1160 } 1161 1162 func foo() { 1163 var ptr *int32 1164 ptr = (*int32)(unsafe.Add(unsafe.Pointer(ptr), unsafe.Sizeof(int32(0))*(20*(unsafe.Sizeof(A{})/2)))) 1165 } 1166 `, 1167 }, 1168 { 1169 skip: true, // TODO 1170 name: "ptr compare out of bounds", 1171 src: ` 1172 void foo() { 1173 void* p; 1174 int arr[9]; 1175 if (p > &arr[9]) { 1176 foo(); 1177 } 1178 } 1179 `, 1180 exp: ` 1181 func foo() { 1182 var ( 1183 p unsafe.Pointer 1184 arr [9]int32 1185 ) 1186 if uintptr(unsafe.Pointer(p)) - uintptr(unsafe.Pointer(&arr)) > unsafe.Sizeof(int32(0))*9 { 1187 foo() 1188 } 1189 } 1190 `, 1191 }, 1192 { 1193 name: "pointer to first elem", 1194 src: ` 1195 void foo() { 1196 char b[10]; 1197 char* p; 1198 p = b; 1199 p = &b; 1200 p = &b[0]; 1201 } 1202 `, 1203 exp: ` 1204 func foo() { 1205 var ( 1206 b [10]byte 1207 p *byte 1208 ) 1209 _ = p 1210 p = &b[0] 1211 p = &b[0] 1212 p = &b[0] 1213 } 1214 `, 1215 }, 1216 { 1217 name: "slice override global", 1218 src: ` 1219 int* foo; 1220 `, 1221 exp: ` 1222 var foo []int32 1223 `, 1224 configFuncs: []configFunc{ 1225 withIdent(IdentConfig{ 1226 Name: "foo", 1227 Type: HintSlice, 1228 }), 1229 }, 1230 }, 1231 { 1232 name: "slice override func arg", 1233 src: ` 1234 void foo(int* a); 1235 void bar(int* b){ 1236 } 1237 `, 1238 exp: ` 1239 func foo(a []int32) 1240 func bar(b []int32) { 1241 } 1242 `, 1243 configFuncs: []configFunc{ 1244 withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}), 1245 withIdentField("bar", IdentConfig{Name: "b", Type: HintSlice}), 1246 }, 1247 }, 1248 { 1249 name: "slice override struct field", 1250 src: ` 1251 typedef struct{ 1252 int* a 1253 } foo; 1254 1255 typedef struct bar { 1256 int* b 1257 } bar; 1258 1259 struct baz { 1260 int* c 1261 }; 1262 `, 1263 exp: ` 1264 type foo struct { 1265 A []int32 1266 } 1267 type bar struct { 1268 B []int32 1269 } 1270 type baz struct { 1271 C []int32 1272 } 1273 `, 1274 configFuncs: []configFunc{ 1275 withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}), 1276 withIdentField("bar", IdentConfig{Name: "b", Type: HintSlice}), 1277 withIdentField("baz", IdentConfig{Name: "c", Type: HintSlice}), 1278 }, 1279 }, 1280 { 1281 name: "slice and ptr", 1282 src: ` 1283 void foo(int* a, int* b, int c) { 1284 a = b; 1285 b = a; 1286 c = *a; 1287 c = a[1]; 1288 if (a != 0) { 1289 a = 0; 1290 } 1291 } 1292 `, 1293 exp: ` 1294 func foo(a []int32, b *int32, c int32) { 1295 a = []int32(b) 1296 b = &a[0] 1297 c = a[0] 1298 c = a[1] 1299 if a != nil { 1300 a = nil 1301 } 1302 } 1303 `, 1304 configFuncs: []configFunc{ 1305 withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}), 1306 }, 1307 }, 1308 { 1309 name: "slice calloc", 1310 src: ` 1311 #include <stdlib.h> 1312 1313 int n; 1314 int* a = calloc(n, sizeof(int)); 1315 int* b = (int*)calloc(n, sizeof(int)); 1316 int* c = (int*)calloc(n, sizeof(int)); 1317 `, 1318 exp: ` 1319 var n int32 1320 var a []int32 = make([]int32, int(n)) 1321 var b []int32 = make([]int32, int(n)) 1322 var c *int32 = &make([]int32, int(n))[0] 1323 `, 1324 configFuncs: []configFunc{ 1325 withIdent(IdentConfig{Name: "a", Type: HintSlice}), 1326 withIdent(IdentConfig{Name: "b", Type: HintSlice}), 1327 }, 1328 }, 1329 { 1330 name: "slice safe calloc", 1331 src: ` 1332 #include <stdlib.h> 1333 1334 void foo(int* a, int n) { 1335 if ((a = (int*)calloc(n, sizeof(int))) != 0) { 1336 a = 0; 1337 } 1338 } 1339 `, 1340 exp: ` 1341 func foo(a []int32, n int32) { 1342 if (func() []int32 { 1343 a = make([]int32, int(n)) 1344 return a 1345 }()) != nil { 1346 a = nil 1347 } 1348 } 1349 `, 1350 configFuncs: []configFunc{ 1351 withIdentField("foo", IdentConfig{Name: "a", Type: HintSlice}), 1352 }, 1353 }, 1354 { 1355 name: "slice index", 1356 src: ` 1357 typedef struct { 1358 int* ptr 1359 } A; 1360 1361 void foo(A x, int y) { 1362 y = *x.ptr; 1363 y = x.ptr[1]; 1364 y = *(x.ptr + 1); 1365 y = *(x.ptr + 2*y + 1); 1366 y = *(&(x.ptr + 2*y + 1)[y]); 1367 } 1368 `, 1369 exp: ` 1370 type A struct { 1371 Ptr []int32 1372 } 1373 1374 func foo(x A, y int32) { 1375 y = x.Ptr[0] 1376 y = x.Ptr[1] 1377 y = x.Ptr[1] 1378 y = x.Ptr[y*2+1] 1379 y = x.Ptr[y*2+1+y] 1380 } 1381 `, 1382 configFuncs: []configFunc{ 1383 withIdentField("A", IdentConfig{Name: "ptr", Type: HintSlice}), 1384 }, 1385 }, 1386 { 1387 name: "slice to bytes", 1388 src: ` 1389 void foo(unsigned char* x) { 1390 } 1391 void foo2(char* x) { 1392 foo(x); 1393 } 1394 `, 1395 exp: ` 1396 func foo(x []byte) { 1397 } 1398 func foo2(x string) { 1399 foo([]byte(x)) 1400 } 1401 `, 1402 configFuncs: []configFunc{ 1403 withIdentField("foo", IdentConfig{Name: "x", Type: HintSlice}), 1404 withIdentField("foo2", IdentConfig{Name: "x", Type: HintString}), 1405 }, 1406 }, 1407 { 1408 name: "slice def index", 1409 builtins: true, 1410 src: ` 1411 typedef struct { 1412 _cxgo_go_slice_t(int) ptr 1413 } A; 1414 1415 void foo(A x, int y) { 1416 y = *x.ptr; 1417 y = x.ptr[1]; 1418 y = *(x.ptr + 1); 1419 y = *(x.ptr + 2*y + 1); 1420 y = *(&(x.ptr + 2*y + 1)[y]); 1421 } 1422 `, 1423 exp: ` 1424 type A struct { 1425 Ptr []int32 1426 } 1427 1428 func foo(x A, y int32) { 1429 y = x.Ptr[0] 1430 y = x.Ptr[1] 1431 y = x.Ptr[1] 1432 y = x.Ptr[y*2+1] 1433 y = x.Ptr[y*2+1+y] 1434 } 1435 `, 1436 }, 1437 { 1438 name: "slice def ops", 1439 builtins: true, 1440 src: ` 1441 void foo(int y) { 1442 _cxgo_go_slice_t(int) arr; 1443 arr = 0; 1444 arr = _cxgo_go_make(_cxgo_go_slice_t(int), 1); 1445 arr = _cxgo_go_make(_cxgo_go_slice_t(int), 1, 2); 1446 arr = _cxgo_go_make_same(arr, 3, 4); 1447 y = _cxgo_go_len(arr); 1448 y = _cxgo_go_cap(arr); 1449 arr = _cxgo_go_slice(arr, -1, -1); 1450 arr = _cxgo_go_slice(arr, -1, 2); 1451 arr = _cxgo_go_slice(arr, 1, -1); 1452 arr = _cxgo_go_slice(arr, 1, 2); 1453 arr = _cxgo_go_slice(arr, -1, -1, -1); 1454 arr = _cxgo_go_slice(arr, -1, 2, 3); 1455 arr = _cxgo_go_slice(arr, 1, 2, 3); 1456 arr = _cxgo_go_append(arr, 1); 1457 arr = _cxgo_go_append(arr, 1, 2); 1458 arr = _cxgo_go_append(arr, arr); 1459 } 1460 `, 1461 exp: ` 1462 func foo(y int32) { 1463 var arr []int32 1464 arr = nil 1465 arr = make([]int32, 1) 1466 arr = make([]int32, 1, 2) 1467 arr = make([]int32, 3, 4) 1468 y = int32(len(arr)) 1469 y = int32(cap(arr)) 1470 arr = arr[:] 1471 arr = arr[:2] 1472 arr = arr[1:] 1473 arr = arr[1:2] 1474 arr = arr[:] 1475 arr = arr[:2:3] 1476 arr = arr[1:2:3] 1477 arr = append(arr, 1) 1478 arr = append(arr, 1, 2) 1479 arr = append(arr, arr...) 1480 } 1481 `, 1482 }, 1483 } 1484 1485 func TestPointers(t *testing.T) { 1486 runTestTranslate(t, casesTranslatePtrs) 1487 }