1 /** 2 Github issues. 3 */ 4 module it.issues; 5 6 import it; 7 8 @Tags("issue") 9 @("3") 10 @safe unittest { 11 shouldCompile( 12 C( 13 ` 14 #include <signal.h> 15 ` 16 ), 17 D( 18 q{ 19 siginfo_t si; 20 si._sifields._timer.si_tid = 2; 21 static assert(is(typeof(si.si_signo) == int)); 22 static assert(is(typeof(si._sifields._timer.si_tid) == int), 23 typeof(si._sifields._timer.si_tid).stringof); 24 } 25 ), 26 ); 27 } 28 29 30 @Tags("issue") 31 @("4") 32 @safe unittest { 33 with(immutable IncludeSandbox()) { 34 writeFile("issue4.h", 35 q{ 36 extern char *arr[9]; 37 }); 38 writeFile("issue4.dpp", 39 ` 40 #include "issue4.h" 41 `); 42 runPreprocessOnly("issue4.dpp"); 43 fileShouldContain("issue4.d", q{extern __gshared char*[9] arr;}); 44 } 45 } 46 47 @Tags("issue") 48 @("5") 49 @safe unittest { 50 shouldCompile( 51 C( 52 q{ 53 typedef enum zfs_error { 54 EZFS_SUCCESS = 0, 55 EZFS_NOMEM = 2000, 56 }; 57 58 typedef struct zfs_perm_node { 59 char z_pname[4096]; 60 } zfs_perm_node_t; 61 62 typedef struct libzfs_handle libzfs_handle_t; 63 } 64 ), 65 D( 66 q{ 67 zfs_error e1 = EZFS_SUCCESS; 68 zfs_error e2 = zfs_error.EZFS_SUCCESS; 69 zfs_perm_node_t node; 70 static assert(node.z_pname.sizeof == 4096); 71 static assert(is(typeof(node.z_pname[0]) == char), (typeof(node.z_pname[0]).stringof)); 72 libzfs_handle_t* ptr; 73 } 74 ), 75 ); 76 } 77 78 @Tags("issue") 79 @("6") 80 @safe unittest { 81 with(immutable IncludeSandbox()) { 82 writeFile("issue6.h", 83 q{ 84 char *getMessage(); 85 }); 86 writeFile("issue6.dpp", 87 ` 88 #include "issue6.h" 89 `); 90 runPreprocessOnly("issue6.dpp"); 91 fileShouldContain("issue6.d", q{char* getMessage() @nogc nothrow;}); 92 } 93 } 94 95 96 @Tags("issue", "bitfield") 97 @("7") 98 @safe unittest { 99 shouldCompile( 100 C( 101 q{ 102 struct splitflags { 103 int dryrun : 1; 104 int import : 2; 105 int name_flags; 106 int foo: 3; 107 int bar: 4; 108 int suffix; 109 }; 110 111 struct other { 112 int quux: 2; 113 int toto: 3; 114 }; 115 } 116 ), 117 D( 118 q{ 119 static assert(splitflags.sizeof == 16); 120 static assert(other.sizeof == 4); 121 } 122 ), 123 ); 124 } 125 126 @Tags("issue") 127 @("10") 128 @safe unittest { 129 shouldCompile( 130 C( 131 q{ 132 enum silly_name { 133 FOO, 134 BAR, 135 BAZ, 136 }; 137 138 extern void silly_name(enum silly_name thingie); 139 } 140 ), 141 D( 142 q{ 143 silly_name_(silly_name.FOO); 144 } 145 ), 146 ); 147 } 148 149 @Tags("issue") 150 @("11") 151 @safe unittest { 152 shouldCompile( 153 C( 154 q{ 155 struct Foo; 156 typedef struct Foo* FooPtr; 157 } 158 ), 159 D( 160 q{ 161 FooPtr f = null; 162 static assert(!__traits(compiles, Foo())); 163 } 164 ), 165 ); 166 } 167 168 @Tags("issue") 169 @("14") 170 @safe unittest { 171 import dpp.runtime.options: Options; 172 with(immutable IncludeSandbox()) { 173 174 writeFile("foo.h", 175 q{ 176 typedef int foo; 177 }); 178 179 runPreprocessOnly("foo.h").shouldThrowWithMessage( 180 "No .dpp input file specified\n" ~ Options.usage); 181 } 182 } 183 184 @Tags("issue", "preprocessor") 185 @("22.0") 186 @safe unittest { 187 shouldCompile( 188 C( 189 ` 190 typedef struct { 191 #ifdef __USE_XOPEN 192 int fds_bits[42]; 193 #define __FDS_BITS(set) ((set)->fds_bits) 194 #else 195 int __fds_bits[42]; 196 #define __FDS_BITS(set) ((set)->__fds_bits) 197 #endif 198 } fd_set; 199 ` 200 ), 201 D( 202 q{ 203 fd_set set; 204 __FDS_BITS(set)[0] = 42; 205 } 206 ), 207 ); 208 } 209 210 @Tags("issue", "preprocessor") 211 @("22.1") 212 @safe unittest { 213 shouldCompile( 214 C( 215 ` 216 #define SIZEOF(x) (sizeof(x)) 217 ` 218 ), 219 D( 220 q{ 221 int i; 222 static assert(SIZEOF(i) == 4); 223 } 224 ), 225 ); 226 } 227 228 @ShouldFail 229 @Tags("issue", "preprocessor") 230 @("22.3") 231 @safe unittest { 232 shouldCompile( 233 C( 234 ` 235 typedef long int __fd_mask; 236 #define __NFDBITS (8 * (int) sizeof (__fd_mask)) 237 ` 238 ), 239 D( 240 q{ 241 import std.conv; 242 static assert(__NFDBITS == 8 * c_long.sizeof, 243 text("expected ", 8 * c_long.sizeof, ", got: ", __NFDBITS)); 244 } 245 ), 246 ); 247 } 248 249 @Tags("issue", "preprocessor") 250 @("22.4") 251 @safe unittest { 252 shouldCompile( 253 C( 254 ` 255 typedef struct clist { struct list* next; }; 256 #define clist_next(iter) (iter ? (iter)->next : NULL) 257 ` 258 ), 259 D( 260 q{ 261 clist l; 262 auto next = clist_next(&l); 263 } 264 ), 265 ); 266 } 267 268 269 270 @Tags("issue", "collision", "issue24") 271 @("24.0") 272 @safe unittest { 273 shouldCompile( 274 C( 275 q{ 276 struct Bar { 277 void (*Foo)(void); // this should get renamed as Foo_ 278 struct Foo* (*whatever)(void); 279 }; 280 } 281 ), 282 D( 283 q{ 284 } 285 ), 286 ); 287 } 288 289 @Tags("issue", "collision", "issue24") 290 @("24.1") 291 @safe unittest { 292 shouldCompile( 293 C( 294 q{ 295 int foo(int, struct foo_data**); 296 struct foo { int dummy; }; 297 struct foo_data { int dummy; }; 298 } 299 ), 300 D( 301 q{ 302 foo_data** data; 303 int ret = foo_(42, data); 304 foo s; 305 s.dummy = 33; 306 foo_data fd; 307 fd.dummy = 77; 308 } 309 ), 310 ); 311 } 312 313 314 @Tags("issue") 315 @("29.0") 316 @safe unittest { 317 shouldCompile( 318 C( 319 q{ 320 typedef struct { 321 union { 322 struct { 323 double x; 324 double y; 325 double z; 326 }; 327 double raw[3]; 328 }; 329 } vec3d_t; 330 } 331 ), 332 D( 333 q{ 334 vec3d_t v; 335 static assert(v.sizeof == 24); 336 v.raw[1] = 3.0; 337 v.y = 4.0; 338 } 339 ), 340 ); 341 } 342 343 @Tags("issue") 344 @("29.1") 345 @safe unittest { 346 shouldCompile( 347 C( 348 q{ 349 typedef struct { 350 struct { 351 int x; 352 int y; 353 }; 354 355 struct { 356 int z; 357 }; 358 } Struct; 359 } 360 ), 361 D( 362 q{ 363 Struct s; 364 s.x = 2; 365 s.y = 3; 366 s.z = 4; 367 } 368 ), 369 ); 370 } 371 372 @Tags("issue") 373 @("29.2") 374 @safe unittest { 375 shouldCompile( 376 C( 377 q{ 378 struct Struct { 379 union { 380 unsigned long long int foo; 381 struct { 382 unsigned int low; 383 unsigned int high; 384 } foo32; 385 }; 386 }; 387 } 388 ), 389 D( 390 q{ 391 Struct s; 392 s.foo = 42; 393 s.foo32.low = 33; 394 s.foo32.high = 77; 395 } 396 ), 397 ); 398 } 399 400 401 @Tags("issue") 402 @("29.3") 403 @safe unittest { 404 shouldCompile( 405 C( 406 q{ 407 struct Struct { 408 union { 409 unsigned long long int foo; 410 void *bar; 411 }; 412 }; 413 } 414 ), 415 D( 416 q{ 417 Struct s; 418 s.foo = 42; 419 s.bar = null; 420 } 421 ), 422 ); 423 } 424 425 426 @Tags("issue") 427 @("33.0") 428 @safe unittest { 429 shouldCompile( 430 C( 431 q{ 432 void (*f)(); 433 } 434 ), 435 D( 436 q{ 437 static extern(C) void printHello() { } 438 f = &printHello; 439 f(); 440 } 441 ), 442 ); 443 } 444 445 @Tags("issue") 446 @("33.1") 447 @safe unittest { 448 shouldCompile( 449 C( 450 q{ 451 int (*f)(); 452 } 453 ), 454 D( 455 q{ 456 static extern(C) int func() { return 42; } 457 f = &func; 458 int i = f(); 459 } 460 ), 461 ); 462 } 463 464 465 @Tags("issue", "bitfield") 466 @("35") 467 @safe unittest { 468 shouldCompile( 469 C( 470 q{ 471 struct Struct { 472 int foo; 473 int bar; 474 int :32; 475 int :31; 476 int :3; 477 int :27; 478 }; 479 } 480 ), 481 D( 482 q{ 483 Struct s; 484 static assert(s.sizeof == 20); 485 } 486 ), 487 ); 488 } 489 490 @Tags("issue") 491 @("37") 492 @safe unittest { 493 shouldCompile( 494 C( 495 ` 496 #include "mmintrin.h" 497 ` 498 ), 499 D( 500 q{ 501 } 502 ), 503 ); 504 } 505 506 507 @Tags("issue", "preprocessor") 508 @("39.0") 509 @safe unittest { 510 shouldCompile( 511 C( 512 ` 513 typedef long value; 514 typedef long intnat; 515 typedef unsigned long uintnat; 516 #define Val_long(x) ((intnat) (((uintnat)(x) << 1)) + 1) 517 #define Long_val(x) ((x) >> 1) 518 #define Val_int(x) Val_long(x) 519 #define Int_val(x) ((int) Long_val(x)) 520 #define Bp_val(v) ((char *) (v)) 521 #define String_val(x) ((const char *) Bp_val(x)) 522 value caml_callback(value, value); 523 char* strdup(const char* val); 524 ` 525 ), 526 D( 527 q{ 528 static value* fib_closure = null; 529 int n; 530 auto val = Int_val(caml_callback(*fib_closure, Val_int(n))); 531 char* str = strdup(String_val(caml_callback(*fib_closure, Val_int(n)))); 532 } 533 ), 534 ); 535 } 536 537 @Tags("issue", "preprocessor") 538 @("39.1") 539 @safe unittest { 540 shouldCompile( 541 C( 542 ` 543 #define VOID_PTR(x) ( void* )(x) 544 ` 545 ), 546 D( 547 q{ 548 auto val = VOID_PTR(42); 549 static assert(is(typeof(val) == void*)); 550 } 551 ), 552 ); 553 } 554 555 @Tags("issue", "preprocessor") 556 @("39.2") 557 @safe unittest { 558 shouldCompile( 559 C( 560 ` 561 typedef int myint; 562 #define CAST(x) ( myint* )(x) 563 ` 564 ), 565 D( 566 q{ 567 auto val = CAST(42); 568 static assert(is(typeof(val) == int*)); 569 } 570 ), 571 ); 572 } 573 574 @Tags("issue", "preprocessor") 575 @("40") 576 @safe unittest { 577 with(immutable IncludeSandbox()) { 578 writeFile("hdr1.h", 579 q{ 580 typedef int myint; 581 }); 582 writeFile("hdr2.h", 583 q{ 584 myint myfunc(void); 585 }); 586 writeFile("src.dpp", 587 ` 588 #include "hdr1.h" 589 #include "hdr2.h" 590 void func() { 591 myint _ = myfunc(); 592 } 593 `); 594 runPreprocessOnly("src.dpp"); 595 shouldCompile("src.d"); 596 } 597 } 598 599 @Tags("issue") 600 @("43") 601 @safe unittest { 602 shouldCompile( 603 C( 604 q{ 605 // The declaration `int (f)(int x, int y)` is of a function 606 // parameter that has the type of a binary function that 607 // returns int. Because C is C, this is similar to writing 608 // `int f[16]` in a parameter list but actually declaring 609 // `int*`. The result is a parameter that's a function pointer 610 // instead. To make things worse, if you put parens around the 611 // parameter name as is done here, the cursor's type according 612 // to libclang (in older versions) goes from FunctionProto to 613 // Unexposed because "reasons". 614 int binOp(int (f)(int x, int y), int a, int b); 615 int thef(int x, int y); 616 } 617 ), 618 D( 619 q{ 620 binOp(&thef, 2, 3); 621 } 622 ), 623 ); 624 } 625 626 627 @Tags("issue") 628 @("44.1") 629 @safe unittest { 630 shouldCompile( 631 C( 632 ` 633 #define macro(x) (x) + 42 634 ` 635 ), 636 D( 637 q{ 638 static assert(macro_(0) == 42); 639 static assert(macro_(1) == 43); 640 } 641 ), 642 ); 643 } 644 645 @Tags("issue") 646 @("44.2") 647 @safe unittest { 648 shouldCompile( 649 C( 650 ` 651 struct macro { int i }; 652 ` 653 ), 654 D( 655 q{ 656 } 657 ), 658 ); 659 } 660 661 662 @Tags("issue") 663 @("48") 664 @safe unittest { 665 shouldCompile( 666 C( 667 ` 668 #include <stddef.h> 669 struct Struct { 670 volatile int x; 671 volatile size_t y; 672 }; 673 ` 674 ), 675 D( 676 q{ 677 678 } 679 ), 680 ); 681 } 682 683 @Tags("issue", "preprocessor") 684 @("49") 685 @safe unittest { 686 shouldCompile( 687 C( 688 ` 689 #define func() ((void)0) 690 void (func)(void); 691 ` 692 ), 693 D( 694 q{ 695 // it gets renamed 696 func_(); 697 } 698 ), 699 ); 700 } 701 702 @Tags("issue") 703 @("53") 704 @safe unittest { 705 shouldCompile( 706 C( 707 q{ 708 typedef int bool; 709 } 710 ), 711 D( 712 q{ 713 714 } 715 ), 716 ); 717 } 718 719 @Tags("issue", "enum") 720 @("54") 721 @safe unittest { 722 shouldCompile( 723 C( 724 q{ 725 enum { 726 SUCCESS, 727 }; 728 typedef int boolean; 729 } 730 ), 731 D( 732 q{ 733 static assert(SUCCESS == 0); 734 } 735 ), 736 ); 737 } 738 739 740 @Tags("issue") 741 @("66") 742 @safe unittest { 743 shouldCompile( 744 C( 745 ` 746 #include <linux/ethtool.h> 747 ` 748 ), 749 D( 750 q{ 751 } 752 ), 753 ); 754 } 755 756 757 @Tags("issue") 758 @("76") 759 @safe unittest { 760 shouldCompile( 761 Cpp( 762 q{ 763 template <typename T> 764 struct Template { 765 T payload; 766 }; 767 } 768 ), 769 D( 770 q{ 771 static assert(__traits(getProtection, Template!int.payload) == "public", 772 __traits(getProtection, Template!int.payload)); 773 } 774 ), 775 ); 776 } 777 778 779 780 @Tags("issue") 781 @("77") 782 @safe unittest { 783 with(immutable IncludeSandbox()) { 784 writeFile("hdr.h", ""); 785 writeFile("app.dpp", 786 ` 787 module mymodule; 788 #include "hdr.h" 789 void main() { 790 static assert(__MODULE__ == "mymodule"); 791 } 792 `); 793 runPreprocessOnly("app.dpp"); 794 shouldCompile("app.d"); 795 } 796 } 797 798 @Tags("issue") 799 @("79") 800 unittest { 801 with(const IncludeSandbox()) { 802 writeHeaderAndApp("1st.h", 803 ` 804 #include "2nd.h" 805 #define BAR 33 806 `, 807 D(""), // no need for .dpp source code 808 ); 809 writeFile("2nd.h", 810 ` 811 // these empty lines are important, since they push the enum 812 // declaration down to have a higher line number than the BAR macro. 813 enum TheEnum { BAR = 42 }; 814 `); 815 run("-c", inSandboxPath("app.dpp")); 816 } 817 } 818 819 820 @Tags("issue") 821 @("90.0") 822 @safe unittest { 823 shouldCompile( 824 C( 825 ` 826 #define TEST(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) 827 ` 828 ), 829 D( 830 q{ 831 } 832 ), 833 ); 834 } 835 836 @Tags("issue") 837 @("90.1") 838 @safe unittest { 839 shouldCompile( 840 C( 841 ` 842 #define TEST(_ARR) ((int)(sizeof(_ARR)/sizeof(_ARR[0]))) 843 ` 844 ), 845 D( 846 q{ 847 int[8] ints; 848 static assert(TEST(ints) == 8); 849 } 850 ), 851 ); 852 } 853 854 @Tags("issue") 855 @("91.0") 856 @safe unittest { 857 shouldCompile( 858 Cpp( 859 q{ 860 template <typename T, typename U> class Test {}; 861 void test(Test<unsigned short, unsigned int> a); 862 } 863 ), 864 D( 865 q{ 866 test(Test!(ushort, uint)()); 867 } 868 ), 869 ); 870 } 871 872 @Tags("issue") 873 @("91.1") 874 @safe unittest { 875 shouldCompile( 876 Cpp( 877 q{ 878 template <typename T, int> class Test {}; 879 void test(Test<unsigned short, 42> a); 880 } 881 ), 882 D( 883 q{ 884 test(Test!(ushort, 42)()); 885 } 886 ), 887 ); 888 } 889 890 891 @Tags("issue") 892 @("93") 893 @safe unittest { 894 shouldCompile( 895 Cpp( 896 q{ 897 constexpr int x = sizeof(int) + (1) + sizeof(int); 898 } 899 ), 900 D( 901 q{ 902 static assert(x == 9); 903 } 904 ), 905 ); 906 } 907 908 909 @Tags("issue") 910 @("95") 911 @safe unittest { 912 shouldCompile( 913 Cpp( 914 q{ 915 constexpr int x = sizeof(int) + alignof(int) + sizeof(int); 916 } 917 ), 918 D( 919 q{ 920 static assert(x == 12); 921 } 922 ), 923 ); 924 } 925 926 927 @Tags("issue") 928 @("96") 929 @safe unittest { 930 shouldCompile( 931 Cpp( 932 q{ 933 template<unsigned long A, int B> class C{ 934 enum { value = 0 }; 935 }; 936 template<> class C<3,4> { 937 enum { value = 1 }; 938 }; 939 } 940 ), 941 D( 942 q{ 943 static assert(C!(0, 0).value == 0); 944 static assert(C!(0, 1).value == 0); 945 static assert(C!(1, 0).value == 0); 946 947 static assert(C!(3, 4).value == 1); 948 } 949 ), 950 ); 951 } 952 953 954 @Tags("issue") 955 @("97") 956 @safe unittest { 957 shouldCompile( 958 Cpp( 959 q{ 960 class T1 { 961 public: 962 int i; 963 }; 964 965 template<int I> 966 class T2 { 967 public: 968 double d; 969 }; 970 971 extern T1 a; 972 extern T2<3> b; 973 } 974 ), 975 D( 976 q{ 977 a.i = 33; 978 b.d = 33.3; 979 } 980 ), 981 ); 982 } 983 984 985 @Tags("issue") 986 @("99") 987 @safe unittest { 988 shouldCompile( 989 Cpp( 990 q{ 991 class A { 992 public: 993 constexpr static int i = 0; 994 constexpr static int j = A::i; 995 }; 996 } 997 ), 998 D( 999 q{ 1000 static assert(A.i == 0); 1001 static assert(A.j == 0); 1002 } 1003 ), 1004 ); 1005 } 1006 1007 1008 @ShouldFail("cursor.enumConstantValue returning 0 for `value = I`") 1009 @Tags("issue") 1010 @("100") 1011 @safe unittest { 1012 shouldCompile( 1013 Cpp( 1014 q{ 1015 class T1 { 1016 enum { value = 42 }; 1017 }; 1018 1019 template<int I> 1020 class T2 { 1021 enum { value = I }; 1022 }; 1023 } 1024 ), 1025 D( 1026 q{ 1027 static assert(T1.value == 42); 1028 static assert(T2!2.value == 2); 1029 static assert(T2!3.value == 3); 1030 } 1031 ), 1032 ); 1033 } 1034 1035 1036 @Tags("issue") 1037 @("101") 1038 @safe unittest { 1039 shouldCompile( 1040 Cpp( 1041 q{ 1042 // normally without the underscore 1043 int operator "" _s(const wchar_t* __str, unsigned long __len); 1044 } 1045 ), 1046 D( 1047 q{ 1048 } 1049 ), 1050 ); 1051 } 1052 1053 1054 @Tags("issue") 1055 @("103.0") 1056 @safe unittest { 1057 with(immutable IncludeSandbox()) { 1058 writeFile("hdr.h", 1059 "#define CONSTANT 42\n"); 1060 writeFile("hdr.dpp", 1061 ` 1062 #include "hdr.h" 1063 `); 1064 writeFile("app.d", 1065 q{ 1066 import hdr; 1067 static assert(DPP_ENUM_CONSTANT == 42); 1068 }); 1069 1070 runPreprocessOnly("hdr.dpp"); 1071 shouldCompile("app.d"); 1072 } 1073 } 1074 1075 1076 @Tags("issue") 1077 @("103.1") 1078 @safe unittest { 1079 with(immutable IncludeSandbox()) { 1080 writeFile("hdr.h", 1081 "#define OCTAL 00177\n"); 1082 writeFile("hdr.dpp", 1083 ` 1084 #include "hdr.h" 1085 `); 1086 writeFile("app.d", 1087 q{ 1088 import hdr; 1089 import std.conv: text; 1090 static assert(DPP_ENUM_OCTAL == 127); 1091 }); 1092 1093 runPreprocessOnly("hdr.dpp"); 1094 shouldCompile("app.d"); 1095 } 1096 } 1097 1098 1099 @ShouldFail 1100 @Tags("issue") 1101 @("104") 1102 @safe unittest { 1103 shouldCompile( 1104 Cpp( 1105 q{ 1106 template <int> struct Struct{}; 1107 template<> 1108 struct Struct<1 + 1> { 1109 static constexpr auto value = 42; 1110 }; 1111 } 1112 ), 1113 D( 1114 q{ 1115 static assert(Struct!2.value == 42); 1116 } 1117 ), 1118 ); 1119 } 1120 1121 1122 @Tags("issue") 1123 @("108") 1124 @safe unittest { 1125 shouldCompile( 1126 Cpp( 1127 q{ 1128 template<class T1, class T2, int I> 1129 class A {}; 1130 1131 template <typename CC> class C {}; 1132 1133 template<> 1134 class A<C<int>, double, 42> {}; 1135 } 1136 ), 1137 D( 1138 q{ 1139 1140 } 1141 ), 1142 ); 1143 } 1144 1145 1146 @Tags("issue") 1147 @("109") 1148 @safe unittest { 1149 shouldCompile( 1150 Cpp( 1151 q{ 1152 template<typename C> class Test 1153 { 1154 bool operator==(const Test<C>& x) const { return 0; } 1155 bool operator<(const Test<C>& x) const { return 0; } 1156 bool operator>(const Test<C>& x) const { return 0; } 1157 }; 1158 } 1159 ), 1160 D( 1161 q{ 1162 const t = Test!int(); 1163 const eq = t == t; 1164 const lt = t < t; 1165 const gt = t > t; 1166 } 1167 ), 1168 ); 1169 } 1170 1171 1172 @Tags("issue") 1173 @("110") 1174 @safe unittest { 1175 shouldCompile( 1176 Cpp( 1177 q{ 1178 class A { 1179 bool operator_a() const; 1180 }; 1181 } 1182 ), 1183 D( 1184 q{ 1185 auto a = new const A; 1186 bool ret = a.operator_a(); 1187 } 1188 ), 1189 ); 1190 } 1191 1192 1193 1194 @Tags("issue", "namespace") 1195 @("113") 1196 @safe unittest { 1197 shouldCompile( 1198 Cpp( 1199 q{ 1200 // the issue here was nested namespaces 1201 namespace ns1 { 1202 namespace ns2 { 1203 struct Struct; 1204 1205 template<typename T> 1206 struct Template { 1207 }; 1208 1209 class Class; // should be ignored but isn't 1210 class Class: public Template<Struct> { 1211 int i; 1212 }; 1213 } 1214 } 1215 } 1216 ), 1217 D( 1218 q{ 1219 } 1220 ), 1221 ); 1222 } 1223 1224 1225 @Tags("issue") 1226 @("114") 1227 @safe unittest { 1228 shouldCompile( 1229 Cpp( 1230 q{ 1231 template<class T> 1232 struct Foo { 1233 template<class U> 1234 Foo& operator=(U& other) { 1235 return *this; 1236 } 1237 }; 1238 } 1239 ), 1240 D( 1241 q{ 1242 Foo!int foo; 1243 int i; 1244 foo = i; 1245 double d; 1246 foo = d; 1247 } 1248 ), 1249 ); 1250 } 1251 1252 1253 @Tags("issue") 1254 @("115") 1255 @safe unittest { 1256 shouldCompile( 1257 Cpp( 1258 q{ 1259 template<class T> 1260 class Foo { 1261 T value; 1262 public: 1263 Foo(T value); 1264 }; 1265 1266 template<class T> 1267 Foo<T>::Foo(T val) { 1268 value = val; 1269 } 1270 } 1271 ), 1272 D( 1273 q{ 1274 auto fooI = Foo!int(42); 1275 auto fooD = Foo!double(33.3); 1276 } 1277 ), 1278 ); 1279 } 1280 1281 1282 @Tags("issue") 1283 @("116") 1284 @safe unittest { 1285 shouldCompile( 1286 Cpp( 1287 q{ 1288 struct Foo; 1289 struct Foo { int i; }; 1290 } 1291 ), 1292 D( 1293 q{ 1294 static assert(is(typeof(Foo.i) == int)); 1295 } 1296 ), 1297 ); 1298 } 1299 1300 1301 @Tags("issue") 1302 @("119.0") 1303 @safe unittest { 1304 shouldCompile( 1305 Cpp( 1306 q{ 1307 struct Struct { 1308 enum Enum { foo, bar, baz }; 1309 }; 1310 1311 void fun(Struct::Enum); 1312 } 1313 ), 1314 D( 1315 q{ 1316 } 1317 ), 1318 ); 1319 } 1320 1321 1322 @Tags("issue") 1323 @("119.1") 1324 @safe unittest { 1325 shouldCompile( 1326 Cpp( 1327 q{ 1328 struct Struct { 1329 enum class Enum { foo, bar, baz }; 1330 }; 1331 } 1332 ), 1333 D( 1334 q{ 1335 auto f = Struct.Enum.foo; 1336 static assert(!__traits(compiles, Struct.foo)); 1337 } 1338 ), 1339 ); 1340 } 1341 1342 1343 @ShouldFail("libclang fails to tokenise this for some reason") 1344 @Tags("issue", "libclang") 1345 @("119.2") 1346 @safe unittest { 1347 with(immutable IncludeSandbox()) { 1348 1349 writeFile("util.hpp", 1350 ` 1351 #define MAKE_ENUM_CLASS(type, values) enum class type { values }; 1352 `); 1353 1354 writeFile("hdr.hpp", 1355 ` 1356 #include "util.hpp" 1357 #define VALUES X(foo) X(bar) X(baz) 1358 #define X(n) n, 1359 MAKE_ENUM_CLASS(Enum, VALUES) 1360 #undef X 1361 `); 1362 1363 writeFile("app.dpp", 1364 ` 1365 #include "hdr.hpp" 1366 void main() { 1367 auto f = Enum.foo; 1368 static assert(!__traits(compiles, foo)); 1369 } 1370 `); 1371 1372 runPreprocessOnly(["app.dpp"]); 1373 shouldCompile("app.d"); 1374 } 1375 } 1376 1377 1378 @Tags("issue") 1379 @("134") 1380 @safe unittest { 1381 shouldCompile( 1382 Cpp( 1383 q{ 1384 struct Foo { 1385 double fun(int i) const; 1386 }; 1387 1388 double Foo::fun(int i) const { 1389 return i * 2; 1390 } 1391 } 1392 ), 1393 D( 1394 q{ 1395 auto foo = Foo(); 1396 double d = foo.fun(42); 1397 } 1398 ), 1399 ); 1400 } 1401 1402 1403 @Tags("namespace", "issue") 1404 @("149") 1405 @safe unittest { 1406 shouldCompile( 1407 Cpp( 1408 q{ 1409 namespace ns { 1410 struct Struct; 1411 1412 template<typename T> 1413 struct Template { }; 1414 1415 // The `Struct` template parameter must be translated properly 1416 // and was showing up as ns.Struct 1417 class Class: public Template<Struct> { 1418 int i; 1419 }; 1420 } 1421 } 1422 ), 1423 D( 1424 q{ 1425 } 1426 ), 1427 ); 1428 } 1429 1430 1431 @Tags("issue") 1432 @("150") 1433 @safe unittest { 1434 shouldCompile( 1435 Cpp( 1436 q{ 1437 struct Foo { 1438 int a, b, c; 1439 }; 1440 1441 struct Bar { 1442 Foo& foo; 1443 }; 1444 } 1445 ), 1446 D( 1447 q{ 1448 import std.conv: text; 1449 static assert(Foo.sizeof == 12, Foo.sizeof.text); 1450 static assert(Foo.alignof == 4, Foo.alignof.text); 1451 static assert(Bar.sizeof == 8, Bar.sizeof.text); 1452 static assert(Bar.alignof == 8, Bar.alignof.text); 1453 } 1454 ), 1455 ); 1456 } 1457 1458 1459 @Tags("issue") 1460 @("151") 1461 @safe unittest { 1462 shouldRun( 1463 Cpp( 1464 q{ 1465 struct Foo { 1466 long data; 1467 }; 1468 1469 struct Bar { 1470 static long numDtors; 1471 long data; 1472 ~Bar(); 1473 }; 1474 1475 Foo makeFoo(); 1476 Bar makeBar(); 1477 } 1478 ), 1479 Cpp( 1480 q{ 1481 Foo makeFoo() { return {}; } 1482 Bar makeBar() { return {}; } 1483 Bar::~Bar() { ++numDtors; } 1484 long Bar::numDtors; 1485 } 1486 ), 1487 D( 1488 q{ 1489 import std.conv: text; 1490 1491 auto foo = makeFoo; 1492 assert(foo.data == 0, foo.data.text); 1493 1494 { 1495 auto bar = makeBar; 1496 assert(bar.data == 0, bar.data.text); 1497 bar.data = 42; 1498 assert(bar.numDtors == 0, bar.numDtors.text); 1499 } 1500 1501 assert(Bar.numDtors == 1, Bar.numDtors.text); 1502 } 1503 ), 1504 ); 1505 } 1506 1507 1508 @("missing.template.parameter") 1509 @safe unittest { 1510 shouldCompile( 1511 Cpp( 1512 q{ 1513 namespace myns { 1514 template<typename T> 1515 struct vector { 1516 T* elements; 1517 long size; 1518 }; 1519 } 1520 1521 struct Problem { 1522 // In the issue this gets emitted as `vector values` 1523 // instead of `vector!double values` 1524 myns::vector<double> values; 1525 }; 1526 1527 Problem createProblem(); 1528 } 1529 ), 1530 D( 1531 q{ 1532 } 1533 ), 1534 ); 1535 }