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                 int binOp(int (f)(int x, int y), int a, int b);
606                 int thef(int x, int y);
607             }
608         ),
609         D(
610             q{
611                 binOp(&thef, 2, 3);
612             }
613         ),
614     );
615 }
616 
617 
618 @Tags("issue")
619 @("44.1")
620 @safe unittest {
621     shouldCompile(
622         C(
623             `
624                 #define macro(x) (x) + 42
625             `
626         ),
627         D(
628             q{
629                 static assert(macro_(0) == 42);
630                 static assert(macro_(1) == 43);
631             }
632         ),
633     );
634 }
635 
636 @Tags("issue")
637 @("44.2")
638 @safe unittest {
639     shouldCompile(
640         C(
641             `
642                 struct macro { int i };
643             `
644         ),
645         D(
646             q{
647             }
648         ),
649     );
650 }
651 
652 
653 @Tags("issue")
654 @("48")
655 @safe unittest {
656     shouldCompile(
657         C(
658             `
659                 #include <stddef.h>
660                 struct Struct {
661                     volatile int x;
662                     volatile size_t y;
663                 };
664             `
665         ),
666         D(
667             q{
668 
669             }
670         ),
671     );
672 }
673 
674 @Tags("issue", "preprocessor")
675 @("49")
676 @safe unittest {
677     shouldCompile(
678         C(
679             `
680                 #define func() ((void)0)
681                 void (func)(void);
682             `
683         ),
684         D(
685             q{
686                 // it gets renamed
687                 func_();
688             }
689         ),
690     );
691 }
692 
693 @Tags("issue")
694 @("53")
695 @safe unittest {
696     shouldCompile(
697         C(
698             q{
699                 typedef int bool;
700             }
701         ),
702         D(
703             q{
704 
705             }
706         ),
707     );
708 }
709 
710 @Tags("issue", "enum")
711 @("54")
712 @safe unittest {
713     shouldCompile(
714         C(
715             q{
716                 enum {
717                     SUCCESS,
718                 };
719                 typedef int boolean;
720             }
721         ),
722         D(
723             q{
724                 static assert(SUCCESS == 0);
725             }
726         ),
727     );
728 }
729 
730 
731 @Tags("issue")
732 @("66")
733 @safe unittest {
734     shouldCompile(
735         C(
736             `
737                 #include <linux/ethtool.h>
738             `
739         ),
740         D(
741             q{
742             }
743         ),
744     );
745 }
746 
747 @Tags("issue")
748 @("77")
749 @safe unittest {
750     with(immutable IncludeSandbox()) {
751         writeFile("hdr.h", "");
752         writeFile("app.dpp",
753                   `
754                       module mymodule;
755                       #include "hdr.h"
756                       void main() {
757                           static assert(__MODULE__ == "mymodule");
758                       }
759                   `);
760         runPreprocessOnly("app.dpp");
761         shouldCompile("app.d");
762     }
763 }
764 
765 @Tags("issue")
766 @("79")
767 unittest {
768     with(const IncludeSandbox()) {
769         writeHeaderAndApp("1st.h",
770                           `
771                               #include "2nd.h"
772                               #define BAR 33
773                           `,
774                           D(""), // no need for .dpp source code
775         );
776         writeFile("2nd.h",
777                   `
778                       // these empty lines are important, since they push the enum
779                       // declaration down to have a higher line number than the BAR macro.
780                       enum TheEnum { BAR = 42 };
781                   `);
782         run("-c", inSandboxPath("app.dpp"));
783     }
784 }
785 
786 
787 @Tags("issue")
788 @("90.0")
789 @safe unittest {
790     shouldCompile(
791         C(
792             `
793                 #define TEST(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR)))
794             `
795         ),
796         D(
797             q{
798             }
799         ),
800     );
801 }
802 
803 @Tags("issue")
804 @("90.1")
805 @safe unittest {
806     shouldCompile(
807         C(
808             `
809                 #define TEST(_ARR) ((int)(sizeof(_ARR)/sizeof(_ARR[0])))
810             `
811         ),
812         D(
813             q{
814                 int[8] ints;
815                 static assert(TEST(ints) == 8);
816             }
817         ),
818     );
819 }
820 
821 @Tags("issue")
822 @("91.0")
823 @safe unittest {
824     shouldCompile(
825         Cpp(
826             q{
827                 template <typename T, typename U> class Test {};
828                 void test(Test<unsigned short, unsigned int> a);
829             }
830         ),
831         D(
832             q{
833                 test(Test!(ushort, uint)());
834             }
835         ),
836     );
837 }
838 
839 @Tags("issue")
840 @("91.1")
841 @safe unittest {
842     shouldCompile(
843         Cpp(
844             q{
845                 template <typename T, int> class Test {};
846                 void test(Test<unsigned short, 42> a);
847             }
848         ),
849         D(
850             q{
851                 test(Test!(ushort, 42)());
852             }
853         ),
854     );
855 }
856 
857 
858 @Tags("issue")
859 @("93")
860 @safe unittest {
861     shouldCompile(
862         Cpp(
863             q{
864                 constexpr int x = sizeof(int) + (1) + sizeof(int);
865             }
866         ),
867         D(
868             q{
869                 static assert(x == 9);
870             }
871         ),
872     );
873 }
874 
875 
876 @Tags("issue")
877 @("95")
878 @safe unittest {
879     shouldCompile(
880         Cpp(
881             q{
882                 constexpr int x = sizeof(int) + alignof(int) + sizeof(int);
883             }
884         ),
885         D(
886             q{
887                 static assert(x == 12);
888             }
889         ),
890     );
891 }
892 
893 
894 @Tags("issue")
895 @("96")
896 @safe unittest {
897     shouldCompile(
898         Cpp(
899             q{
900                 template<unsigned long A, int B> class C{
901                     enum { value = 0 };
902                 };
903                 template<> class C<3,4> {
904                     enum { value = 1 };
905                 };
906             }
907         ),
908         D(
909             q{
910                 static assert(C!(0, 0).value == 0);
911                 static assert(C!(0, 1).value == 0);
912                 static assert(C!(1, 0).value == 0);
913 
914                 static assert(C!(3, 4).value == 1);
915             }
916         ),
917     );
918 }
919 
920 
921 @Tags("issue")
922 @("97")
923 @safe unittest {
924     shouldCompile(
925         Cpp(
926             q{
927                 class T1 {
928                     int i;
929                 };
930 
931                 template<int I>
932                 class T2 {
933                     double d;
934                 };
935 
936                 extern T1 a;
937                 extern T2<3> b;
938             }
939         ),
940         D(
941             q{
942                 a.i = 33;
943                 b.d = 33.3;
944             }
945         ),
946     );
947 }
948 
949 
950 @Tags("issue")
951 @("99")
952 @safe unittest {
953     shouldCompile(
954         Cpp(
955             q{
956                 class A {
957                     constexpr static int i = 0;
958                     constexpr static int j = A::i;
959                 };
960             }
961         ),
962         D(
963             q{
964                 static assert(A.i == 0);
965                 static assert(A.j == 0);
966             }
967         ),
968     );
969 }
970 
971 
972 @ShouldFail("cursor.enumConstantValue returning 0 for `value = I`")
973 @Tags("issue")
974 @("100")
975 @safe unittest {
976     shouldCompile(
977         Cpp(
978             q{
979                 class T1 {
980                     enum { value = 42 };
981                 };
982 
983                 template<int I>
984                 class T2 {
985                     enum { value = I };
986                 };
987             }
988         ),
989         D(
990             q{
991                 static assert(T1.value == 42);
992                 static assert(T2!2.value == 2);
993                 static assert(T2!3.value == 3);
994             }
995         ),
996     );
997 }
998 
999 
1000 @Tags("issue")
1001 @("101")
1002 @safe unittest {
1003     shouldCompile(
1004         Cpp(
1005             q{
1006                 // normally without the underscore
1007                 int operator "" _s(const wchar_t* __str, unsigned long __len);
1008             }
1009         ),
1010         D(
1011             q{
1012             }
1013         ),
1014     );
1015 }
1016 
1017 
1018 @ShouldFail
1019 @Tags("issue")
1020 @("104")
1021 @safe unittest {
1022     shouldCompile(
1023         Cpp(
1024             q{
1025                 template <int> struct Struct{};
1026                 template<>
1027                 struct Struct<1 + 1> {
1028                     static constexpr auto value = 42;
1029                 };
1030             }
1031         ),
1032         D(
1033             q{
1034                 static assert(Struct!2.value == 42);
1035             }
1036         ),
1037    );
1038 }