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 }