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 1219 @ShouldFail 1220 @Tags("issue") 1221 @("104") 1222 @safe unittest { 1223 shouldCompile( 1224 Cpp( 1225 q{ 1226 template <int> struct Struct{}; 1227 template<> 1228 struct Struct<1 + 1> { 1229 static constexpr auto value = 42; 1230 }; 1231 } 1232 ), 1233 D( 1234 q{ 1235 static assert(Struct!2.value == 42); 1236 } 1237 ), 1238 ); 1239 } 1240 1241 1242 @Tags("issue") 1243 @("108") 1244 @safe unittest { 1245 shouldCompile( 1246 Cpp( 1247 q{ 1248 template<class T1, class T2, int I> 1249 class A {}; 1250 1251 template <typename CC> class C {}; 1252 1253 template<> 1254 class A<C<int>, double, 42> {}; 1255 } 1256 ), 1257 D( 1258 q{ 1259 1260 } 1261 ), 1262 ); 1263 } 1264 1265 1266 @Tags("issue") 1267 @("109") 1268 @safe unittest { 1269 shouldCompile( 1270 Cpp( 1271 q{ 1272 template<typename C> class Test 1273 { 1274 bool operator==(const Test<C>& x) const { return 0; } 1275 bool operator<(const Test<C>& x) const { return 0; } 1276 bool operator>(const Test<C>& x) const { return 0; } 1277 }; 1278 } 1279 ), 1280 D( 1281 q{ 1282 const t = Test!int(); 1283 const eq = t == t; 1284 const lt = t < t; 1285 const gt = t > t; 1286 } 1287 ), 1288 ); 1289 } 1290 1291 1292 @Tags("issue") 1293 @("110") 1294 @safe unittest { 1295 shouldCompile( 1296 Cpp( 1297 q{ 1298 class A { 1299 bool operator_a() const; 1300 }; 1301 } 1302 ), 1303 D( 1304 q{ 1305 auto a = new const A; 1306 bool ret = a.operator_a(); 1307 } 1308 ), 1309 ); 1310 } 1311 1312 1313 1314 @Tags("issue", "namespace") 1315 @("113") 1316 @safe unittest { 1317 shouldCompile( 1318 Cpp( 1319 q{ 1320 // the issue here was nested namespaces 1321 namespace ns1 { 1322 namespace ns2 { 1323 struct Struct; 1324 1325 template<typename T> 1326 struct Template { 1327 }; 1328 1329 class Class; // should be ignored but isn't 1330 class Class: public Template<Struct> { 1331 int i; 1332 }; 1333 } 1334 } 1335 } 1336 ), 1337 D( 1338 q{ 1339 } 1340 ), 1341 ); 1342 } 1343 1344 1345 @Tags("issue") 1346 @("114") 1347 @safe unittest { 1348 shouldCompile( 1349 Cpp( 1350 q{ 1351 template<class T> 1352 struct Foo { 1353 template<class U> 1354 Foo& operator=(U& other) { 1355 return *this; 1356 } 1357 }; 1358 } 1359 ), 1360 D( 1361 q{ 1362 Foo!int foo; 1363 int i; 1364 foo = i; 1365 double d; 1366 foo = d; 1367 } 1368 ), 1369 ); 1370 } 1371 1372 1373 @Tags("issue") 1374 @("115") 1375 @safe unittest { 1376 shouldCompile( 1377 Cpp( 1378 q{ 1379 template<class T> 1380 class Foo { 1381 T value; 1382 public: 1383 Foo(T value); 1384 }; 1385 1386 template<class T> 1387 Foo<T>::Foo(T val) { 1388 value = val; 1389 } 1390 } 1391 ), 1392 D( 1393 q{ 1394 auto fooI = Foo!int(42); 1395 auto fooD = Foo!double(33.3); 1396 } 1397 ), 1398 ); 1399 } 1400 1401 1402 @Tags("issue") 1403 @("116") 1404 @safe unittest { 1405 shouldCompile( 1406 Cpp( 1407 q{ 1408 struct Foo; 1409 struct Foo { int i; }; 1410 } 1411 ), 1412 D( 1413 q{ 1414 static assert(is(typeof(Foo.i) == int)); 1415 } 1416 ), 1417 ); 1418 } 1419 1420 1421 @Tags("issue") 1422 @("119.0") 1423 @safe unittest { 1424 shouldCompile( 1425 Cpp( 1426 q{ 1427 struct Struct { 1428 enum Enum { foo, bar, baz }; 1429 }; 1430 1431 void fun(Struct::Enum); 1432 } 1433 ), 1434 D( 1435 q{ 1436 } 1437 ), 1438 ); 1439 } 1440 1441 1442 @Tags("issue") 1443 @("119.1") 1444 @safe unittest { 1445 shouldCompile( 1446 Cpp( 1447 q{ 1448 struct Struct { 1449 enum class Enum { foo, bar, baz }; 1450 }; 1451 } 1452 ), 1453 D( 1454 q{ 1455 auto f = Struct.Enum.foo; 1456 static assert(!__traits(compiles, Struct.foo)); 1457 } 1458 ), 1459 ); 1460 } 1461 1462 1463 @ShouldFail("libclang fails to tokenise this for some reason") 1464 @Tags("issue", "libclang") 1465 @("119.2") 1466 @safe unittest { 1467 with(immutable IncludeSandbox()) { 1468 1469 writeFile("util.hpp", 1470 ` 1471 #define MAKE_ENUM_CLASS(type, values) enum class type { values }; 1472 `); 1473 1474 writeFile("hdr.hpp", 1475 ` 1476 #include "util.hpp" 1477 #define VALUES X(foo) X(bar) X(baz) 1478 #define X(n) n, 1479 MAKE_ENUM_CLASS(Enum, VALUES) 1480 #undef X 1481 `); 1482 1483 writeFile("app.dpp", 1484 ` 1485 #include "hdr.hpp" 1486 void main() { 1487 auto f = Enum.foo; 1488 static assert(!__traits(compiles, foo)); 1489 } 1490 `); 1491 1492 runPreprocessOnly(["app.dpp"]); 1493 shouldCompile("app.d"); 1494 } 1495 } 1496 1497 1498 @Tags("issue") 1499 @("134") 1500 @safe unittest { 1501 shouldCompile( 1502 Cpp( 1503 q{ 1504 struct Foo { 1505 double fun(int i) const; 1506 }; 1507 1508 double Foo::fun(int i) const { 1509 return i * 2; 1510 } 1511 } 1512 ), 1513 D( 1514 q{ 1515 auto foo = Foo(); 1516 double d = foo.fun(42); 1517 } 1518 ), 1519 ); 1520 } 1521 1522 1523 @Tags("namespace", "issue") 1524 @("149") 1525 @safe unittest { 1526 shouldCompile( 1527 Cpp( 1528 q{ 1529 namespace ns { 1530 struct Struct; 1531 1532 template<typename T> 1533 struct Template { }; 1534 1535 // The `Struct` template parameter must be translated properly 1536 // and was showing up as ns.Struct 1537 class Class: public Template<Struct> { 1538 int i; 1539 }; 1540 } 1541 } 1542 ), 1543 D( 1544 q{ 1545 } 1546 ), 1547 ); 1548 } 1549 1550 1551 @Tags("issue") 1552 @("150") 1553 @safe unittest { 1554 shouldCompile( 1555 Cpp( 1556 q{ 1557 struct Foo { 1558 int a, b, c; 1559 }; 1560 1561 struct Bar { 1562 Foo& foo; 1563 }; 1564 } 1565 ), 1566 D( 1567 q{ 1568 import std.conv: text; 1569 static assert(Foo.sizeof == 12, Foo.sizeof.text); 1570 static assert(Foo.alignof == 4, Foo.alignof.text); 1571 static assert(Bar.sizeof == 8, Bar.sizeof.text); 1572 static assert(Bar.alignof == 8, Bar.alignof.text); 1573 } 1574 ), 1575 ); 1576 } 1577 1578 1579 @Tags("issue") 1580 @("151") 1581 @safe unittest { 1582 shouldRun( 1583 Cpp( 1584 q{ 1585 struct Foo { 1586 long data; 1587 }; 1588 1589 struct Bar { 1590 static long numDtors; 1591 long data; 1592 ~Bar(); 1593 }; 1594 1595 Foo makeFoo(); 1596 Bar makeBar(); 1597 } 1598 ), 1599 Cpp( 1600 q{ 1601 Foo makeFoo() { return {}; } 1602 Bar makeBar() { return {}; } 1603 Bar::~Bar() { ++numDtors; } 1604 long Bar::numDtors; 1605 } 1606 ), 1607 D( 1608 q{ 1609 import std.conv: text; 1610 1611 auto foo = makeFoo; 1612 assert(foo.data == 0, foo.data.text); 1613 1614 { 1615 auto bar = makeBar; 1616 assert(bar.data == 0, bar.data.text); 1617 bar.data = 42; 1618 assert(bar.numDtors == 0, bar.numDtors.text); 1619 } 1620 1621 assert(Bar.numDtors == 1, Bar.numDtors.text); 1622 } 1623 ), 1624 ); 1625 } 1626 1627 1628 @("missing.template.parameter") 1629 @safe unittest { 1630 shouldCompile( 1631 Cpp( 1632 q{ 1633 namespace myns { 1634 template<typename T> 1635 struct vector { 1636 T* elements; 1637 long size; 1638 }; 1639 } 1640 1641 struct Problem { 1642 // In the issue this gets emitted as `vector values` 1643 // instead of `vector!double values` 1644 myns::vector<double> values; 1645 }; 1646 1647 Problem createProblem(); 1648 } 1649 ), 1650 D( 1651 q{ 1652 } 1653 ), 1654 ); 1655 } 1656 1657 @Tags("issue") 1658 @("168") 1659 // @("gcc.__extention__") 1660 // Examples: 1661 // /usr/include/netinet/in.h 1662 // /usr/include/x86_64-linux-gnu/bits/cpu-set.h 1663 @safe unittest { 1664 shouldCompile( 1665 C( 1666 ` 1667 #define FOO(bar) {__extension__({bar;}) 1668 ` 1669 ), 1670 D( 1671 q{ 1672 } 1673 ) 1674 ); 1675 } 1676 1677 1678 @Tags("issue") 1679 @("172") 1680 @safe unittest { 1681 shouldCompile( 1682 Cpp( 1683 q{ 1684 struct virtual_base { 1685 virtual_base() = default; 1686 virtual ~virtual_base() = default; 1687 virtual_base(virtual_base&&) = default; 1688 virtual_base(const virtual_base&) = default; 1689 virtual_base& operator=(virtual_base&&) = default; 1690 virtual_base& operator=(const virtual_base&) = default; 1691 }; 1692 } 1693 ), 1694 D( 1695 q{ 1696 } 1697 ) 1698 ); 1699 } 1700 1701 1702 @HiddenTest("Needs the cl_platform.h header on the machine") 1703 @Tags("issue") 1704 @("175") 1705 @safe unittest { 1706 shouldCompile( 1707 C( 1708 ` 1709 #include "CL/cl_platform.h" 1710 ` 1711 ), 1712 D( 1713 q{ 1714 } 1715 ) 1716 ); 1717 } 1718 1719 1720 @Tags("issue") 1721 @("207") 1722 @safe unittest { 1723 shouldCompile( 1724 C( 1725 ` 1726 #define FOO 1 1727 #define BAR 2 1728 #define BAZ 4 1729 #define ALL ( \ 1730 FOO | \ 1731 BAR | \ 1732 BAZ \ 1733 ) 1734 ` 1735 ), 1736 D( 1737 q{ 1738 static assert(ALL == 7); 1739 } 1740 ) 1741 ); 1742 } 1743 1744 1745 version(Linux) { 1746 @Tags("issue") 1747 @("229.0") 1748 @safe unittest { 1749 with(immutable IncludeSandbox()) { 1750 writeFile(`app.dpp`, 1751 ` 1752 module foo.linux.bar; 1753 ` 1754 ); 1755 runPreprocessOnly("app.dpp"); 1756 shouldNotCompile("app.d"); 1757 } 1758 } 1759 1760 1761 @Tags("issue") 1762 @("229.1") 1763 @safe unittest { 1764 with(immutable IncludeSandbox()) { 1765 writeFile(`app.dpp`, 1766 ` 1767 #undef linux 1768 module foo.linux.bar; 1769 ` 1770 ); 1771 runPreprocessOnly("app.dpp"); 1772 shouldCompile("app.d"); 1773 } 1774 } 1775 } 1776 1777 1778 1779 @Tags("issue") 1780 @("237") 1781 @safe unittest { 1782 shouldCompile( 1783 C( 1784 ` 1785 #define GPIO_AFR(n, af) ((af) << ((n) * 4)) 1786 #define GPIO_AFR_MASK(n) (0xf << ((n) * 4)) 1787 ` 1788 ), 1789 D( 1790 q{ 1791 } 1792 ) 1793 ); 1794 }