1 /** 2 Github issues. 3 */ 4 module it.issues; 5 6 import it; 7 8 version(Posix) // because Windows doesn't have signinfo 9 @Tags("issue") 10 @("3") 11 @safe unittest { 12 shouldCompile( 13 C( 14 ` 15 #include <signal.h> 16 ` 17 ), 18 D( 19 q{ 20 siginfo_t si; 21 si._sifields._timer.si_tid = 2; 22 static assert(is(typeof(si.si_signo) == int)); 23 static assert(is(typeof(si._sifields._timer.si_tid) == int), 24 typeof(si._sifields._timer.si_tid).stringof); 25 } 26 ), 27 ); 28 } 29 30 31 @Tags("issue") 32 @("4") 33 @safe unittest { 34 with(immutable IncludeSandbox()) { 35 writeFile("issue4.h", 36 q{ 37 extern char *arr[9]; 38 }); 39 writeFile("issue4.dpp", 40 ` 41 #include "issue4.h" 42 `); 43 runPreprocessOnly("issue4.dpp"); 44 fileShouldContain("issue4.d", q{extern __gshared char*[9] arr;}); 45 } 46 } 47 48 @Tags("issue") 49 @("5") 50 @safe unittest { 51 shouldCompile( 52 C( 53 q{ 54 typedef enum zfs_error { 55 EZFS_SUCCESS = 0, 56 EZFS_NOMEM = 2000, 57 }; 58 59 typedef struct zfs_perm_node { 60 char z_pname[4096]; 61 } zfs_perm_node_t; 62 63 typedef struct libzfs_handle libzfs_handle_t; 64 } 65 ), 66 D( 67 q{ 68 zfs_error e1 = EZFS_SUCCESS; 69 zfs_error e2 = zfs_error.EZFS_SUCCESS; 70 zfs_perm_node_t node; 71 static assert(node.z_pname.sizeof == 4096); 72 static assert(is(typeof(node.z_pname[0]) == char), (typeof(node.z_pname[0]).stringof)); 73 libzfs_handle_t* ptr; 74 } 75 ), 76 ); 77 } 78 79 @Tags("issue") 80 @("6") 81 @safe unittest { 82 with(immutable IncludeSandbox()) { 83 writeFile("issue6.h", 84 q{ 85 char *getMessage(); 86 }); 87 writeFile("issue6.dpp", 88 ` 89 #include "issue6.h" 90 `); 91 runPreprocessOnly("issue6.dpp"); 92 fileShouldContain("issue6.d", q{char* getMessage() @nogc nothrow;}); 93 } 94 } 95 96 97 @Tags("issue", "bitfield") 98 @("7.0") 99 @safe unittest { 100 shouldCompile( 101 C( 102 q{ 103 struct splitflags { 104 int dryrun : 1; 105 int import : 2; 106 int name_flags; 107 int foo: 3; 108 int bar: 4; 109 int suffix; 110 }; 111 112 struct other { 113 int quux: 2; 114 int toto: 3; 115 }; 116 } 117 ), 118 D( 119 q{ 120 static assert(splitflags.sizeof == 16); 121 static assert(other.sizeof == 4); 122 } 123 ), 124 ); 125 } 126 127 @Tags("issue", "bitfield") 128 @("7.1") 129 @safe unittest { 130 shouldCompile( 131 C( 132 q{ 133 struct other { 134 int a: 2; 135 int b: 3; 136 // field type of pointer to undeclared struct should not 137 // affect the generated bitfields' syntax 138 struct A *ptr; 139 }; 140 } 141 ), 142 D( 143 q{ 144 other o; 145 } 146 ), 147 ); 148 } 149 150 151 152 @Tags("issue") 153 @("10") 154 @safe unittest { 155 shouldCompile( 156 C( 157 q{ 158 enum silly_name { 159 FOO, 160 BAR, 161 BAZ, 162 }; 163 164 extern void silly_name(enum silly_name thingie); 165 } 166 ), 167 D( 168 q{ 169 silly_name_(silly_name.FOO); 170 } 171 ), 172 ); 173 } 174 175 @Tags("issue") 176 @("11") 177 @safe unittest { 178 shouldCompile( 179 C( 180 q{ 181 struct Foo; 182 typedef struct Foo* FooPtr; 183 } 184 ), 185 D( 186 q{ 187 FooPtr f = null; 188 static assert(!__traits(compiles, Foo())); 189 } 190 ), 191 ); 192 } 193 194 @Tags("issue") 195 @("14") 196 @safe unittest { 197 import dpp.runtime.options: Options; 198 with(immutable IncludeSandbox()) { 199 200 writeFile("foo.h", 201 q{ 202 typedef int foo; 203 }); 204 205 runPreprocessOnly("foo.h").shouldThrowWithMessage( 206 "No .dpp input file specified\n" ~ Options.usage); 207 } 208 } 209 210 @Tags("issue", "preprocessor") 211 @("22.0") 212 @safe unittest { 213 shouldCompile( 214 C( 215 ` 216 typedef struct { 217 #ifdef __USE_XOPEN 218 int fds_bits[42]; 219 #define __FDS_BITS(set) ((set)->fds_bits) 220 #else 221 int __fds_bits[42]; 222 #define __FDS_BITS(set) ((set)->__fds_bits) 223 #endif 224 } fd_set; 225 ` 226 ), 227 D( 228 q{ 229 fd_set set; 230 __FDS_BITS(set)[0] = 42; 231 } 232 ), 233 ); 234 } 235 236 @Tags("issue", "preprocessor") 237 @("22.1") 238 @safe unittest { 239 shouldCompile( 240 C( 241 ` 242 #define SIZEOF(x) (sizeof(x)) 243 ` 244 ), 245 D( 246 q{ 247 int i; 248 static assert(SIZEOF(i) == 4); 249 } 250 ), 251 ); 252 } 253 254 @Tags("issue", "preprocessor") 255 @("22.2") 256 @safe unittest { 257 shouldCompile( 258 C( 259 ` 260 typedef long int __fd_mask; 261 #define __NFDBITS (8 * (int) sizeof (__fd_mask)) 262 ` 263 ), 264 D( 265 q{ 266 import std.conv; 267 static assert(__NFDBITS == 8 * c_long.sizeof, 268 text("expected ", 8 * c_long.sizeof, ", got: ", __NFDBITS)); 269 } 270 ), 271 ); 272 } 273 274 @Tags("issue", "preprocessor") 275 @("22.3") 276 @safe unittest { 277 shouldCompile( 278 C( 279 ` 280 typedef struct clist { struct list* next; }; 281 #define clist_next(iter) (iter ? (iter)->next : NULL) 282 ` 283 ), 284 D( 285 q{ 286 clist l; 287 auto next = clist_next(&l); 288 } 289 ), 290 ); 291 } 292 293 294 295 @Tags("issue", "collision", "issue24") 296 @("24.0") 297 @safe unittest { 298 shouldCompile( 299 C( 300 q{ 301 struct Bar { 302 void (*Foo)(void); // this should get renamed as Foo_ 303 struct Foo* (*whatever)(void); 304 }; 305 } 306 ), 307 D( 308 q{ 309 } 310 ), 311 ); 312 } 313 314 @Tags("issue", "collision", "issue24") 315 @("24.1") 316 @safe unittest { 317 shouldCompile( 318 C( 319 q{ 320 int foo(int, struct foo_data**); 321 struct foo { int dummy; }; 322 struct foo_data { int dummy; }; 323 } 324 ), 325 D( 326 q{ 327 foo_data** data; 328 int ret = foo_(42, data); 329 foo s; 330 s.dummy = 33; 331 foo_data fd; 332 fd.dummy = 77; 333 } 334 ), 335 ); 336 } 337 338 339 @Tags("issue") 340 @("29.0") 341 @safe unittest { 342 shouldCompile( 343 C( 344 q{ 345 typedef struct { 346 union { 347 struct { 348 double x; 349 double y; 350 double z; 351 }; 352 double raw[3]; 353 }; 354 } vec3d_t; 355 } 356 ), 357 D( 358 q{ 359 vec3d_t v; 360 static assert(v.sizeof == 24); 361 v.raw[1] = 3.0; 362 v.y = 4.0; 363 } 364 ), 365 ); 366 } 367 368 @Tags("issue") 369 @("29.1") 370 @safe unittest { 371 shouldCompile( 372 C( 373 q{ 374 typedef struct { 375 struct { 376 int x; 377 int y; 378 }; 379 380 struct { 381 int z; 382 }; 383 } Struct; 384 } 385 ), 386 D( 387 q{ 388 Struct s; 389 s.x = 2; 390 s.y = 3; 391 s.z = 4; 392 } 393 ), 394 ); 395 } 396 397 @Tags("issue") 398 @("29.2") 399 @safe unittest { 400 shouldCompile( 401 C( 402 q{ 403 struct Struct { 404 union { 405 unsigned long long int foo; 406 struct { 407 unsigned int low; 408 unsigned int high; 409 } foo32; 410 }; 411 }; 412 } 413 ), 414 D( 415 q{ 416 Struct s; 417 s.foo = 42; 418 s.foo32.low = 33; 419 s.foo32.high = 77; 420 } 421 ), 422 ); 423 } 424 425 426 @Tags("issue") 427 @("29.3") 428 @safe unittest { 429 shouldCompile( 430 C( 431 q{ 432 struct Struct { 433 union { 434 unsigned long long int foo; 435 void *bar; 436 }; 437 }; 438 } 439 ), 440 D( 441 q{ 442 Struct s; 443 s.foo = 42; 444 s.bar = null; 445 } 446 ), 447 ); 448 } 449 450 @Tags("issue") 451 @("29.4") 452 @safe unittest { 453 shouldCompile( 454 C( 455 q{ 456 struct Struct { 457 union { 458 int a; 459 struct { 460 int b; 461 union { 462 int c; 463 char d; 464 }; 465 }; 466 }; 467 }; 468 } 469 ), 470 D( 471 q{ 472 Struct s; 473 s.a = 42; 474 s.b = 1337; 475 s.c = 7; 476 s.d = 'D'; 477 } 478 ), 479 ); 480 } 481 482 483 484 @Tags("issue") 485 @("33.0") 486 @safe unittest { 487 shouldCompile( 488 C( 489 q{ 490 void (*f)(); 491 } 492 ), 493 D( 494 q{ 495 static extern(C) void printHello() { } 496 f = &printHello; 497 f(); 498 } 499 ), 500 ); 501 } 502 503 @Tags("issue") 504 @("33.1") 505 @safe unittest { 506 shouldCompile( 507 C( 508 q{ 509 int (*f)(); 510 } 511 ), 512 D( 513 q{ 514 static extern(C) int func() { return 42; } 515 f = &func; 516 int i = f(); 517 } 518 ), 519 ); 520 } 521 522 523 @Tags("issue", "bitfield") 524 @("35") 525 @safe unittest { 526 shouldCompile( 527 C( 528 q{ 529 struct Struct { 530 int foo; 531 int bar; 532 int :32; 533 int :31; 534 int :3; 535 int :27; 536 }; 537 } 538 ), 539 D( 540 q{ 541 Struct s; 542 static assert(s.sizeof == 20); 543 } 544 ), 545 ); 546 } 547 548 @Tags("issue") 549 @("37") 550 @safe unittest { 551 shouldCompile( 552 C( 553 ` 554 #include "mmintrin.h" 555 ` 556 ), 557 D( 558 q{ 559 } 560 ), 561 ); 562 } 563 564 565 @Tags("issue", "preprocessor") 566 @("39.0") 567 @safe unittest { 568 shouldCompile( 569 C( 570 ` 571 typedef long value; 572 typedef long intnat; 573 typedef unsigned long uintnat; 574 #define Val_long(x) ((intnat) (((uintnat)(x) << 1)) + 1) 575 #define Long_val(x) ((x) >> 1) 576 #define Val_int(x) Val_long(x) 577 #define Int_val(x) ((int) Long_val(x)) 578 #define Bp_val(v) ((char *) (v)) 579 #define String_val(x) ((const char *) Bp_val(x)) 580 value caml_callback(value, value); 581 char* strdup(const char* val); 582 ` 583 ), 584 D( 585 q{ 586 static value* fib_closure = null; 587 int n; 588 auto val = Int_val(caml_callback(*fib_closure, Val_int(n))); 589 char* str = strdup(String_val(caml_callback(*fib_closure, Val_int(n)))); 590 } 591 ), 592 ); 593 } 594 595 @Tags("issue", "preprocessor") 596 @("39.1") 597 @safe unittest { 598 shouldCompile( 599 C( 600 ` 601 #define VOID_PTR(x) ( void* )(x) 602 ` 603 ), 604 D( 605 q{ 606 auto val = VOID_PTR(42); 607 static assert(is(typeof(val) == void*)); 608 } 609 ), 610 ); 611 } 612 613 @Tags("issue", "preprocessor") 614 @("39.2") 615 @safe unittest { 616 shouldCompile( 617 C( 618 ` 619 typedef int myint; 620 #define CAST(x) ( myint* )(x) 621 ` 622 ), 623 D( 624 q{ 625 auto val = CAST(42); 626 static assert(is(typeof(val) == int*)); 627 } 628 ), 629 ); 630 } 631 632 @Tags("issue", "preprocessor") 633 @("40") 634 @safe unittest { 635 with(immutable IncludeSandbox()) { 636 writeFile("hdr1.h", 637 q{ 638 typedef int myint; 639 }); 640 writeFile("hdr2.h", 641 q{ 642 myint myfunc(void); 643 }); 644 writeFile("src.dpp", 645 ` 646 #include "hdr1.h" 647 #include "hdr2.h" 648 void func() { 649 myint _ = myfunc(); 650 } 651 `); 652 runPreprocessOnly("src.dpp"); 653 shouldCompile("src.d"); 654 } 655 } 656 657 658 @Tags("issue") 659 @("43") 660 @safe unittest { 661 shouldCompile( 662 C( 663 q{ 664 // The declaration `int (f)(int x, int y)` is of a function 665 // parameter that has the type of a binary function that 666 // returns int. Because C is C, this is similar to writing 667 // `int f[16]` in a parameter list but actually declaring 668 // `int*`. The result is a parameter that's a function pointer 669 // instead. To make things worse, if you put parens around the 670 // parameter name as is done here, the cursor's type according 671 // to libclang (in older versions) goes from FunctionProto to 672 // Unexposed because "reasons". 673 int binOp(int (f)(int x, int y), int a, int b); 674 int thef(int x, int y); 675 } 676 ), 677 D( 678 q{ 679 binOp(&thef, 2, 3); 680 } 681 ), 682 ); 683 } 684 685 686 @Tags("issue") 687 @("44.1") 688 @safe unittest { 689 shouldCompile( 690 C( 691 ` 692 #define macro(x) (x) + 42 693 ` 694 ), 695 D( 696 q{ 697 static assert(macro_(0) == 42); 698 static assert(macro_(1) == 43); 699 } 700 ), 701 ); 702 } 703 704 @Tags("issue") 705 @("44.2") 706 @safe unittest { 707 shouldCompile( 708 C( 709 ` 710 struct macro { int i }; 711 ` 712 ), 713 D( 714 q{ 715 } 716 ), 717 ); 718 } 719 720 721 @Tags("issue") 722 @("48") 723 @safe unittest { 724 shouldCompile( 725 C( 726 ` 727 #include <stddef.h> 728 struct Struct { 729 volatile int x; 730 volatile size_t y; 731 }; 732 ` 733 ), 734 D( 735 q{ 736 737 } 738 ), 739 ); 740 } 741 742 @Tags("issue", "preprocessor") 743 @("49") 744 @safe unittest { 745 shouldCompile( 746 C( 747 ` 748 #define func() ((void)0) 749 void (func)(void); 750 ` 751 ), 752 D( 753 q{ 754 // it gets renamed 755 func_(); 756 } 757 ), 758 ); 759 } 760 761 @Tags("issue") 762 @("53") 763 @safe unittest { 764 shouldCompile( 765 C( 766 q{ 767 typedef int bool; 768 } 769 ), 770 D( 771 q{ 772 773 } 774 ), 775 ); 776 } 777 778 @Tags("issue", "enum") 779 @("54") 780 @safe unittest { 781 shouldCompile( 782 C( 783 q{ 784 enum { 785 SUCCESS, 786 }; 787 typedef int boolean; 788 } 789 ), 790 D( 791 q{ 792 static assert(SUCCESS == 0); 793 } 794 ), 795 ); 796 } 797 798 799 version(linux) // linux specific header in the test 800 @Tags("issue") 801 @("66") 802 @safe unittest { 803 shouldCompile( 804 C( 805 ` 806 #include <linux/ethtool.h> 807 ` 808 ), 809 D( 810 q{ 811 } 812 ), 813 ); 814 } 815 816 817 @Tags("issue") 818 @("76") 819 @safe unittest { 820 shouldCompile( 821 Cpp( 822 q{ 823 template <typename T> 824 struct Template { 825 T payload; 826 }; 827 } 828 ), 829 D( 830 q{ 831 static assert(__traits(getProtection, Template!int.payload) == "public", 832 __traits(getProtection, Template!int.payload)); 833 } 834 ), 835 ); 836 } 837 838 839 840 @Tags("issue") 841 @("77") 842 @safe unittest { 843 with(immutable IncludeSandbox()) { 844 writeFile("hdr.h", ""); 845 writeFile("app.dpp", 846 ` 847 module mymodule; 848 #include "hdr.h" 849 void main() { 850 static assert(__MODULE__ == "mymodule"); 851 } 852 `); 853 runPreprocessOnly("app.dpp"); 854 shouldCompile("app.d"); 855 } 856 } 857 858 @Tags("issue") 859 @("79") 860 unittest { 861 with(const IncludeSandbox()) { 862 writeHeaderAndApp("1st.h", 863 ` 864 #include "2nd.h" 865 #define BAR 33 866 // before the BAR macro, BAR is 42. After, it's 33. 867 `, 868 D(""), // no need for .dpp source code 869 ); 870 writeFile("2nd.h", 871 ` 872 // These empty lines are important, since they push the enum 873 // declaration down to have a higher line number than the BAR macro. 874 // The bug had to do with ordering. 875 enum TheEnum { BAR = 42 }; 876 `); 877 run("-c", inSandboxPath("app.dpp"), "--keep-pre-cpp-files"); 878 } 879 } 880 881 882 @Tags("issue") 883 @("90.0") 884 @safe unittest { 885 shouldCompile( 886 C( 887 ` 888 #define TEST(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) 889 ` 890 ), 891 D( 892 q{ 893 } 894 ), 895 ); 896 } 897 898 @Tags("issue") 899 @("90.1") 900 @safe unittest { 901 shouldCompile( 902 C( 903 ` 904 #define TEST(_ARR) ((int)(sizeof(_ARR)/sizeof(_ARR[0]))) 905 ` 906 ), 907 D( 908 q{ 909 int[8] ints; 910 static assert(TEST(ints) == 8); 911 } 912 ), 913 ); 914 } 915 916 @Tags("issue") 917 @("91.0") 918 @safe unittest { 919 shouldCompile( 920 Cpp( 921 q{ 922 template <typename T, typename U> class Test {}; 923 void test(Test<unsigned short, unsigned int> a); 924 } 925 ), 926 D( 927 q{ 928 test(Test!(ushort, uint)()); 929 } 930 ), 931 ); 932 } 933 934 @Tags("issue") 935 @("91.1") 936 @safe unittest { 937 shouldCompile( 938 Cpp( 939 q{ 940 template <typename T, int> class Test {}; 941 void test(Test<unsigned short, 42> a); 942 } 943 ), 944 D( 945 q{ 946 test(Test!(ushort, 42)()); 947 } 948 ), 949 ); 950 } 951 952 953 @Tags("issue") 954 @("93") 955 @safe unittest { 956 shouldCompile( 957 Cpp( 958 q{ 959 constexpr int x = sizeof(int) + (1) + sizeof(int); 960 } 961 ), 962 D( 963 q{ 964 static assert(x == 9); 965 } 966 ), 967 ); 968 } 969 970 971 @Tags("issue") 972 @("95") 973 @safe unittest { 974 shouldCompile( 975 Cpp( 976 q{ 977 constexpr int x = sizeof(int) + alignof(int) + sizeof(int); 978 } 979 ), 980 D( 981 q{ 982 static assert(x == 12); 983 } 984 ), 985 ); 986 } 987 988 989 @Tags("issue") 990 @("96") 991 @safe unittest { 992 shouldCompile( 993 Cpp( 994 q{ 995 template<unsigned long A, int B> class C{ 996 enum { value = 0 }; 997 }; 998 template<> class C<3,4> { 999 enum { value = 1 }; 1000 }; 1001 } 1002 ), 1003 D( 1004 q{ 1005 static assert(C!(0, 0).value == 0); 1006 static assert(C!(0, 1).value == 0); 1007 static assert(C!(1, 0).value == 0); 1008 1009 static assert(C!(3, 4).value == 1); 1010 } 1011 ), 1012 ); 1013 } 1014 1015 1016 @Tags("issue") 1017 @("97") 1018 @safe unittest { 1019 shouldCompile( 1020 Cpp( 1021 q{ 1022 class T1 { 1023 public: 1024 int i; 1025 }; 1026 1027 template<int I> 1028 class T2 { 1029 public: 1030 double d; 1031 }; 1032 1033 extern T1 a; 1034 extern T2<3> b; 1035 } 1036 ), 1037 D( 1038 q{ 1039 a.i = 33; 1040 b.d = 33.3; 1041 } 1042 ), 1043 ); 1044 } 1045 1046 1047 @Tags("issue") 1048 @("99") 1049 @safe unittest { 1050 shouldCompile( 1051 Cpp( 1052 q{ 1053 class A { 1054 public: 1055 constexpr static int i = 0; 1056 constexpr static int j = A::i; 1057 }; 1058 } 1059 ), 1060 D( 1061 q{ 1062 static assert(A.i == 0); 1063 static assert(A.j == 0); 1064 } 1065 ), 1066 ); 1067 } 1068 1069 1070 @ShouldFail("cursor.enumConstantValue returning 0 for `value = I`") 1071 @Tags("issue") 1072 @("100") 1073 @safe unittest { 1074 shouldCompile( 1075 Cpp( 1076 q{ 1077 class T1 { 1078 enum { value = 42 }; 1079 }; 1080 1081 template<int I> 1082 class T2 { 1083 enum { value = I }; 1084 }; 1085 } 1086 ), 1087 D( 1088 q{ 1089 static assert(T1.value == 42); 1090 static assert(T2!2.value == 2); 1091 static assert(T2!3.value == 3); 1092 } 1093 ), 1094 ); 1095 } 1096 1097 1098 @Tags("issue") 1099 @("101") 1100 @safe unittest { 1101 // SO tells me the standard insists upon unsigned long long 1102 // and apparently so does MSVC... but linux doesn't. idk why. 1103 // see: https://stackoverflow.com/a/16596909/1457000 1104 version(Windows) 1105 string type = "unsigned long long"; 1106 else 1107 string type = "unsigned long"; 1108 shouldCompile( 1109 Cpp( 1110 q{ 1111 // normally without the underscore 1112 int operator "" _s(const wchar_t* __str, } ~ type ~ q{ __len); 1113 } 1114 ), 1115 D( 1116 q{ 1117 } 1118 ), 1119 ); 1120 } 1121 1122 1123 @Tags("issue") 1124 @("103.0") 1125 @safe unittest { 1126 with(immutable IncludeSandbox()) { 1127 writeFile("hdr.h", 1128 "#define CONSTANT 42\n"); 1129 writeFile("hdr.dpp", 1130 ` 1131 #include "hdr.h" 1132 `); 1133 writeFile("app.d", 1134 q{ 1135 import hdr; 1136 static assert(CONSTANT == 42); 1137 }); 1138 1139 runPreprocessOnly("hdr.dpp"); 1140 shouldCompile("app.d"); 1141 } 1142 } 1143 1144 1145 @Tags("issue") 1146 @("103.1") 1147 @safe unittest { 1148 with(immutable IncludeSandbox()) { 1149 writeFile("hdr.h", 1150 "#define OCTAL 00177\n"); 1151 writeFile("hdr.dpp", 1152 ` 1153 #include "hdr.h" 1154 `); 1155 writeFile("app.d", 1156 q{ 1157 import hdr; 1158 static assert(OCTAL == 127); 1159 }); 1160 1161 runPreprocessOnly("hdr.dpp"); 1162 shouldCompile("app.d"); 1163 } 1164 } 1165 1166 1167 @Tags("issue") 1168 @("103.2") 1169 @safe unittest { 1170 with(immutable IncludeSandbox()) { 1171 writeFile("hdr.h", 1172 "#define STRING \"foobar\"\n"); 1173 writeFile("hdr.dpp", 1174 ` 1175 #include "hdr.h" 1176 `); 1177 writeFile("app.d", 1178 q{ 1179 import hdr; 1180 static assert(STRING == "foobar"); 1181 }); 1182 1183 runPreprocessOnly("hdr.dpp"); 1184 shouldCompile("app.d"); 1185 } 1186 } 1187 1188 1189 @Tags("issue") 1190 @("103.3") 1191 @safe unittest { 1192 with(immutable IncludeSandbox()) { 1193 writeFile("hdr.h", 1194 ` 1195 #define BASE 5 1196 #define OPT0 (BASE * 16 + 0) 1197 #define OPT1 (BASE * 16 + 1) 1198 ` 1199 ); 1200 writeFile("hdr.dpp", 1201 ` 1202 #include "hdr.h" 1203 `); 1204 writeFile("app.d", 1205 q{ 1206 import hdr; 1207 static assert(BASE == 5); 1208 static assert(OPT0 == 80); 1209 static assert(OPT1 == 81); 1210 }); 1211 1212 runPreprocessOnly("hdr.dpp"); 1213 shouldCompile("app.d"); 1214 } 1215 } 1216 1217 1218 @Tags("issue") 1219 @("103.4") 1220 @safe unittest { 1221 with(immutable IncludeSandbox()) { 1222 writeFile("hdr.h", 1223 "#define OCTAL 00177\n"); 1224 writeFile("hdr.dpp", 1225 ` 1226 #include "hdr.h" 1227 `); 1228 writeFile("app.d", 1229 q{ 1230 import hdr; 1231 static assert(OCTAL == 127); 1232 }); 1233 1234 runPreprocessOnly("hdr.dpp"); 1235 shouldCompile(DFlags("-betterC"), "app.d"); 1236 } 1237 } 1238 1239 1240 1241 @ShouldFail 1242 @Tags("issue") 1243 @("104") 1244 @safe unittest { 1245 shouldCompile( 1246 Cpp( 1247 q{ 1248 template <int> struct Struct{}; 1249 template<> 1250 struct Struct<1 + 1> { 1251 static constexpr auto value = 42; 1252 }; 1253 } 1254 ), 1255 D( 1256 q{ 1257 static assert(Struct!2.value == 42); 1258 } 1259 ), 1260 ); 1261 } 1262 1263 1264 @Tags("issue") 1265 @("108") 1266 @safe unittest { 1267 shouldCompile( 1268 Cpp( 1269 q{ 1270 template<class T1, class T2, int I> 1271 class A {}; 1272 1273 template <typename CC> class C {}; 1274 1275 template<> 1276 class A<C<int>, double, 42> {}; 1277 } 1278 ), 1279 D( 1280 q{ 1281 1282 } 1283 ), 1284 ); 1285 } 1286 1287 1288 @Tags("issue") 1289 @("109") 1290 @safe unittest { 1291 shouldCompile( 1292 Cpp( 1293 q{ 1294 template<typename C> class Test 1295 { 1296 bool operator==(const Test<C>& x) const { return 0; } 1297 bool operator<(const Test<C>& x) const { return 0; } 1298 bool operator>(const Test<C>& x) const { return 0; } 1299 }; 1300 } 1301 ), 1302 D( 1303 q{ 1304 const t = Test!int(); 1305 const eq = t == t; 1306 const lt = t < t; 1307 const gt = t > t; 1308 } 1309 ), 1310 ); 1311 } 1312 1313 1314 @Tags("issue") 1315 @("110") 1316 @safe unittest { 1317 shouldCompile( 1318 Cpp( 1319 q{ 1320 class A { 1321 bool operator_a() const; 1322 }; 1323 } 1324 ), 1325 D( 1326 q{ 1327 auto a = new const A; 1328 bool ret = a.operator_a(); 1329 } 1330 ), 1331 ); 1332 } 1333 1334 1335 1336 @Tags("issue", "namespace") 1337 @("113") 1338 @safe unittest { 1339 shouldCompile( 1340 Cpp( 1341 q{ 1342 // the issue here was nested namespaces 1343 namespace ns1 { 1344 namespace ns2 { 1345 struct Struct; 1346 1347 template<typename T> 1348 struct Template { 1349 }; 1350 1351 class Class; // should be ignored but isn't 1352 class Class: public Template<Struct> { 1353 int i; 1354 }; 1355 } 1356 } 1357 } 1358 ), 1359 D( 1360 q{ 1361 } 1362 ), 1363 ); 1364 } 1365 1366 1367 @Tags("issue") 1368 @("114") 1369 @safe unittest { 1370 shouldCompile( 1371 Cpp( 1372 q{ 1373 template<class T> 1374 struct Foo { 1375 template<class U> 1376 Foo& operator=(U& other) { 1377 return *this; 1378 } 1379 }; 1380 } 1381 ), 1382 D( 1383 q{ 1384 Foo!int foo; 1385 int i; 1386 foo = i; 1387 double d; 1388 foo = d; 1389 } 1390 ), 1391 ); 1392 } 1393 1394 1395 @Tags("issue") 1396 @("115") 1397 @safe unittest { 1398 shouldCompile( 1399 Cpp( 1400 q{ 1401 template<class T> 1402 class Foo { 1403 T value; 1404 public: 1405 Foo(T value); 1406 }; 1407 1408 template<class T> 1409 Foo<T>::Foo(T val) { 1410 value = val; 1411 } 1412 } 1413 ), 1414 D( 1415 q{ 1416 auto fooI = Foo!int(42); 1417 auto fooD = Foo!double(33.3); 1418 } 1419 ), 1420 ); 1421 } 1422 1423 1424 @Tags("issue") 1425 @("116") 1426 @safe unittest { 1427 shouldCompile( 1428 Cpp( 1429 q{ 1430 struct Foo; 1431 struct Foo { int i; }; 1432 } 1433 ), 1434 D( 1435 q{ 1436 static assert(is(typeof(Foo.i) == int)); 1437 } 1438 ), 1439 ); 1440 } 1441 1442 1443 @Tags("issue") 1444 @("119.0") 1445 @safe unittest { 1446 shouldCompile( 1447 Cpp( 1448 q{ 1449 struct Struct { 1450 enum Enum { foo, bar, baz }; 1451 }; 1452 1453 void fun(Struct::Enum); 1454 } 1455 ), 1456 D( 1457 q{ 1458 } 1459 ), 1460 ); 1461 } 1462 1463 1464 @Tags("issue") 1465 @("119.1") 1466 @safe unittest { 1467 shouldCompile( 1468 Cpp( 1469 q{ 1470 struct Struct { 1471 enum class Enum { foo, bar, baz }; 1472 }; 1473 } 1474 ), 1475 D( 1476 q{ 1477 auto f = Struct.Enum.foo; 1478 static assert(!__traits(compiles, Struct.foo)); 1479 } 1480 ), 1481 ); 1482 } 1483 1484 1485 @ShouldFail("libclang fails to tokenise this for some reason") 1486 @Tags("issue", "libclang") 1487 @("119.2") 1488 @safe unittest { 1489 with(immutable IncludeSandbox()) { 1490 1491 writeFile("util.hpp", 1492 ` 1493 #define MAKE_ENUM_CLASS(type, values) enum class type { values }; 1494 `); 1495 1496 writeFile("hdr.hpp", 1497 ` 1498 #include "util.hpp" 1499 #define VALUES X(foo) X(bar) X(baz) 1500 #define X(n) n, 1501 MAKE_ENUM_CLASS(Enum, VALUES) 1502 #undef X 1503 `); 1504 1505 writeFile("app.dpp", 1506 ` 1507 #include "hdr.hpp" 1508 void main() { 1509 auto f = Enum.foo; 1510 static assert(!__traits(compiles, foo)); 1511 } 1512 `); 1513 1514 runPreprocessOnly(["app.dpp"]); 1515 shouldCompile("app.d"); 1516 } 1517 } 1518 1519 1520 @Tags("issue") 1521 @("134") 1522 @safe unittest { 1523 shouldCompile( 1524 Cpp( 1525 q{ 1526 struct Foo { 1527 double fun(int i) const; 1528 }; 1529 1530 double Foo::fun(int i) const { 1531 return i * 2; 1532 } 1533 } 1534 ), 1535 D( 1536 q{ 1537 auto foo = Foo(); 1538 double d = foo.fun(42); 1539 } 1540 ), 1541 ); 1542 } 1543 1544 1545 @Tags("namespace", "issue") 1546 @("149") 1547 @safe unittest { 1548 shouldCompile( 1549 Cpp( 1550 q{ 1551 namespace ns { 1552 struct Struct; 1553 1554 template<typename T> 1555 struct Template { }; 1556 1557 // The `Struct` template parameter must be translated properly 1558 // and was showing up as ns.Struct 1559 class Class: public Template<Struct> { 1560 int i; 1561 }; 1562 } 1563 } 1564 ), 1565 D( 1566 q{ 1567 } 1568 ), 1569 ); 1570 } 1571 1572 1573 @Tags("issue") 1574 @("150") 1575 @safe unittest { 1576 shouldCompile( 1577 Cpp( 1578 q{ 1579 struct Foo { 1580 int a, b, c; 1581 }; 1582 1583 struct Bar { 1584 Foo& foo; 1585 }; 1586 } 1587 ), 1588 D( 1589 q{ 1590 import std.conv: text; 1591 static assert(Foo.sizeof == 12, Foo.sizeof.text); 1592 static assert(Foo.alignof == 4, Foo.alignof.text); 1593 static assert(Bar.sizeof == 8, Bar.sizeof.text); 1594 static assert(Bar.alignof == 8, Bar.alignof.text); 1595 } 1596 ), 1597 ); 1598 } 1599 1600 1601 @Tags("issue") 1602 @("151") 1603 @safe unittest { 1604 shouldRun( 1605 Cpp( 1606 q{ 1607 struct Foo { 1608 long data; 1609 }; 1610 1611 struct Bar { 1612 static long numDtors; 1613 long data; 1614 ~Bar(); 1615 }; 1616 1617 Foo makeFoo(); 1618 Bar makeBar(); 1619 } 1620 ), 1621 Cpp( 1622 q{ 1623 Foo makeFoo() { return {}; } 1624 Bar makeBar() { return {}; } 1625 Bar::~Bar() { ++numDtors; } 1626 long Bar::numDtors; 1627 } 1628 ), 1629 D( 1630 q{ 1631 import std.conv: text; 1632 1633 auto foo = makeFoo; 1634 assert(foo.data == 0, foo.data.text); 1635 1636 { 1637 auto bar = makeBar; 1638 assert(bar.data == 0, bar.data.text); 1639 bar.data = 42; 1640 assert(bar.numDtors == 0, bar.numDtors.text); 1641 } 1642 1643 assert(Bar.numDtors == 1, Bar.numDtors.text); 1644 } 1645 ), 1646 ); 1647 } 1648 1649 1650 @("missing.template.parameter") 1651 @safe unittest { 1652 shouldCompile( 1653 Cpp( 1654 q{ 1655 namespace myns { 1656 template<typename T> 1657 struct vector { 1658 T* elements; 1659 long size; 1660 }; 1661 } 1662 1663 struct Problem { 1664 // In the issue this gets emitted as `vector values` 1665 // instead of `vector!double values` 1666 myns::vector<double> values; 1667 }; 1668 1669 Problem createProblem(); 1670 } 1671 ), 1672 D( 1673 q{ 1674 } 1675 ), 1676 ); 1677 } 1678 1679 @Tags("issue") 1680 @("168") 1681 // @("gcc.__extention__") 1682 // Examples: 1683 // /usr/include/netinet/in.h 1684 // /usr/include/x86_64-linux-gnu/bits/cpu-set.h 1685 @safe unittest { 1686 shouldCompile( 1687 C( 1688 ` 1689 #define FOO(bar) {__extension__({bar;}) 1690 ` 1691 ), 1692 D( 1693 q{ 1694 } 1695 ) 1696 ); 1697 } 1698 1699 1700 @Tags("issue") 1701 @("172") 1702 @safe unittest { 1703 shouldCompile( 1704 Cpp( 1705 q{ 1706 struct virtual_base { 1707 virtual_base() = default; 1708 virtual ~virtual_base() = default; 1709 virtual_base(virtual_base&&) = default; 1710 virtual_base(const virtual_base&) = default; 1711 virtual_base& operator=(virtual_base&&) = default; 1712 virtual_base& operator=(const virtual_base&) = default; 1713 }; 1714 } 1715 ), 1716 D( 1717 q{ 1718 } 1719 ) 1720 ); 1721 } 1722 1723 1724 @HiddenTest("Needs the cl_platform.h header on the machine") 1725 @Tags("issue") 1726 @("175") 1727 @safe unittest { 1728 shouldCompile( 1729 C( 1730 ` 1731 #include "CL/cl_platform.h" 1732 ` 1733 ), 1734 D( 1735 q{ 1736 } 1737 ) 1738 ); 1739 } 1740 1741 1742 @Tags("issue") 1743 @("207") 1744 @safe unittest { 1745 shouldCompile( 1746 C( 1747 ` 1748 #define FOO 1 1749 #define BAR 2 1750 #define BAZ 4 1751 #define ALL ( \ 1752 FOO | \ 1753 BAR | \ 1754 BAZ \ 1755 ) 1756 ` 1757 ), 1758 D( 1759 q{ 1760 static assert(ALL == 7); 1761 } 1762 ) 1763 ); 1764 } 1765 1766 1767 version(Linux) { 1768 @Tags("issue") 1769 @("229.0") 1770 @safe unittest { 1771 with(immutable IncludeSandbox()) { 1772 writeFile(`app.dpp`, 1773 ` 1774 module foo.linux.bar; 1775 ` 1776 ); 1777 runPreprocessOnly("app.dpp"); 1778 shouldNotCompile("app.d"); 1779 } 1780 } 1781 1782 1783 @Tags("issue") 1784 @("229.1") 1785 @safe unittest { 1786 with(immutable IncludeSandbox()) { 1787 writeFile(`app.dpp`, 1788 ` 1789 #undef linux 1790 module foo.linux.bar; 1791 ` 1792 ); 1793 runPreprocessOnly("app.dpp"); 1794 shouldCompile("app.d"); 1795 } 1796 } 1797 } 1798 1799 1800 @Tags("issue") 1801 @("244") 1802 @safe unittest { 1803 shouldCompile( 1804 C( 1805 ` 1806 #define IS_FOO(obj) true 1807 #define IS_BAR(obj) true 1808 #define IS_PRIM(obj)(IS_FOO(obj) \ 1809 ||IS_BAR(obj)) 1810 // notice that IS_QUUX doesn't have balanced parens 1811 #define IS_QUUX(obj) (!(IS_PRIM(obj)) 1812 ` 1813 ), 1814 D( 1815 q{ 1816 } 1817 ) 1818 ); 1819 } 1820 1821 1822 @ShouldFail 1823 @Tags("issue") 1824 @("269") 1825 @safe unittest { 1826 shouldCompile( 1827 Cpp( 1828 q{ 1829 struct OopsStruct {}; 1830 namespace Oops { 1831 void fun(OopsStruct); 1832 } 1833 } 1834 ), 1835 D( 1836 q{ 1837 fun(OopsStruct()); 1838 } 1839 ), 1840 ); 1841 } 1842 1843 1844 @ShouldFail 1845 @Tags("issue") 1846 @("270") 1847 @safe unittest { 1848 shouldRun( 1849 Cpp( 1850 q{ 1851 int twice(int i = 1); 1852 } 1853 ), 1854 Cpp( 1855 q{ 1856 int twice(int i) { return i * 2; } 1857 } 1858 ), 1859 D( 1860 q{ 1861 assert(twice(2) == 4); 1862 assert(twice(3) == 6); 1863 assert(twice() == 2); 1864 } 1865 ), 1866 ); 1867 } 1868 1869 1870 @ShouldFail 1871 @Tags("issue") 1872 @("282") 1873 @safe unittest { 1874 shouldCompile( 1875 C( 1876 q{ 1877 typedef double array[2]; 1878 void oops(array* a); 1879 } 1880 ), 1881 D( 1882 q{ 1883 double[2] doubles; 1884 oops(&doubles); 1885 } 1886 ) 1887 ); 1888 } 1889 1890 1891 @ShouldFail 1892 @Tags("issue") 1893 @("297") 1894 @safe unittest { 1895 shouldCompile( 1896 C( 1897 q{ 1898 struct B 1899 { 1900 union 1901 { 1902 int a; 1903 char c; 1904 }; 1905 }; 1906 } 1907 ), 1908 D( 1909 q{ 1910 B b; 1911 int* a = &b.a; 1912 } 1913 ) 1914 ); 1915 } 1916 1917 1918 @Tags("issue") 1919 @("303") 1920 @safe unittest { 1921 shouldCompile( 1922 C( 1923 ` 1924 #include <stdint.h> 1925 typedef uint64_t Index; 1926 #define INDEX_MAX ((Index) (1ULL << 60)) 1927 ` 1928 ), 1929 D( 1930 q{ 1931 static assert(INDEX_MAX == (1UL << 60)); 1932 } 1933 ) 1934 ); 1935 1936 } 1937 1938 @Tags("issue") 1939 @("307") 1940 @safe unittest { 1941 with(immutable IncludeSandbox()) { 1942 import std.path : pathSeparator; 1943 import std.process : environment; 1944 import std.string : join; 1945 1946 writeFile("includes/dir1/issue307.h", 1947 ` 1948 #ifndef ISSUE307_H 1949 #define ISSUE307_H 1950 #if __has_include_next(<issue307.h>) 1951 #include_next <issue307.h> 1952 #else // fallback for cpp that does not support include_next 1953 typedef int myint_t; 1954 #endif 1955 #endif 1956 `); 1957 writeFile("includes/dir2/issue307.h", 1958 ` 1959 typedef int myint_t; 1960 `); 1961 writeFile("issue307.dpp", 1962 ` 1963 #include <issue307.h> 1964 `); 1965 1966 auto original_cpath = environment.get("CPATH", ""); 1967 environment["CPATH"] = [ 1968 inSandboxPath("includes/dir1"), 1969 inSandboxPath("includes/dir2"), 1970 original_cpath, 1971 ].join(pathSeparator); 1972 scope(exit) 1973 { 1974 if (original_cpath == "") 1975 { 1976 environment.remove("CPATH"); 1977 } 1978 else 1979 { 1980 environment["CPATH"] = original_cpath; 1981 } 1982 } 1983 1984 runPreprocessOnly("issue307.dpp"); 1985 fileShouldContain("issue307.d", q{alias myint_t = int;}); 1986 } 1987 } 1988 1989 @Tags("issue") 1990 @("312") 1991 @safe unittest { 1992 shouldCompile( 1993 C( 1994 q{ 1995 /** 1996 * & enable_if_c // see untranslatable 1997 */ 1998 int foo(int); 1999 } 2000 ), 2001 D( 2002 q{ 2003 int f = foo(42); 2004 } 2005 ) 2006 ); 2007 }