1 // PERMUTE_ARGS: -unittest -O -release -inline -g
2
3 import core.vararg;
4
5 extern (C) int printf(const(char*) fmt, ...);
6
TypeTuple(T...)7 template TypeTuple(T...) { alias TypeTuple = T; }
8
9 /**********************************/
10
11 int sdtor;
12
13 struct S1
14 {
~thisS115 ~this() { printf("~S()\n"); sdtor++; }
16 }
17
test1()18 void test1()
19 {
20 S1* s = new S1();
21 delete s;
22 assert(sdtor == 1);
23 }
24
25 /**********************************/
26
27 int sdtor2;
28
29 struct S2
30 {
~thisS231 ~this() { printf("~S2()\n"); sdtor2++; }
deleteS232 delete(void* p) { assert(sdtor2 == 1); printf("S2.delete()\n"); sdtor2++; }
33 }
34
test2()35 void test2()
36 {
37 S2* s = new S2();
38 delete s;
39 assert(sdtor2 == 2);
40 }
41
42 /**********************************/
43
44 int sdtor3;
45
46 struct S3
47 { int a;
~thisS348 ~this() { printf("~S3()\n"); sdtor3++; assert(a == 3); }
49 }
50
51 struct T3
52 {
53 int i;
54 S3 s;
55 }
56
test3()57 void test3()
58 {
59 T3* s = new T3();
60 s.s.a = 3;
61 delete s;
62 assert(sdtor3 == 1);
63 }
64
65 /**********************************/
66
67 int sdtor4;
68
69 struct S4
70 { int a = 3;
~thisS471 ~this()
72 { printf("~S4()\n");
73 if (a == 4)
74 assert(sdtor4 == 2);
75 else
76 { assert(a == 3);
77 assert(sdtor4 == 1);
78 }
79 sdtor4++;
80 }
81 }
82
83 struct T4
84 {
85 int i;
86 S4 s;
~this()87 ~this() { printf("~T4()\n"); assert(sdtor4 == 0); sdtor4++; }
88 S4 t;
89 }
90
test4()91 void test4()
92 {
93 T4* s = new T4();
94 s.s.a = 4;
95 delete s;
96 assert(sdtor4 == 3);
97 }
98
99 /**********************************/
100
101 int sdtor5;
102
M5()103 template M5()
104 { ~this()
105 {
106 printf("~M5()\n"); assert(sdtor5 == 1); sdtor5++;
107 }
108 }
109
110 struct T5
111 {
112 mixin M5 m;
~thisT5113 ~this() { printf("~T5()\n"); assert(sdtor5 == 0); sdtor5++; }
114 }
115
test5()116 void test5()
117 {
118 T5* s = new T5();
119 delete s;
120 assert(sdtor5 == 2);
121 }
122
123 /**********************************/
124
125 int sdtor6;
126
127 struct S6
128 { int b = 7;
~thisS6129 ~this()
130 {
131 printf("~S6()\n"); assert(b == 7); assert(sdtor6 == 1); sdtor6++;
132 }
133 }
134
135 class T6
136 {
137 int a = 3;
138 S6 s;
~this()139 ~this() { printf("~T6()\n"); assert(a == 3); assert(sdtor6 == 0); sdtor6++; }
140 }
141
test6()142 void test6()
143 {
144 T6 s = new T6();
145 delete s;
146 assert(sdtor6 == 2);
147 }
148
149 /**********************************/
150
151 int sdtor7;
152
153 struct S7
154 { int b = 7;
~thisS7155 ~this()
156 {
157 printf("~S7()\n");
158 assert(b == 7);
159 assert(sdtor7 >= 1 && sdtor7 <= 3);
160 sdtor7++;
161 }
162 }
163
164 struct T7
165 {
166 int a = 3;
167 S7[3] s;
~this()168 ~this()
169 { printf("~T7() %d\n", sdtor7);
170 assert(a == 3);
171 assert(sdtor7 == 0);
172 sdtor7++;
173 }
174 }
175
test7()176 void test7()
177 {
178 T7* s = new T7();
179 delete s;
180 assert(sdtor7 == 4);
181 }
182
183 /**********************************/
184
185 int sdtor8;
186
187 struct S8
188 { int b = 7;
189 int c;
~thisS8190 ~this()
191 {
192 printf("~S8() %d\n", sdtor8);
193 assert(b == 7);
194 assert(sdtor8 == c);
195 sdtor8++;
196 }
197 }
198
test8()199 void test8()
200 {
201 S8[] s = new S8[3];
202 s[0].c = 2;
203 s[1].c = 1;
204 s[2].c = 0;
205 delete s;
206 assert(sdtor8 == 3);
207 }
208
209 /**********************************/
210
211 int sdtor9;
212
213 struct S9
214 { int b = 7;
~thisS9215 ~this()
216 {
217 printf("~S9() %d\n", sdtor9);
218 assert(b == 7);
219 sdtor9++;
220 }
221 }
222
test9()223 void test9()
224 {
225 {
226 S9 s;
227 }
228 assert(sdtor9 == 1);
229 }
230
231 /**********************************/
232
233 int sdtor10;
234
235 struct S10
236 { int b = 7;
237 int c;
~thisS10238 ~this()
239 {
240 printf("~S10() %d\n", sdtor10);
241 assert(b == 7);
242 assert(sdtor10 == c);
243 sdtor10++;
244 }
245 }
246
test10()247 void test10()
248 {
249 {
250 S10[3] s;
251 s[0].c = 2;
252 s[1].c = 1;
253 s[2].c = 0;
254 }
255 assert(sdtor10 == 3);
256 }
257
258 /**********************************/
259
260 int sdtor11;
261
M11()262 template M11()
263 { ~this()
264 {
265 printf("~M11()\n"); assert(sdtor11 == 1); sdtor11++;
266 }
267 }
268
269 class T11
270 {
271 mixin M11 m;
~this()272 ~this() { printf("~T11()\n"); assert(sdtor11 == 0); sdtor11++; }
273 }
274
test11()275 void test11()
276 {
277 T11 s = new T11();
278 delete s;
279 assert(sdtor11 == 2);
280 }
281
282 /**********************************/
283
284 int sdtor12;
285
286 struct S12
287 { int a = 3;
~thisS12288 ~this() { printf("~S12() %d\n", sdtor12); sdtor12++; }
289 }
290
foo12(S12 s)291 void foo12(S12 s)
292 {
293 }
294
test12()295 void test12()
296 {
297 {
298 S12 s;
299 foo12(s);
300 s.a = 4;
301 }
302 assert(sdtor12 == 2);
303 }
304
305 /**********************************/
306
307 struct S13
308 { int a = 3;
opAssignS13309 int opAssign(S13 s)
310 {
311 printf("S13.opAssign(%p)\n", &this);
312 a = 4;
313 return s.a + 2;
314 }
315 }
316
test13()317 void test13()
318 {
319 S13 s;
320 S13 t;
321 assert((s = t) == 5);
322 assert(s.a == 4);
323 }
324
325 /**********************************/
326
327 struct S14
328 { int a = 3;
opAssignS14329 int opAssign(ref S14 s)
330 {
331 printf("S14.opAssign(%p)\n", &this);
332 a = 4;
333 return s.a + 2;
334 }
335 }
336
test14()337 void test14()
338 {
339 S14 s;
340 S14 t;
341 assert((s = t) == 5);
342 assert(s.a == 4);
343 }
344
345 /**********************************/
346
347 struct S15
348 { int a = 3;
opAssignS15349 int opAssign(ref const S15 s)
350 {
351 printf("S15.opAssign(%p)\n", &this);
352 a = 4;
353 return s.a + 2;
354 }
355 }
356
test15()357 void test15()
358 {
359 S15 s;
360 S15 t;
361 assert((s = t) == 5);
362 assert(s.a == 4);
363 }
364
365 /**********************************/
366
367 struct S16
368 { int a = 3;
opAssignS16369 int opAssign(S16 s, ...)
370 {
371 printf("S16.opAssign(%p)\n", &this);
372 a = 4;
373 return s.a + 2;
374 }
375 }
376
test16()377 void test16()
378 {
379 S16 s;
380 S16 t;
381 assert((s = t) == 5);
382 assert(s.a == 4);
383 }
384
385 /**********************************/
386
387 struct S17
388 { int a = 3;
opAssignS17389 int opAssign(...)
390 {
391 printf("S17.opAssign(%p)\n", &this);
392 a = 4;
393 return 5;
394 }
395 }
396
test17()397 void test17()
398 {
399 S17 s;
400 S17 t;
401 assert((s = t) == 5);
402 assert(s.a == 4);
403 }
404
405 /**********************************/
406
407 struct S18
408 { int a = 3;
409 int opAssign(S18 s, int x = 7)
410 {
411 printf("S18.opAssign(%p)\n", &this);
412 a = 4;
413 assert(x == 7);
414 return s.a + 2;
415 }
416 }
417
test18()418 void test18()
419 {
420 S18 s;
421 S18 t;
422 assert((s = t) == 5);
423 assert(s.a == 4);
424 }
425
426 /**********************************/
427
428 struct S19
429 {
430 int a,b,c,d;
thisS19431 this(this) { printf("this(this) %p\n", &this); }
~thisS19432 ~this() { printf("~this() %p\n", &this); }
433 }
434
foo19()435 S19 foo19()
436 {
437 S19 s;
438 void bar() { s.a++; }
439 bar();
440 return s;
441 }
442
test19()443 void test19()
444 {
445 S19 t = foo19();
446 printf("-main()\n");
447 }
448
449 /**********************************/
450
451 struct S20
452 {
453 static char[] r;
454 int a,b,c=2,d;
thisS20455 this(this) { printf("this(this) %p\n", &this); r ~= '='; }
~thisS20456 ~this() { printf("~this() %p\n", &this); r ~= '~'; }
457 }
458
foo20()459 void foo20()
460 {
461 S20 s;
462 S20[3] a;
463 assert(S20.r == "");
464 a = s;
465 assert(S20.r == "=~=~=~");
466 }
467
test20()468 void test20()
469 {
470 foo20();
471 assert(S20.r == "=~=~=~~~~~");
472 printf("-main()\n");
473 }
474
475 /**********************************/
476
477 struct S21
478 {
479 static char[] r;
480 int a,b,c=2,d;
thisS21481 this(this) { printf("this(this) %p\n", &this); r ~= '='; }
~thisS21482 ~this() { printf("~this() %p\n", &this); r ~= '~'; }
483 }
484
foo21()485 void foo21()
486 {
487 S21 s;
488 S21[3] a = s;
489 assert(S21.r == "===");
490 S21.r = null;
491 S21[3][2] b = s;
492 assert(S21.r == "======");
493 S21.r = null;
494 }
495
test21()496 void test21()
497 {
498 foo21();
499 assert(S21.r == "~~~~~~~~~~");
500 printf("-main()\n");
501 }
502
503 /**********************************/
504
505 struct S22
506 {
507 static char[] r;
508 int a,b,c=2,d;
thisS22509 this(this) { printf("this(this) %p\n", &this); r ~= '='; }
~thisS22510 ~this() { printf("~this() %p\n", &this); r ~= '~'; }
511 }
512
foo22()513 void foo22()
514 {
515 S22[3] s;
516 S22[3][2] a;
517 assert(S22.r == "");
518 a = s;
519 assert(S22.r == "===~~~===~~~");
520 S22.r = null;
521 }
522
test22()523 void test22()
524 {
525 foo22();
526 assert(S22.r == "~~~~~~~~~");
527 printf("-main()\n");
528 }
529
530
531 /************************************************/
532
533 struct S23
534 {
535 int m = 4, n, o, p, q;
536
thisS23537 this(int x)
538 {
539 printf("S23(%d)\n", x);
540 assert(x == 3);
541 assert(m == 4 && n == 0 && o == 0 && p == 0 && q == 0);
542 q = 7;
543 }
544 }
545
test23()546 void test23()
547 {
548 {
549 auto s = S23(3);
550 printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q);
551 assert(s.m == 4 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);
552 }
553 {
554 auto s = new S23(3);
555 printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q);
556 assert(s.m == 4 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);
557 }
558 {
559 S23 s;
560 s = S23(3);
561 printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q);
562 assert(s.m == 4 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);
563 }
564 }
565
566 /************************************************/
567
568 struct S24
569 {
570 int m, n, o, p, q;
571
thisS24572 this(int x)
573 {
574 printf("S24(%d)\n", x);
575 assert(x == 3);
576 assert(m == 0 && n == 0 && o == 0 && p == 0 && q == 0);
577 q = 7;
578 }
579 }
580
test24()581 void test24()
582 {
583 {
584 auto s = S24(3);
585 printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q);
586 assert(s.m == 0 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);
587 }
588 {
589 auto s = new S24(3);
590 printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q);
591 assert(s.m == 0 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);
592 }
593 {
594 S24 s;
595 s = S24(3);
596 printf("s.m = %d, s.n = %d, s.q = %d\n", s.m, s.n, s.q);
597 assert(s.m == 0 && s.n == 0 && s.o == 0 && s.p == 0 && s.q == 7);
598 }
599 }
600
601 /**********************************/
602
603 struct S25
604 {
thisS25605 this(int s) {}
606 }
607
test25()608 void test25()
609 {
610 auto a = S25();
611 }
612
613 /**********************************/
614
615 int z26;
616
617 struct A26
618 {
619 int id;
thisA26620 this(int x) { id = x; printf("Created A from scratch: %d\n", x); z26++; }
thisA26621 this(this) { printf("Copying A: %d\n", id); z26 += 10; }
~thisA26622 ~this() { printf("Destroying A: %d\n", id); z26 += 100; }
623 }
624
625 struct B26
626 {
627 A26 member;
this(this)628 this(this) { printf("Copying B: %d\n", member.id); assert(0); }
629 }
630
foo26()631 B26 foo26()
632 {
633 A26 a = A26(45);
634 printf("1\n");
635 assert(z26 == 1);
636 return B26(a);
637 }
638
test26()639 void test26()
640 {
641 {
642 auto b = foo26();
643 assert(z26 == 111);
644 printf("2\n");
645 }
646 assert(z26 == 211);
647 }
648
649 /**********************************/
650
651 int z27;
652
653 struct A27
654 {
655 int id;
thisA27656 this(int x) { id = x; printf("Ctor A27: %d\n", x); z27++; }
thisA27657 this(this) { printf("Copying A27: %d\n", id); z27 += 10; }
~thisA27658 ~this() { printf("Destroying A27: %d\n", id); z27 += 100; }
659 }
660
661 struct B27
662 {
663 A27[2][3] member;
664 }
665
test27()666 void test27()
667 {
668 {
669 A27[2][3] a;
670 assert(z27 == 0);
671 B27 b = B27(a);
672 assert(z27 == 60);
673 }
674 assert(z27 == 1260);
675 }
676
677
678 /**********************************/
679
680 string s28;
681
682 struct A28
683 {
thisA28684 this(this)
685 {
686 printf("A's copy\n");
687 s28 ~= "A";
688 }
689 }
690
691 struct B28
692 {
693 A28 member;
this(this)694 this(this)
695 {
696 printf("B's copy\n");
697 s28 ~= "B";
698 }
699 }
700
test28()701 void test28()
702 {
703 B28 b1;
704 B28 b2 = b1;
705 assert(s28 == "AB");
706 }
707
708
709 /**********************************/
710
711 string s29;
712
Templ29()713 template Templ29 ()
714 {
715 this(int i) { this(0.0); s29 ~= "i"; }
716 this(double d) { s29 ~= "d"; }
717 }
718
719 class C29 { mixin Templ29; }
720 struct S29 { mixin Templ29; }
721
test29()722 void test29()
723 {
724 auto r = S29(1);
725 assert(s29 == "di");
726
727 r = S29(2.0);
728 assert(s29 == "did");
729
730 auto c = new C29(2);
731 assert(s29 == "diddi");
732
733 auto c2 = new C29(2.0);
734 assert(s29 == "diddid");
735 }
736
737 /**********************************/
738
739 struct S30
740 {
741 int x;
thisS30742 this(T)(T args) { x = args + 1; }
743 }
744
test30()745 void test30()
746 {
747 auto s = S30(3);
748 assert(s.x == 4);
749 }
750
751 /**********************************/
752
753 struct S31
754 {
755 int x;
thisS31756 this(T...)(T args) { x = args[0] + 1; }
757 }
758
test31()759 void test31()
760 {
761 auto s = S31(3);
762 assert(s.x == 4);
763 }
764
765 /**********************************/
766
767 struct S32
768 {
769 static int x;
770
thisS32771 this(int i)
772 {
773 printf("ctor %p(%d)\n", &this, i);
774 x += 1;
775 }
776
thisS32777 this(this)
778 {
779 printf("postblit %p\n", &this);
780 x += 0x10;
781 }
782
~thisS32783 ~this()
784 {
785 printf("dtor %p\n", &this);
786 x += 0x100;
787 }
788 }
789
foo32()790 S32 foo32()
791 {
792 printf("test1\n");
793 return S32(1);
794 }
795
bar32()796 S32 bar32()
797 {
798 printf("test1\n");
799 S32 f = S32(1);
800 printf("test2\n");
801 return f;
802 }
803
test32()804 void test32()
805 {
806 {
807 S32 s = foo32();
808 }
809 assert(S32.x == 0x101);
810
811 S32.x = 0;
812 {
813 S32 s = bar32();
814 }
815 assert(S32.x == 0x101);
816 }
817
818 /**********************************/
819
820 struct S33
821 {
822 static int x;
823
thisS33824 this(int i)
825 {
826 printf("ctor %p(%d)\n", &this, i);
827 x += 1;
828 }
829
thisS33830 this(this)
831 {
832 printf("postblit %p\n", &this);
833 x += 0x10;
834 }
835
~thisS33836 ~this()
837 {
838 printf("dtor %p\n", &this);
839 x += 0x100;
840 }
841 }
842
843 struct T33
844 {
foo()845 S33 foo()
846 {
847 return t;
848 }
849
850 S33 t;
851 }
852
test33()853 void test33()
854 {
855 {
856 T33 t;
857 S33 s = t.foo();
858 }
859 printf("S.x = %x\n", S33.x);
860 assert(S33.x == 0x210);
861 }
862
863 /**********************************/
864
865 struct X34 {
866 int i;
thisX34867 this(this) {
868 printf("postblit %p\n", &this);
869 ++i;
870 }
871
~thisX34872 ~this() {
873 printf("dtor %p\n", &this);
874 }
875 }
876
test34()877 void test34()
878 {
879 X34[2] xs;
880 // xs[0][0] = X34();
881 printf("foreach\n");
882 for (int j = 0; j < xs.length; j++) { auto x = (j++,j--,xs[j]);
883 //foreach(x; xs) {
884 //printf("foreach x.i = %d\n", x[0].i);
885 //assert(x[0].i == 1);
886 printf("foreach x.i = %d\n", x.i);
887 assert(x.i == 1);
888 }
889 printf("loop done\n");
890 }
891
892 /**********************************/
893
894 struct X35 {
895 __gshared int k;
896 int i;
thisX35897 this(this) {
898 printf("postblit %p\n", &this);
899 ++i;
900 }
901
~thisX35902 ~this() {
903 printf("dtor %p\n", &this);
904 k++;
905 }
906 }
907
test35()908 void test35()
909 {
910 {
911 X35[2] xs;
912 printf("foreach\n");
913 foreach(ref x; xs) {
914 printf("foreach x.i = %d\n", x.i);
915 assert(x.i == 0);
916 }
917 printf("loop done\n");
918 }
919 assert(X35.k == 2);
920 }
921
922 /**********************************/
923
924 struct X36 {
925 __gshared int k;
926 int i;
thisX36927 this(this) {
928 printf("postblit %p\n", &this);
929 ++i;
930 }
931
~thisX36932 ~this() {
933 printf("dtor %p\n", &this);
934 k++;
935 }
936 }
937
test36()938 void test36()
939 {
940 {
941 X36[2] xs;
942 printf("foreach\n");
943 foreach(x; xs) {
944 printf("foreach x.i = %d\n", x.i);
945 assert(x.i == 1);
946 }
947 printf("loop done\n");
948 }
949 assert(X36.k == 4);
950 }
951
952 /**********************************/
953
954 struct X37 {
955 __gshared int k;
956 int i;
thisX37957 this(this) {
958 printf("postblit %p\n", &this);
959 ++i;
960 }
961
~thisX37962 ~this() {
963 printf("dtor %p\n", &this);
964 k++;
965 }
966 }
967
test37()968 void test37() {
969 {
970 X37[2][3] xs;
971 printf("foreach\n");
972 foreach(ref x; xs) {
973 printf("foreach x.i = %d\n", x[0].i);
974 assert(x[0].i == 0);
975 }
976 printf("loop done\n");
977 }
978 assert(X37.k == 6);
979 }
980
981 /**********************************/
982
983 struct S38 {
984 __gshared int count;
985 __gshared int postblit;
986
thisS38987 this(int x) {
988 printf("this(%d)\n", x);
989 assert(this.x == 0);
990 this.x = x;
991 count++;
992 }
thisS38993 this(this) {
994 printf("this(this) with %d\n", x);
995 assert(x == 1 || x == 2);
996 count++;
997 postblit++;
998 }
~thisS38999 ~this() {
1000 printf("~this(%d)\n", x);
1001 assert(x == 1 || x == 2);
1002 x = 0;
1003 count--;
1004 }
1005 int x;
1006 }
1007
foo38()1008 S38 foo38() {
1009 auto s = S38(1);
1010 return s;
1011 }
1012
bar38()1013 S38 bar38() {
1014 return S38(2);
1015 }
1016
test38()1017 void test38()
1018 {
1019 {
1020 auto s1 = foo38();
1021 assert(S38.count == 1);
1022 assert(S38.postblit == 0);
1023 }
1024 assert(S38.count == 0);
1025 S38.postblit = 0;
1026
1027 {
1028 auto s2 = bar38();
1029 assert(S38.count == 1);
1030 assert(S38.postblit == 0);
1031 }
1032 assert(S38.count == 0);
1033 }
1034
1035
1036 /**********************************/
1037
1038 struct Foo39
1039 {
1040 int x;
thisFoo391041 this(int v){ x = v + 1; }
opAssignFoo391042 void opAssign(int v){
1043 x = v + 3;
1044 }
1045 }
1046
test39()1047 void test39()
1048 {
1049 int y = 5;
1050 Foo39 f = y;
1051 assert(f.x == 6);
1052 f = y;
1053 assert(f.x == 8);
1054 // f = Foo39(y);
1055
1056 }
1057
1058 /**********************************/
1059
approxEqual(float a,float b)1060 bool approxEqual(float a, float b)
1061 {
1062 return a < b ? b-a < .001 : a-b < .001;
1063 }
1064
1065 struct Point {
1066 float x = 0, y = 0;
opEqualsPoint1067 const bool opEquals(const ref Point rhs)
1068 {
1069 return approxEqual(x, rhs.x) && approxEqual(y, rhs.y);
1070 }
1071 }
1072
1073 struct Rectangle {
1074 Point leftBottom, rightTop;
1075 }
1076
test40()1077 void test40()
1078 {
1079 Rectangle a, b;
1080 assert(a == b);
1081 a.leftBottom.x = 1e-8;
1082 assert(a == b);
1083 a.rightTop.y = 5;
1084 assert(a != b);
1085 }
1086
1087 /**********************************/
1088
1089 struct S41 {
thisS411090 this(int) immutable { }
1091 }
1092
test41()1093 void test41()
1094 {
1095 auto s = new immutable S41(3);
1096 //writeln(typeid(typeof(s)));
1097 static assert(is(typeof(s) == immutable(S41)*));
1098
1099 auto t = immutable S41(3);
1100 //writeln(typeid(typeof(t)));
1101 static assert(is(typeof(t) == immutable(S41)));
1102 }
1103
1104 /**********************************/
1105
1106 class C42 {
this(int)1107 this(int) immutable {
1108 }
1109 }
1110
test42()1111 void test42()
1112 {
1113 static assert(!__traits(compiles, new C42(3)));
1114 //writeln(typeid(typeof(c)));
1115 //static assert(is(typeof(c) == immutable(C42)));
1116
1117 auto d = new immutable(C42)(3);
1118 //writeln(typeid(typeof(d)));
1119 static assert(is(typeof(d) == immutable(C42)));
1120 }
1121
1122 /**********************************/
1123
1124 struct S43 {
1125 int i;
1126 int* p;
1127 // this(int i, int* t) immutable { this.i = i; p = t; }
1128 }
1129
test43()1130 void test43()
1131 {
1132 int i;
1133 assert(!__traits(compiles, immutable(S43)(3, &i)));
1134 immutable int j = 4;
1135 auto s = immutable(S43)(3, &j);
1136 //writeln(typeid(typeof(s)));
1137 static assert(is(typeof(s) == immutable(S43)));
1138 }
1139
1140 /**********************************/
1141
1142 struct S44 {
1143 int i;
1144 immutable(int)* p;
thisS441145 this(int i, immutable(int)* t) immutable { this.i = i; this.p = t; }
1146 }
1147
test44()1148 void test44()
1149 {
1150 int i;
1151 assert(!__traits(compiles, immutable(S44)(3, &i)));
1152 immutable int j = 4;
1153 auto s = immutable(S44)(3, &j);
1154 //writeln(typeid(typeof(s)));
1155 static assert(is(typeof(s) == immutable(S44)));
1156 }
1157
1158 /**********************************/
1159
1160 class C45 {
1161 C45 next;
this(int[]data)1162 this(int[] data) immutable {
1163 next = new immutable(C45)(data[1 .. $]);
1164 }
1165 }
1166
test45()1167 void test45()
1168 {
1169 }
1170
1171 /**********************************/
1172 // 3986
1173
1174 struct SiberianHamster
1175 {
1176 int rat = 813;
thisSiberianHamster1177 this(string z) { }
1178 }
1179
test46()1180 void test46()
1181 {
1182 SiberianHamster basil = "cybil";
1183 assert(basil.rat == 813);
1184 }
1185
1186 /**********************************/
1187 // 8741
1188
1189 struct Vec8741
1190 {
thisVec87411191 this(float x)
1192 {
1193 m[0] = x;
1194 m[1] = 58;
1195 }
1196 float[2] m;
1197 static Vec8741 zzz = Vec8741(7);
1198 }
1199
test8741()1200 void test8741()
1201 {
1202 assert(Vec8741.zzz.m[0] == 7);
1203 assert(Vec8741.zzz.m[1] == 58);
1204 }
1205
1206 /**********************************/
1207
1208 struct Segfault3984
1209 {
1210 int a;
thisSegfault39841211 this(int x){
1212 a = x;
1213 }
1214 }
1215
test47()1216 void test47()
1217 {
1218 //static
1219 assert(Segfault3984(3).a == 3);
1220 }
1221
1222 /**********************************/
1223
test48()1224 void test48()
1225 {
1226 struct B {
1227 void foo() { }
1228 }
1229 B x = B.init;
1230 }
1231
1232 /**********************************/
1233
1234 struct Foo49 {
1235 int z;
thisFoo491236 this(int a){z=a;}
1237 }
1238
1239 void bar49(Foo49 a = Foo49(1))
1240 {
1241 assert(a.z == 1);
1242 }
1243
test49()1244 void test49()
1245 {
1246 bar49();
1247 bar49();
1248 }
1249
1250 /**********************************/
1251
1252 struct aStruct{
1253 int m_Int;
1254
thisaStruct1255 this(int a){
1256 m_Int = a;
1257 }
1258 }
1259
1260 class aClass{
1261 void aFunc(aStruct a = aStruct(44))
1262 {
1263 assert(a.m_Int == 44);
1264 }
1265 }
1266
test50()1267 void test50()
1268 {
1269 aClass a = new aClass();
1270 a.aFunc();
1271 a.aFunc();
1272 }
1273
1274 /**********************************/
1275
1276 int A51_a;
1277
1278 struct A51
1279 {
~thisA511280 ~this() { ++A51_a; }
1281 }
1282
test51()1283 void test51()
1284 {
1285 A51_a = 0; { while(0) A51 a; } assert(A51_a == 0);
1286 A51_a = 0; { if(0) A51 a; } assert(A51_a == 0);
1287 A51_a = 0; { if(1){} else A51 a; } assert(A51_a == 0);
1288 A51_a = 0; { for(;0;) A51 a; } assert(A51_a == 0);
1289 A51_a = 0; { if (1) { A51 a; } } assert(A51_a == 1);
1290 A51_a = 0; { if (1) A51 a; } assert(A51_a == 1);
1291 A51_a = 0; { if(0) {} else A51 a; } assert(A51_a == 1);
1292 A51_a = 0; { if (0) for(A51 a;;) {} } assert(A51_a == 0);
1293 A51_a = 0; { if (0) for(;;) A51 a; } assert(A51_a == 0);
1294 A51_a = 0; { do A51 a; while(0); } assert(A51_a == 1);
1295 A51_a = 0; { if (0) while(1) A51 a; } assert(A51_a == 0);
1296 A51_a = 0; { try A51 a; catch(Error e) {} } assert(A51_a == 1);
1297 A51_a = 0; { if (0) final switch(1) A51 a; } assert(A51_a == 0); // should fail to build
1298 // A51_a = 0; { if (0) switch(1) { A51 a; default: } } assert(A51_a == 0);
1299 A51_a = 0; { if (0) switch(1) { default: A51 a; } } assert(A51_a == 0);
1300 // A51_a = 0; { if (1) switch(1) { A51 a; default: } } assert(A51_a == 1); // should be 0, right?
1301 A51_a = 0; { if (1) switch(1) { default: A51 a; } } assert(A51_a == 1);
1302 // A51_a = 0; { final switch(0) A51 a; } assert(A51_a == 0);
1303 A51_a = 0; { A51 a; with(a) A51 b; } assert(A51_a == 2);
1304 }
1305
1306 /**********************************/
1307
1308 string s52;
1309
1310 struct A52
1311 {
1312 int m;
thisA521313 this(this)
1314 {
1315 printf("this(this) %p\n", &this);
1316 s52 ~= 'a';
1317 }
~thisA521318 ~this()
1319 {
1320 printf("~this() %p\n", &this);
1321 s52 ~= 'b';
1322 }
copyA521323 A52 copy()
1324 {
1325 s52 ~= 'c';
1326 A52 another = this;
1327 return another;
1328 }
1329 }
1330
test52()1331 void test52()
1332 {
1333 {
1334 A52 a;
1335 A52 b = a.copy();
1336 printf("a: %p, b: %p\n", &a, &b);
1337 }
1338 printf("s = '%.*s'\n", s52.length, s52.ptr);
1339 assert(s52 == "cabb");
1340 }
1341
1342 /**********************************/
1343 // 4339
1344
1345 struct A53 {
invariantA531346 invariant() { }
~thisA531347 ~this() { }
opAssignA531348 void opAssign(A53 a) {}
blahA531349 int blah(A53 a) { return 0; }
1350 }
1351
1352 /**********************************/
1353
1354 struct S54
1355 {
1356 int x = 1;
1357
bar()1358 int bar() { return x; }
1359
this(int i)1360 this(int i)
1361 {
1362 printf("ctor %p(%d)\n", &this, i);
1363 t ~= "a";
1364 }
1365
this(this)1366 this(this)
1367 {
1368 printf("postblit %p\n", &this);
1369 t ~= "b";
1370 }
1371
~this()1372 ~this()
1373 {
1374 printf("dtor %p\n", &this);
1375 t ~= "c";
1376 }
1377
1378 static string t;
1379 }
1380
bar54(S54 s)1381 void bar54(S54 s) { }
1382
abc54()1383 S54 abc54() { return S54(1); }
1384
test54()1385 void test54()
1386 {
1387 { S54.t = null;
1388 S54 s = S54(1);
1389 }
1390 assert(S54.t == "ac");
1391
1392 { S54.t = null;
1393 S54 s = S54();
1394 }
1395 assert(S54.t == "c");
1396
1397 { S54.t = null;
1398 int b = 1 && (bar54(S54(1)), 1);
1399 }
1400 assert(S54.t == "ac");
1401
1402 { S54.t = null;
1403 int b = 0 && (bar54(S54(1)), 1);
1404 }
1405 assert(S54.t == "");
1406
1407 { S54.t = null;
1408 int b = 0 || (bar54(S54(1)), 1);
1409 }
1410 assert(S54.t == "ac");
1411
1412 { S54.t = null;
1413 int b = 1 || (bar54(S54(1)), 1);
1414 }
1415 assert(S54.t == "");
1416
1417 {
1418 S54.t = null;
1419 { const S54 s = S54(1); }
1420 assert(S54.t == "ac");
1421 }
1422 {
1423 S54.t = null;
1424 abc54();
1425 assert(S54.t == "ac");
1426 }
1427 {
1428 S54.t = null;
1429 abc54().x += 1;
1430 assert(S54.t == "ac");
1431 }
1432 }
1433
1434 /**********************************/
1435
test55()1436 void test55()
1437 {
1438 S55 s;
1439 auto t = s.copy();
1440 assert(t.count == 1); // (5)
1441 }
1442
1443 struct S55
1444 {
1445 int count;
thisS551446 this(this) { ++count; }
copyS551447 S55 copy() { return this; }
1448 }
1449
1450 /**********************************/
1451
1452 struct S56
1453 {
1454 int x = 1;
1455
bar()1456 int bar() { return x; }
1457
this(int i)1458 this(int i)
1459 {
1460 printf("ctor %p(%d)\n", &this, i);
1461 t ~= "a";
1462 }
1463
this(this)1464 this(this)
1465 {
1466 printf("postblit %p\n", &this);
1467 t ~= "b";
1468 }
1469
~this()1470 ~this()
1471 {
1472 printf("dtor %p\n", &this);
1473 t ~= "c";
1474 }
1475
1476 static string t;
1477 }
1478
foo56()1479 int foo56()
1480 {
1481 throw new Throwable("hello");
1482 return 5;
1483 }
1484
1485
test56()1486 void test56()
1487 {
1488 int i;
1489 int j;
1490 try
1491 {
1492 j |= 1;
1493 i = S56(1).x + foo56() + 1;
1494 j |= 2;
1495 }
1496 catch (Throwable o)
1497 {
1498 printf("caught\n");
1499 j |= 4;
1500 }
1501 printf("i = %d, j = %d\n", i, j);
1502 assert(i == 0);
1503 assert(j == 5);
1504 }
1505
1506 /**********************************/
1507 // 5859
1508
1509 int dtor_cnt = 0;
1510 struct S57
1511 {
1512 int v;
thisS571513 this(int n){ v = n; printf("S.ctor v=%d\n", v); }
~thisS571514 ~this(){ ++dtor_cnt; printf("S.dtor v=%d\n", v); }
1515 bool opCast(T:bool)(){ printf("S.cast v=%d\n", v); return true; }
1516 }
f(int n)1517 S57 f(int n){ return S57(n); }
1518
test57()1519 void test57()
1520 {
1521 printf("----\n");
1522 dtor_cnt = 0;
1523 if (auto s = S57(10))
1524 {
1525 printf("ifbody\n");
1526 }
1527 else assert(0);
1528 assert(dtor_cnt == 1);
1529
1530 printf("----\n"); //+
1531 dtor_cnt = 0;
1532 if (auto s = (S57(1), S57(2), S57(10)))
1533 {
1534 assert(dtor_cnt == 2);
1535 printf("ifbody\n");
1536 }
1537 else assert(0);
1538 assert(dtor_cnt == 3); // +/
1539
1540 printf("----\n");
1541 dtor_cnt = 0;
1542 try{
1543 if (auto s = S57(10))
1544 {
1545 printf("ifbody\n");
1546 throw new Exception("test");
1547 }
1548 else assert(0);
1549 }catch (Exception e){}
1550 assert(dtor_cnt == 1);
1551
1552
1553
1554 printf("----\n");
1555 dtor_cnt = 0;
1556 if (auto s = f(10))
1557 {
1558 printf("ifbody\n");
1559 }
1560 else assert(0);
1561 assert(dtor_cnt == 1);
1562
1563 printf("----\n"); //+
1564 dtor_cnt = 0;
1565 if (auto s = (f(1), f(2), f(10)))
1566 {
1567 assert(dtor_cnt == 2);
1568 printf("ifbody\n");
1569 }
1570 else assert(0);
1571 assert(dtor_cnt == 3); // +/
1572
1573 printf("----\n");
1574 dtor_cnt = 0;
1575 try{
1576 if (auto s = f(10))
1577 {
1578 printf("ifbody\n");
1579 throw new Exception("test");
1580 }
1581 else assert(0);
1582 }catch (Exception e){}
1583 assert(dtor_cnt == 1);
1584
1585
1586
1587
1588 printf("----\n");
1589 dtor_cnt = 0;
1590 if (S57(10))
1591 {
1592 assert(dtor_cnt == 1);
1593 printf("ifbody\n");
1594 }
1595 else assert(0);
1596
1597 printf("----\n");
1598 dtor_cnt = 0;
1599 if ((S57(1), S57(2), S57(10)))
1600 {
1601 assert(dtor_cnt == 3);
1602 printf("ifbody\n");
1603 }
1604 else assert(0);
1605
1606 printf("----\n");
1607 dtor_cnt = 0;
1608 try{
1609 if (auto s = S57(10))
1610 {
1611 printf("ifbody\n");
1612 throw new Exception("test");
1613 }
1614 else assert(0);
1615 }catch (Exception e){}
1616 assert(dtor_cnt == 1);
1617
1618
1619
1620 printf("----\n");
1621 dtor_cnt = 0;
1622 if (f(10))
1623 {
1624 assert(dtor_cnt == 1);
1625 printf("ifbody\n");
1626 }
1627 else assert(0);
1628
1629 printf("----\n");
1630 dtor_cnt = 0;
1631 if ((f(1), f(2), f(10)))
1632 {
1633 assert(dtor_cnt == 3);
1634 printf("ifbody\n");
1635 }
1636 else assert(0);
1637
1638 printf("----\n");
1639 dtor_cnt = 0;
1640 try{
1641 if (auto s = f(10))
1642 {
1643 printf("ifbody\n");
1644 throw new Exception("test");
1645 }
1646 else assert(0);
1647 }catch (Exception e){}
1648 assert(dtor_cnt == 1);
1649 }
1650
1651 /**********************************/
1652 // 5574
1653
1654 struct foo5574a
1655 {
~thisfoo5574a1656 ~this() {}
1657 }
1658 class bar5574a
1659 {
1660 foo5574a[1] frop;
1661 }
1662
1663 struct foo5574b
1664 {
thisfoo5574b1665 this(this){}
1666 }
1667 struct bar5574b
1668 {
1669 foo5574b[1] frop;
1670 }
1671
1672 /**********************************/
1673 // 5777
1674
1675 int sdtor58 = 0;
1676 S58* ps58;
1677
1678 struct S58
1679 {
1680 @disable this(this);
~thisS581681 ~this(){ ++sdtor58; }
1682 }
1683
makeS58()1684 S58 makeS58()
1685 {
1686 S58 s;
1687 ps58 = &s;
1688 return s;
1689 }
1690
test58()1691 void test58()
1692 {
1693 auto s1 = makeS58();
1694 assert(ps58 == &s1);
1695 assert(sdtor58 == 0);
1696 }
1697
1698 /**********************************/
1699 // 6308
1700
1701 struct C59
1702 {
oopsC591703 void oops()
1704 {
1705 throw new Throwable("Oops!");
1706 }
1707
~thisC591708 ~this()
1709 {
1710 }
1711 }
1712
foo59()1713 void foo59()
1714 {
1715 C59().oops();
1716 // auto c = C(); c.oops();
1717 }
1718
1719
test59()1720 void test59()
1721 {
1722 int i = 0;
1723 try
1724 foo59();
1725 catch (Throwable)
1726 { i = 1;
1727 }
1728 assert(i == 1);
1729 }
1730
1731 /**********************************/
1732 // 5737
1733
test5737()1734 void test5737()
1735 {
1736 static struct S
1737 {
1738 static int destroyed;
1739 static int copied;
1740
1741 this(this)
1742 {
1743 copied++;
1744 }
1745
1746 ~this()
1747 {
1748 destroyed++;
1749 }
1750 }
1751
1752 static S s;
1753
1754 ref S foo()
1755 {
1756 return s;
1757 }
1758
1759 {
1760 auto s2 = foo();
1761 }
1762
1763 assert(S.copied == 1); // fail, s2 was not copied;
1764 assert(S.destroyed == 1); // ok, s2 was destroyed
1765 }
1766
1767 /**********************************/
1768 // 6119
1769
test6119()1770 void test6119()
1771 {
1772 int postblit = 0;
1773 int dtor = 0;
1774
1775 struct Test
1776 {
1777 this(this) { ++postblit; }
1778 ~this() { ++dtor; }
1779 }
1780
1781 void takesVal(Test x) {}
1782 ref Test returnsRef(ref Test x) { return x; }
1783
1784 void f(ref Test x) { takesVal( x ); }
1785
1786 Test x;
1787
1788 postblit = dtor = 0;
1789 takesVal(returnsRef(x));
1790 assert(postblit == 1);
1791 assert(dtor == 1);
1792
1793 postblit = dtor = 0;
1794 f(x);
1795 assert(postblit == 1);
1796 assert(dtor == 1);
1797 }
1798
1799 /**********************************/
1800 // 6364
1801
1802 struct Foo6364
1803 {
1804 int state = 1;
1805
~thisFoo63641806 ~this()
1807 {
1808 state = 0;
1809 }
1810 }
1811
testfoo6364()1812 void testfoo6364()
1813 {
1814 static Foo6364 foo;
1815 printf("%d\n", foo.state);
1816 assert(foo.state == 1);
1817 }
1818
test6364()1819 void test6364()
1820 {
1821 testfoo6364();
1822 testfoo6364();
1823 }
1824
1825 /**********************************/
1826 // 6499
1827
1828 struct S6499
1829 {
1830 string m = "<not set>";
1831
thisS64991832 this(string s)
1833 {
1834 m = s;
1835 printf("Constructor - %.*s\n", m.length, m.ptr);
1836 if (m == "foo") { ++sdtor; assert(sdtor == 1); }
1837 if (m == "bar") { ++sdtor; assert(sdtor == 2); }
1838 }
thisS64991839 this(this)
1840 {
1841 printf("Postblit - %.*s\n", m.length, m.ptr);
1842 assert(0);
1843 }
~thisS64991844 ~this()
1845 {
1846 printf("Destructor - %.*s\n", m.length, m.ptr);
1847 if (m == "bar") { assert(sdtor == 2); --sdtor; }
1848 if (m == "foo") { assert(sdtor == 1); --sdtor; }
1849 }
barS64991850 S6499 bar() { return S6499("bar"); }
bazS64991851 S6499 baz()() { return S6499("baz"); }
1852 }
1853
test6499()1854 void test6499()
1855 {
1856 S6499 foo() { return S6499("foo"); }
1857
1858 {
1859 sdtor = 0;
1860 scope(exit) assert(sdtor == 0);
1861 foo().bar();
1862 }
1863 {
1864 sdtor = 0;
1865 scope(exit) assert(sdtor == 0);
1866 foo().baz();
1867 }
1868 }
1869
1870 /**********************************/
1871
isImplicitlyConvertible(From,To)1872 template isImplicitlyConvertible(From, To)
1873 {
1874 enum bool isImplicitlyConvertible = is(typeof({
1875 void fun(ref From v) {
1876 void gun(To) {}
1877 gun(v);
1878 }
1879 }()));
1880 }
1881
test60()1882 void test60()
1883 {
1884 static struct X1
1885 {
1886 void* ptr;
1887 this(this){}
1888 }
1889 static struct S1
1890 {
1891 X1 x;
1892 }
1893
1894 static struct X2
1895 {
1896 int ptr;
1897 this(this){}
1898 }
1899 static struct S2
1900 {
1901 X2 x;
1902 }
1903
1904 {
1905 S1 ms;
1906 S1 ms2 = ms; // mutable to mutable
1907 const(S1) cs2 = ms; // mutable to const // NG -> OK
1908 }
1909 {
1910 const(S1) cs;
1911 static assert(!__traits(compiles,{ // NG -> OK
1912 S1 ms2 = cs; // field has reference, then const to mutable is invalid
1913 }));
1914 const(S1) cs2 = cs; // const to const // NG -> OK
1915 }
1916 static assert( isImplicitlyConvertible!( S1 , S1 ) );
1917 static assert( isImplicitlyConvertible!( S1 , const(S1)) ); // NG -> OK
1918 static assert(!isImplicitlyConvertible!(const(S1), S1 ) );
1919 static assert( isImplicitlyConvertible!(const(S1), const(S1)) ); // NG -> OK
1920
1921
1922 {
1923 S2 ms;
1924 S2 ms2 = ms; // mutable to mutable
1925 const(S2) cs2 = ms; // mutable to const // NG -> OK
1926 }
1927 {
1928 const(S2) cs;
1929 S2 ms2 = cs; // all fields are value, then const to mutable is OK
1930 const(S2) cs2 = cs; // const to const // NG -> OK
1931 }
1932
1933 static assert( isImplicitlyConvertible!( S2 , S2 ) );
1934 static assert( isImplicitlyConvertible!( S2 , const(S2)) ); // NG -> OK
1935 static assert( isImplicitlyConvertible!(const(S2), S2 ) );
1936 static assert( isImplicitlyConvertible!(const(S2), const(S2)) ); // NG -> OK
1937 }
1938
1939 /**********************************/
1940 // 4316
1941
1942 struct A4316
1943 {
thisA43161944 this(this) @safe { }
1945 }
1946
test4316()1947 @safe void test4316()
1948 {
1949 A4316 a;
1950 auto b = a; // Error: safe function 'main' cannot call system function'__cpctor'
1951 }
1952
1953 /**********************************/
1954
1955 struct F6177
1956 {
~thisF61771957 ~this() {}
1958 }
1959
1960 struct G6177
1961 {
this(F6177[]p...)1962 this(F6177[] p...) {}
1963 }
1964
test6177()1965 void test6177()
1966 {
1967 F6177 c;
1968 auto g = G6177(c);
1969 }
1970
1971
1972 /**********************************/
1973 // 6470
1974
1975 struct S6470
1976 {
1977 static int spblit;
1978
thisS64701979 this(this){ ++spblit; }
1980 }
1981
test6470()1982 void test6470()
1983 {
1984 S6470[] a1;
1985 S6470[] a2;
1986 a1.length = 3;
1987 a2.length = 3;
1988 a1[] = a2[];
1989 assert(S6470.spblit == 3);
1990
1991 S6470 s;
1992
1993 S6470[] a3;
1994 a3.length = 3;
1995 a3 = [s, s, s];
1996 assert(S6470.spblit == 6);
1997
1998 void func(S6470[] a){}
1999 func([s, s, s]);
2000 assert(S6470.spblit == 9);
2001 }
2002
2003 /**********************************/
2004 // 6636
2005
2006 struct S6636
2007 {
~thisS66362008 ~this()
2009 {
2010 ++sdtor;
2011 }
2012 }
2013
func6636(S6636[3]sa)2014 void func6636(S6636[3] sa) {}
2015
test6636()2016 void test6636()
2017 {
2018 sdtor = 0;
2019
2020 S6636[3] sa;
2021 func6636(sa);
2022 assert(sdtor == 3);
2023 }
2024
2025 /**********************************/
2026 // 6637
2027
2028 struct S6637
2029 {
2030 static int spblit;
2031
thisS66372032 this(this){ ++spblit; }
2033 }
2034
test6637()2035 void test6637()
2036 {
2037 void func(S6637[3] sa){}
2038
2039 S6637[3] sa;
2040 func(sa);
2041 assert(S6637.spblit == 3);
2042 }
2043
2044 /**********************************/
2045 // 7353
2046
2047 struct S7353
2048 {
2049 static uint ci = 0;
2050 uint i;
2051
thisS73532052 this(int x) { i = ci++; /*writeln("new: ", i);*/ }
thisS73532053 this(this) { i = ci++; /*writeln("copy ", i);*/ }
~thisS73532054 ~this() { /*writeln("del ", i);*/ }
2055
save1S73532056 S7353 save1() // produces 2 copies in total
2057 {
2058 S7353 s = this;
2059 return s;
2060 }
save2S73532061 auto save2() // produces 3 copies in total
2062 {
2063 S7353 s = this;
2064 return s;
2065 pragma(msg, typeof(return));
2066 }
2067 }
test7353()2068 void test7353()
2069 {
2070 {
2071 auto s = S7353(1), t = S7353(1);
2072 t = s.save1();
2073 assert(S7353.ci == 3);
2074 }
2075 S7353.ci = 0; //writeln("-");
2076 {
2077 auto s = S7353(1), t = S7353(1);
2078 t = s.save2();
2079 assert(S7353.ci == 3);
2080 }
2081 }
2082
2083 /**********************************/
2084 // 8036
2085
2086 struct S8036a
2087 {
~thisS8036a2088 ~this() {}
2089 }
2090 struct S8036b // or class
2091 {
2092 S8036a[0] s;
2093 }
2094
2095 /**********************************/
2096
2097 struct S61
2098 {
thisS612099 this(long length)
2100 {
2101 this.length = length;
2102 }
2103
2104 long length;
2105 }
2106
2107
copy(const S61 s)2108 const(S61) copy(const S61 s)
2109 {
2110 return s;
2111 }
2112
2113
test61()2114 void test61()
2115 {
2116 S61 t = S61(42);
2117 const S61 u = t;
2118
2119 assert(t == u);
2120 assert(copy(t) == u);
2121 assert(t == copy(u));
2122 }
2123
2124 /**********************************/
2125 // 7506
2126
test7506()2127 void test7506()
2128 {
2129 static struct S
2130 {
2131 static uint ci = 0;
2132 static uint di = 0;
2133 uint i;
2134
2135 this(int x) { i = ci++; /*writeln("new: ", i);*/ }
2136 this(this) { i = ci++; /*writeln("copy ", i);*/ }
2137 ~this() { ++di; /*writeln("del: ", i);*/ }
2138
2139 S save3()
2140 {
2141 return this;
2142 }
2143 }
2144
2145 {
2146 auto s = S(1), t = S(1);
2147 assert(S.ci == 2);
2148 t = s.save3();
2149 assert(S.ci == 3); // line 23
2150 }
2151 assert(S.di == 3);
2152 }
2153
2154 /**********************************/
2155 // 7516
2156
2157 struct S7516
2158 {
2159 int val;
2160
2161 this(int n) { val = n; }
2162 this(this) { val *= 3; }
2163 }
2164
2165 // CondExp on return statement
2166 void test7516a()
2167 {
2168 alias S = S7516;
2169 S s1 = S(1);
2170 S s2 = S(2);
2171
2172 S foo(bool f) { return f ? s1 : s2; }
2173 S hoo(bool f) { return f ? S(1) : S(2); }
2174 S bar(bool f) { return f ? s1 : S(2); }
2175 S baz(bool f) { return f ? S(1) : s2; }
2176
2177 auto r1 = foo(true); assert(r1.val == 3);
2178 auto r2 = foo(false); assert(r2.val == 6);
2179 auto r3 = hoo(true); assert(r3.val == 1);
2180 auto r4 = hoo(false); assert(r4.val == 2);
2181 auto r5 = bar(true); assert(r5.val == 3);
2182 auto r6 = bar(false); assert(r6.val == 2);
2183 auto r7 = baz(true); assert(r7.val == 1);
2184 auto r8 = baz(false); assert(r8.val == 6);
2185 }
2186
2187 // CondExp on function argument
2188 void test7516b()
2189 {
2190 alias S = S7516;
2191 S s1 = S(1);
2192 S s2 = S(2);
2193 S func(S s) { return s; }
2194
2195 S foo(bool f) { return func(f ? s1 : s2 ); }
2196 S hoo(bool f) { return func(f ? S(1) : S(2)); }
2197 S bar(bool f) { return func(f ? s1 : S(2)); }
2198 S baz(bool f) { return func(f ? S(1) : s2 ); }
2199
2200 auto r1 = foo(true); assert(r1.val == 3 * 3);
2201 auto r2 = foo(false); assert(r2.val == 6 * 3);
2202 auto r3 = hoo(true); assert(r3.val == 1 * 3);
2203 auto r4 = hoo(false); assert(r4.val == 2 * 3);
2204 auto r5 = bar(true); assert(r5.val == 3 * 3);
2205 auto r6 = bar(false); assert(r6.val == 2 * 3);
2206 auto r7 = baz(true); assert(r7.val == 1 * 3);
2207 auto r8 = baz(false); assert(r8.val == 6 * 3);
2208 }
2209
2210 // CondExp on array literal
2211 void test7516c()
2212 {
2213 alias S = S7516;
2214 S s1 = S(1);
2215 S s2 = S(2);
2216
2217 S[] foo(bool f) { return [f ? s1 : s2 ]; }
2218 S[] hoo(bool f) { return [f ? S(1) : S(2)]; }
2219 S[] bar(bool f) { return [f ? s1 : S(2)]; }
2220 S[] baz(bool f) { return [f ? S(1) : s2 ]; }
2221
2222 auto r1 = foo(true); assert(r1[0].val == 3);
2223 auto r2 = foo(false); assert(r2[0].val == 6);
2224 auto r3 = hoo(true); assert(r3[0].val == 1);
2225 auto r4 = hoo(false); assert(r4[0].val == 2);
2226 auto r5 = bar(true); assert(r5[0].val == 3);
2227 auto r6 = bar(false); assert(r6[0].val == 2);
2228 auto r7 = baz(true); assert(r7[0].val == 1);
2229 auto r8 = baz(false); assert(r8[0].val == 6);
2230 }
2231
2232 // CondExp on rhs of cat assign
2233 void test7516d()
2234 {
2235 alias S = S7516;
2236 S s1 = S(1);
2237 S s2 = S(2);
2238
2239 S[] foo(bool f) { S[] a; a ~= f ? s1 : s2 ; return a; }
2240 S[] hoo(bool f) { S[] a; a ~= f ? S(1) : S(2); return a; }
2241 S[] bar(bool f) { S[] a; a ~= f ? s1 : S(2); return a; }
2242 S[] baz(bool f) { S[] a; a ~= f ? S(1) : s2 ; return a; }
2243
2244 auto r1 = foo(true); assert(r1[0].val == 3);
2245 auto r2 = foo(false); assert(r2[0].val == 6);
2246 auto r3 = hoo(true); assert(r3[0].val == 1);
2247 auto r4 = hoo(false); assert(r4[0].val == 2);
2248 auto r5 = bar(true); assert(r5[0].val == 3);
2249 auto r6 = bar(false); assert(r6[0].val == 2);
2250 auto r7 = baz(true); assert(r7[0].val == 1);
2251 auto r8 = baz(false); assert(r8[0].val == 6);
2252 }
2253
2254 // CondExp on struct literal element
2255 void test7516e()
2256 {
2257 alias S = S7516;
2258 S s1 = S(1);
2259 S s2 = S(2);
2260 struct X { S s; }
2261
2262 X foo(bool f) { return X(f ? s1 : s2 ); }
2263 X hoo(bool f) { return X(f ? S(1) : S(2)); }
2264 X bar(bool f) { return X(f ? s1 : S(2)); }
2265 X baz(bool f) { return X(f ? S(1) : s2 ); }
2266
2267 auto r1 = foo(true); assert(r1.s.val == 3);
2268 auto r2 = foo(false); assert(r2.s.val == 6);
2269 auto r3 = hoo(true); assert(r3.s.val == 1);
2270 auto r4 = hoo(false); assert(r4.s.val == 2);
2271 auto r5 = bar(true); assert(r5.s.val == 3);
2272 auto r6 = bar(false); assert(r6.s.val == 2);
2273 auto r7 = baz(true); assert(r7.s.val == 1);
2274 auto r8 = baz(false); assert(r8.s.val == 6);
2275 }
2276
2277 /**********************************/
2278 // 7530
2279
2280 void test7530()
2281 {
2282 static struct S
2283 {
2284 int val;
2285
2286 this(int n) { val = n; }
2287 this(this) { val *= 3; }
2288 }
2289
2290 S[] sa = new S[](1);
2291 sa[0].val = 1;
2292 S foo()
2293 {
2294 return sa[0];
2295 }
2296 auto s = foo();
2297 assert(s.val == 3);
2298 }
2299
2300 /**********************************/
2301
2302 struct S62
2303 {
2304 this(int length)
2305 {
2306 _length = length;
2307 }
2308
2309 int opBinary(string op)(in S62 rhs) const
2310 if(op == "-")
2311 {
2312 return this.length - rhs.length;
2313 }
2314
2315 @property int length() const
2316 {
2317 return _length;
2318 }
2319
2320 invariant()
2321 {
2322 assert(_length == 1);
2323 }
2324
2325 int _length = 1;
2326 }
2327
2328
2329 void test62()
2330 {
2331 immutable result = S62.init - S62.init;
2332 }
2333
2334 /**********************************/
2335 // 7579
2336
2337 void test7579a()
2338 {
2339 static struct S
2340 {
2341 // postblit can also have no body because isn't called
2342 @disable this(this) { assert(0); }
2343 }
2344
2345 @property S fs() { return S(); }
2346 @property S[3] fsa() { return [S(), S(), S()]; }
2347
2348 S s0;
2349 S s1 = S();
2350 static assert(!__traits(compiles, { S s2 = s1; })); // OK
2351 S s2 = fs;
2352 static assert(!__traits(compiles, { s2 = s1; })); // OK
2353
2354 // static array
2355 S[3] sa0;
2356 S[3] sa1 = [S(), S(), S()];
2357 static assert(!__traits(compiles, { S[3] sa2 = sa1; })); // fixed
2358 S[3] sa2 = fsa;
2359 static assert(!__traits(compiles, { sa2 = sa1; })); // fixed
2360 sa2 = [S(), S(), S()];
2361 sa2 = fsa;
2362
2363 S[] da1 = new S[3];
2364 S[] da2 = new S[3];
2365 static assert(!__traits(compiles, { da2[] = da1[]; })); // fixed
2366
2367 // concatenation and appending
2368 static assert(!__traits(compiles, { da1 ~= s1; })); // fixed
2369 static assert(!__traits(compiles, { da1 ~= S(); }));
2370 static assert(!__traits(compiles, { da1 ~= fsa; }));
2371 static assert(!__traits(compiles, { da1 ~= fsa[]; }));
2372 static assert(!__traits(compiles, { da1 = da1 ~ s1; })); // fixed
2373 static assert(!__traits(compiles, { da1 = s1 ~ da1; })); // fixed
2374 static assert(!__traits(compiles, { da1 = da1 ~ S(); }));
2375 static assert(!__traits(compiles, { da1 = da1 ~ fsa; }));
2376 static assert(!__traits(compiles, { da1 = da1 ~ da; }));
2377 }
2378
2379 void test7579b()
2380 {
2381 static struct S
2382 {
2383 // postblit asserts in runtime
2384 this(this) { assert(0); }
2385 }
2386
2387 @property S fs() { return S(); }
2388 @property S[3] fsa() { return [S(), S(), S()]; }
2389
2390 S s0;
2391 S s1 = S();
2392 S s2 = fs;
2393
2394 // static array
2395 S[3] sa0;
2396 S[3] sa1 = [S(), S(), S()];
2397 S[3] sa2 = fsa;
2398 sa2 = [S(), S(), S()];
2399 sa2 = fsa;
2400
2401 S[] da1 = new S[3];
2402 S[] da2 = new S[3];
2403
2404 // concatenation and appending always run postblits
2405 }
2406
2407 /**********************************/
2408 // 8335
2409
2410 struct S8335
2411 {
2412 static int postblit;
2413
2414 int i;
2415 this(this) { ++postblit; }
2416 }
2417
2418 void f8335(ref S8335[3] arr)
2419 {
2420 arr[0].i = 7;
2421 }
2422
2423 void g8335(lazy S8335[3] arr)
2424 {
2425 assert(S8335.postblit == 0);
2426 auto x = arr;
2427 assert(S8335.postblit == 3);
2428 }
2429
2430 void h8335(lazy S8335 s)
2431 {
2432 assert(S8335.postblit == 0);
2433 auto x = s;
2434 assert(S8335.postblit == 1);
2435 }
2436
2437 void test8335()
2438 {
2439 S8335[3] arr;
2440 f8335(arr);
2441 assert(S8335.postblit == 0);
2442 assert(arr[0].i == 7);
2443
2444 g8335(arr);
2445 assert(S8335.postblit == 3);
2446
2447 S8335.postblit = 0;
2448 S8335 s;
2449 h8335(s);
2450 assert(S8335.postblit == 1);
2451 }
2452
2453 /**********************************/
2454 // 8356
2455
2456 void test8356()
2457 {
2458 static struct S
2459 {
2460 @disable this(this) { assert(0); }
2461 }
2462
2463 S s;
2464 S[3] sa;
2465
2466 static assert(!__traits(compiles, {
2467 S fs() { return s; }
2468 }));
2469
2470 static assert(!__traits(compiles, {
2471 S[3] fsa() { return sa; }
2472 }));
2473 }
2474
2475 /**********************************/
2476 // 8475
2477
2478 T func8475(T)(T x) @safe pure
2479 {
2480 return T();
2481 }
2482
2483 template X8475(bool something)
2484 {
2485 struct XY
2486 {
2487 this(this) @safe pure {}
2488 void func(XY x) @safe pure
2489 {
2490 XY y = x; //Error: see below
2491 func8475(x);
2492 func8475(y);
2493 }
2494 }
2495 }
2496
2497 alias X8475!(true).XY Xtrue;
2498
2499 /**********************************/
2500
2501 struct Foo9320 {
2502 real x;
2503
2504 this(real x) {
2505 this.x = x;
2506 }
2507
2508 Foo9320 opBinary(string op)(Foo9320 other) {
2509 return Foo9320(mixin("x" ~ op ~ "other.x"));
2510 }
2511 }
2512
2513 Foo9320 test9320(Foo9320 a, Foo9320 b, Foo9320 c) {
2514 return (a + b) / (a * b) - c;
2515 }
2516
2517 /**********************************/
2518 // 9386
2519
2520 struct Test9386
2521 {
2522 string name;
2523 static char[25] op;
2524 static size_t i;
2525
2526 static @property string sop() { return cast(string)op[0..i]; }
2527
2528 this(string name)
2529 {
2530 this.name = name;
2531 printf("Created %.*s...\n", name.length, name.ptr);
2532 assert(i + 1 < op.length);
2533 op[i++] = 'a';
2534 }
2535
2536 this(this)
2537 {
2538 printf("Copied %.*s...\n", name.length, name.ptr);
2539 assert(i + 1 < op.length);
2540 op[i++] = 'b';
2541 }
2542
2543 ~this()
2544 {
2545 printf("Deleted %.*s\n", name.length, name.ptr);
2546 assert(i + 1 < op.length);
2547 op[i++] = 'c';
2548 }
2549
2550 const int opCmp(ref const Test9386 t)
2551 {
2552 return op[0] - t.op[0];
2553 }
2554 }
2555
2556 void test9386()
2557 {
2558 {
2559 Test9386.op[] = 0;
2560 Test9386.i = 0;
2561
2562 Test9386[] tests =
2563 [ Test9386("one"),
2564 Test9386("two"),
2565 Test9386("three"),
2566 Test9386("four") ];
2567
2568 assert(Test9386.sop == "aaaa");
2569 Test9386.op[] = 0;
2570 Test9386.i = 0;
2571
2572 printf("----\n");
2573 foreach (Test9386 test; tests)
2574 {
2575 printf("\tForeach %.*s\n", test.name.length, test.name.ptr);
2576 Test9386.op[Test9386.i++] = 'x';
2577 }
2578
2579 assert(Test9386.sop == "bxcbxcbxcbxc");
2580 Test9386.op[] = 0;
2581 Test9386.i = 0;
2582
2583 printf("----\n");
2584 foreach (ref Test9386 test; tests)
2585 {
2586 printf("\tForeach %.*s\n", test.name.length, test.name.ptr);
2587 Test9386.op[Test9386.i++] = 'x';
2588 }
2589 assert(Test9386.sop == "xxxx");
2590 }
2591 printf("====\n");
2592 {
2593 Test9386.op[] = 0;
2594 Test9386.i = 0;
2595
2596 Test9386[Test9386] tests =
2597 [ Test9386("1") : Test9386("one"),
2598 Test9386("2") : Test9386("two"),
2599 Test9386("3") : Test9386("three"),
2600 Test9386("4") : Test9386("four") ];
2601
2602 Test9386.op[] = 0;
2603 Test9386.i = 0;
2604
2605 printf("----\n");
2606 foreach (Test9386 k, Test9386 v; tests)
2607 {
2608 printf("\tForeach %.*s : %.*s\n", k.name.length, k.name.ptr,
2609 v.name.length, v.name.ptr);
2610 Test9386.op[Test9386.i++] = 'x';
2611 }
2612
2613 assert(Test9386.sop == "bbxccbbxccbbxccbbxcc");
2614 Test9386.op[] = 0;
2615 Test9386.i = 0;
2616
2617 printf("----\n");
2618 foreach (Test9386 k, ref Test9386 v; tests)
2619 {
2620 printf("\tForeach %.*s : %.*s\n", k.name.length, k.name.ptr,
2621 v.name.length, v.name.ptr);
2622 Test9386.op[Test9386.i++] = 'x';
2623 }
2624 assert(Test9386.sop == "bxcbxcbxcbxc");
2625 Test9386.op[] = 0;
2626 Test9386.i = 0;
2627 }
2628 }
2629
2630 /**********************************/
2631 // 9441
2632
2633 auto x9441 = X9441(0.123);
2634
2635 struct X9441
2636 {
2637 int a;
2638 this(double x) { a = cast(int)(x * 100); }
2639 }
2640
2641 void test9441()
2642 {
2643 assert(x9441.a == 12);
2644 }
2645
2646 /**********************************/
2647
2648 struct Payload
2649 {
2650 size_t _capacity; //Comment me
2651 int[] _pay; //Comment me
2652
2653 size_t insertBack(Data d)
2654 {
2655 immutable newLen = _pay.length + 3;
2656 _pay.length = newLen;
2657 _pay = _pay[0 .. newLen]; //Comment me
2658 return 3;
2659 }
2660 }
2661
2662 struct Impl
2663 {
2664 Payload _payload;
2665 size_t _count;
2666 }
2667
2668 struct Data
2669 {
2670 Impl* _store;
2671
2672 this(int i)
2673 {
2674 _store = new Impl;
2675 _store._payload = Payload.init;
2676 }
2677
2678 ~this()
2679 {
2680 printf("%d\n", _store._count);
2681 --_store._count;
2682 }
2683 }
2684
2685
2686 void test9720()
2687 {
2688 auto a = Data(1);
2689 auto b = Data(1);
2690 a._store._payload.insertBack(b); //Fails
2691 }
2692
2693 /**********************************/
2694 // 9899
2695
2696 struct S9899
2697 {
2698 @safe pure nothrow ~this() {}
2699 }
2700
2701 struct MemberS9899
2702 {
2703 S9899 s;
2704 }
2705
2706 void test9899() @safe pure nothrow
2707 {
2708 MemberS9899 s; // 11
2709 }
2710
2711 /**********************************/
2712 // 9907
2713
2714 void test9907()
2715 {
2716 static struct SX(bool hasCtor, bool hasDtor)
2717 {
2718 int i;
2719 static size_t assign;
2720 static size_t dtor;
2721
2722 static if (hasCtor)
2723 {
2724 this(int i) { this.i = i; }
2725 }
2726
2727 void opAssign(SX rhs)
2728 {
2729 printf("%08X(%d) from Rvalue %08X(%d)\n", &this.i, this.i, &rhs.i, rhs.i);
2730 ++assign;
2731 }
2732
2733 void opAssign(ref SX rhs)
2734 {
2735 printf("%08X(%d) from Lvalue %08X(%d)\n", &this.i, this.i, &rhs.i, rhs.i);
2736 assert(0);
2737 }
2738
2739 static if (hasDtor)
2740 {
2741 ~this()
2742 {
2743 printf("destroying %08X(%d)\n", &this.i, this.i);
2744 ++dtor;
2745 }
2746 }
2747 }
2748
2749 S test(S)(int i)
2750 {
2751 return S(i);
2752 }
2753
2754 foreach (hasCtor; TypeTuple!(false, true))
2755 foreach (hasDtor; TypeTuple!(false, true))
2756 {
2757 alias S = SX!(hasCtor, hasDtor);
2758 alias test!S foo;
2759
2760 printf("----\n");
2761 auto s = S(1);
2762
2763 // Assignment from two kinds of rvalues
2764 assert(S.assign == 0);
2765 s = foo(2);
2766 static if (hasDtor) assert(S.dtor == 1);
2767 assert(S.assign == 1);
2768 s = S(3);
2769 assert(S.assign == 2);
2770 static if (hasDtor) assert(S.dtor == 2);
2771 }
2772 printf("----\n");
2773 }
2774
2775 /**********************************/
2776 // 9985
2777
2778 struct S9985
2779 {
2780 ubyte* b;
2781 ubyte buf[128];
2782 this(this) { assert(0); }
2783
2784 static void* ptr;
2785 }
2786 auto ref makeS9985() @system
2787 {
2788 S9985 s;
2789 s.b = s.buf.ptr;
2790 S9985.ptr = &s;
2791 return s;
2792 }
2793 void test9985()
2794 {
2795 S9985 s = makeS9985();
2796 assert(S9985.ptr == &s); // NRVO
2797
2798 static const int n = 1;
2799 static auto ref retN()
2800 {
2801 return n;
2802 }
2803 auto p = &(retN()); // OK
2804 assert(p == &n);
2805 alias pure nothrow @nogc @safe ref const(int) F1();
2806 static assert(is(typeof(retN) == F1));
2807
2808 enum const(int) x = 1;
2809 static auto ref retX()
2810 {
2811 return x;
2812 }
2813 static assert(!__traits(compiles, { auto q = &(retX()); }));
2814 alias pure nothrow @nogc @safe const(int) F2();
2815 static assert(is(typeof(retX) == F2));
2816 }
2817
2818 /**********************************/
2819
2820 // https://issues.dlang.org/show_bug.cgi?id=17457
2821
2822 void delegate() dg17457;
2823
2824 struct S17457 {
2825 ulong[10] data;
2826
2827 this(int seconds) {
2828 dg17457 = &mfunc;
2829 }
2830 void mfunc() {}
2831 }
2832
2833 auto foo17457() {
2834 pragma(inline, false);
2835 return S17457(18);
2836 }
2837
2838 void test17457()
2839 {
2840 auto x = foo17457();
2841 //printf("%p vs %p\n", &x, dg17457.ptr);
2842 assert(&x == dg17457.ptr);
2843 }
2844
2845 /**********************************/
2846 // 9994
2847
2848 void test9994()
2849 {
2850 static struct S
2851 {
2852 static int dtor;
2853 ~this() { ++dtor; }
2854 }
2855
2856 S s;
2857 static assert( __traits(compiles, s.opAssign(s)));
2858 static assert(!__traits(compiles, s.__postblit()));
2859
2860 assert(S.dtor == 0);
2861 s = s;
2862 assert(S.dtor == 1);
2863 }
2864
2865 /**********************************/
2866 // 10053
2867
2868 struct S10053A
2869 {
2870 pure ~this() {}
2871 }
2872
2873 struct S10053B
2874 {
2875 S10053A sa;
2876 ~this() {}
2877 }
2878
2879 /**********************************/
2880 // 10055
2881
2882 void test10055a()
2883 {
2884 static struct SX { pure nothrow @safe ~this() {} }
2885 static struct SY { pure nothrow @safe ~this() {} }
2886 static struct SZ { @disable ~this() {} }
2887
2888 // function to check merge result of the dtor attributes
2889 static void check(S)() { S s; }
2890
2891 static struct S1 { }
2892 static struct S2 { ~this() {} }
2893 static struct SA { SX sx; SY sy; }
2894 static struct SB { SX sx; SY sy; pure nothrow @safe ~this() {} }
2895 static struct SC { SX sx; SY sy; nothrow @safe ~this() {} }
2896 static struct SD { SX sx; SY sy; pure @safe ~this() {} }
2897 static struct SE { SX sx; SY sy; pure nothrow ~this() {} }
2898 static struct SF { SX sx; SY sy; @safe ~this() {} }
2899 static struct SG { SX sx; SY sy; nothrow ~this() {} }
2900 static struct SH { SX sx; SY sy; pure ~this() {} }
2901 static struct SI { SX sx; SY sy; ~this() {} }
2902 static assert(is( typeof(&check!S1) == void function() pure nothrow @nogc @safe ));
2903 static assert(is( typeof(&check!S2) == void function() ));
2904 static assert(is( typeof(&check!SA) == void function() pure nothrow @safe ));
2905 static assert(is( typeof(&check!SB) == void function() pure nothrow @safe ));
2906 static assert(is( typeof(&check!SC) == void function() nothrow @safe ));
2907 static assert(is( typeof(&check!SD) == void function() pure @safe ));
2908 static assert(is( typeof(&check!SE) == void function() pure nothrow ));
2909 static assert(is( typeof(&check!SF) == void function() @safe ));
2910 static assert(is( typeof(&check!SG) == void function() nothrow ));
2911 static assert(is( typeof(&check!SH) == void function() pure ));
2912 static assert(is( typeof(&check!SI) == void function() ));
2913
2914 static struct S1x { SZ sz; }
2915 static struct S2x { ~this() {} SZ sz; }
2916 static struct SAx { SX sx; SY sy; SZ sz; }
2917 static struct SBx { SX sx; SY sy; pure nothrow @safe ~this() {} SZ sz; }
2918 static struct SCx { SX sx; SY sy; nothrow @safe ~this() {} SZ sz; }
2919 static struct SDx { SX sx; SY sy; pure @safe ~this() {} SZ sz; }
2920 static struct SEx { SX sx; SY sy; pure nothrow ~this() {} SZ sz; }
2921 static struct SFx { SX sx; SY sy; @safe ~this() {} SZ sz; }
2922 static struct SGx { SX sx; SY sy; nothrow ~this() {} SZ sz; }
2923 static struct SHx { SX sx; SY sy; pure ~this() {} SZ sz; }
2924 static struct SIx { SX sx; SY sy; ~this() {} SZ sz; }
2925 foreach (Sx; TypeTuple!(S1x, S2x, SAx, SBx, SCx, SDx, SEx, SFx, SGx, SHx, SIx))
2926 {
2927 static assert(!__traits(compiles, &check!Sx));
2928 }
2929 }
2930
2931 void test10055b()
2932 {
2933 static struct SX { pure nothrow @safe this(this) {} }
2934 static struct SY { pure nothrow @safe this(this) {} }
2935 static struct SZ { @disable this(this) {} }
2936
2937 // function to check merge result of the postblit attributes
2938 static void check(S)() { S s; S s2 = s; }
2939
2940 static struct S1 { }
2941 static struct S2 { this(this) {} }
2942 static struct SA { SX sx; SY sy; }
2943 static struct SB { SX sx; SY sy; pure nothrow @safe this(this) {} }
2944 static struct SC { SX sx; SY sy; nothrow @safe this(this) {} }
2945 static struct SD { SX sx; SY sy; pure @safe this(this) {} }
2946 static struct SE { SX sx; SY sy; pure nothrow this(this) {} }
2947 static struct SF { SX sx; SY sy; @safe this(this) {} }
2948 static struct SG { SX sx; SY sy; nothrow this(this) {} }
2949 static struct SH { SX sx; SY sy; pure this(this) {} }
2950 static struct SI { SX sx; SY sy; this(this) {} }
2951 static assert(is( typeof(&check!S1) == void function() pure nothrow @nogc @safe ));
2952 static assert(is( typeof(&check!S2) == void function() ));
2953 static assert(is( typeof(&check!SA) == void function() pure nothrow @safe ));
2954 static assert(is( typeof(&check!SB) == void function() pure nothrow @safe ));
2955 static assert(is( typeof(&check!SC) == void function() nothrow @safe ));
2956 static assert(is( typeof(&check!SD) == void function() pure @safe ));
2957 static assert(is( typeof(&check!SE) == void function() pure nothrow ));
2958 static assert(is( typeof(&check!SF) == void function() @safe ));
2959 static assert(is( typeof(&check!SG) == void function() nothrow ));
2960 static assert(is( typeof(&check!SH) == void function() pure ));
2961 static assert(is( typeof(&check!SI) == void function() ));
2962
2963 static struct S1x { SZ sz; }
2964 static struct S2x { this(this) {} SZ sz; }
2965 static struct SAx { SX sx; SY sy; SZ sz; }
2966 static struct SBx { SX sx; SY sy; pure nothrow @safe this(this) {} SZ sz; }
2967 static struct SCx { SX sx; SY sy; nothrow @safe this(this) {} SZ sz; }
2968 static struct SDx { SX sx; SY sy; pure @safe this(this) {} SZ sz; }
2969 static struct SEx { SX sx; SY sy; pure nothrow this(this) {} SZ sz; }
2970 static struct SFx { SX sx; SY sy; @safe this(this) {} SZ sz; }
2971 static struct SGx { SX sx; SY sy; nothrow this(this) {} SZ sz; }
2972 static struct SHx { SX sx; SY sy; pure this(this) {} SZ sz; }
2973 static struct SIx { SX sx; SY sy; this(this) {} SZ sz; }
2974 foreach (Sx; TypeTuple!(S1x, S2x, SAx, SBx, SCx, SDx, SEx, SFx, SGx, SHx, SIx))
2975 {
2976 static assert(!__traits(compiles, &check!Sx));
2977 }
2978 }
2979
2980 /**********************************/
2981 // 10160
2982
2983 struct S10160 { this(this) {} }
2984
2985 struct X10160a { S10160 s; const int x; }
2986 struct X10160b { S10160 s; enum int x = 1; }
2987
2988 void test10160()
2989 {
2990 X10160a xa;
2991 X10160b xb;
2992 }
2993
2994 /**********************************/
2995 // 10094
2996
2997 void test10094()
2998 {
2999 static void* p;
3000 const string[4] i2s = ()
3001 {
3002 string[4] tmp;
3003 p = &tmp[0];
3004 for (int i = 0; i < 4; ++i)
3005 {
3006 char[1] buf = [cast(char)('0' + i)];
3007 string str = buf.idup;
3008 tmp[i] = str;
3009 }
3010 return tmp; // NRVO should work
3011 }();
3012 assert(p == cast(void*)&i2s[0]);
3013 assert(i2s == ["0", "1", "2", "3"]);
3014 }
3015
3016 /**********************************/
3017 // 10079
3018
3019 // dtor || postblit
3020 struct S10079a
3021 {
3022 this(this) pure nothrow @safe {}
3023 }
3024 struct S10079b
3025 {
3026 ~this() pure nothrow @safe {}
3027 }
3028 struct S10079c
3029 {
3030 this(this) pure nothrow @safe {}
3031 ~this() pure nothrow @safe {}
3032 }
3033 struct S10079d
3034 {
3035 this(this) {}
3036 }
3037 struct S10079e
3038 {
3039 this(this) {}
3040 ~this() pure nothrow @safe {}
3041 }
3042
3043 // memberwise
3044 struct S10079f
3045 {
3046 S10079a a;
3047 S10079b b;
3048 S10079c c;
3049 S10079d d;
3050 S10079e e;
3051 }
3052
3053 void check10079(S)(ref S s) pure nothrow @safe { s = S(); }
3054
3055 // Assignment is pure, nothrow, and @safe in all cases.
3056 static assert(__traits(compiles, &check10079!S10079a));
3057 static assert(__traits(compiles, &check10079!S10079b));
3058 static assert(__traits(compiles, &check10079!S10079c));
3059 static assert(__traits(compiles, &check10079!S10079d));
3060 static assert(__traits(compiles, &check10079!S10079e));
3061 static assert(__traits(compiles, &check10079!S10079f));
3062
3063 /**********************************/
3064 // 10244
3065
3066 void test10244()
3067 {
3068 static struct Foo
3069 {
3070 string _str;
3071 long _num;
3072
3073 template DeclareConstructor(string fieldName)
3074 {
3075 enum code =
3076 `this(typeof(_` ~ fieldName ~ `) value)` ~
3077 `{ this._` ~ fieldName ~ ` = value; }`;
3078 mixin(code);
3079 }
3080
3081 mixin DeclareConstructor!"str";
3082 mixin DeclareConstructor!"num";
3083 }
3084
3085 Foo value1 = Foo("D");
3086 Foo value2 = Foo(128);
3087 assert(value1._str == "D");
3088 assert(value2._num == 128);
3089 }
3090
3091 /**********************************/
3092 // 10694
3093
3094 struct Foo10694 { ~this() { } }
3095
3096 void test10694() pure
3097 {
3098 static Foo10694 i1;
3099 __gshared Foo10694 i2;
3100 void foo() pure
3101 {
3102 static Foo10694 j1;
3103 __gshared Foo10694 j2;
3104 }
3105 }
3106
3107 /**********************************/
3108 // 10787
3109
3110 int global10787;
3111
3112 static ~this() nothrow pure @safe
3113 {
3114 int* p;
3115 static assert(!__traits(compiles, ++p));
3116 static assert(!__traits(compiles, ++global10787));
3117 }
3118
3119 shared static ~this() nothrow pure @safe
3120 {
3121 int* p;
3122 static assert(!__traits(compiles, ++p));
3123 static assert(!__traits(compiles, ++global10787));
3124 }
3125
3126 /**********************************/
3127 // 10789
3128
3129 struct S10789
3130 {
3131 static int count;
3132 int value;
3133
3134 this(int) { value = ++count; }
3135 ~this() { --count; }
3136 this(this) { value = ++count; assert(value == 3); }
3137 }
3138
3139 S10789 fun10789a(bool isCondExp)(bool cond)
3140 {
3141 S10789 s1 = S10789(42), s2 = S10789(24);
3142 assert(S10789.count == 2);
3143 static if (isCondExp)
3144 {
3145 return cond ? s1 : s2;
3146 }
3147 else
3148 {
3149 if (cond)
3150 return s1;
3151 else
3152 return s2;
3153 }
3154 }
3155
3156 auto fun10789b(bool isCondExp)(bool cond)
3157 {
3158 S10789 s1 = S10789(42), s2 = S10789(24);
3159 assert(S10789.count == 2);
3160 static if (isCondExp)
3161 {
3162 return cond ? s1 : s2;
3163 }
3164 else
3165 {
3166 if (cond)
3167 return s1;
3168 else
3169 return s2;
3170 }
3171 }
3172
3173 void test10789()
3174 {
3175 foreach (fun; TypeTuple!(fun10789a, fun10789b))
3176 foreach (isCondExp; TypeTuple!(false, true))
3177 {
3178 {
3179 S10789 s = fun!isCondExp(true);
3180 assert(S10789.count == 1);
3181 assert(s.value == 3);
3182 }
3183 assert(S10789.count == 0);
3184 {
3185 S10789 s = fun!isCondExp(false);
3186 assert(S10789.count == 1);
3187 assert(s.value == 3);
3188 }
3189 assert(S10789.count == 0);
3190 }
3191 }
3192
3193 /**********************************/
3194 // 10972
3195
3196 int test10972()
3197 {
3198 string result;
3199
3200 struct A
3201 {
3202 this(this) { result ~= "pA"; version(none) printf("copied A\n"); }
3203 ~this() { result ~= "dA"; version(none) printf("destroy A\n"); }
3204 }
3205 struct B
3206 {
3207 this(this)
3208 {
3209 result ~= "(pB)"; version(none) printf("B says what?\n");
3210 throw new Exception("BOOM!");
3211 }
3212 ~this() { result ~= "dB"; version(none) printf("destroy B\n"); }
3213 }
3214 struct S
3215 {
3216 A a;
3217 B b;
3218 }
3219
3220 result = "{";
3221 {
3222 S s1;
3223 result ~= "[";
3224 try
3225 {
3226 S s3 = s1;
3227 assert(0);
3228 }
3229 catch (Exception e)
3230 {}
3231 result ~= "]";
3232 }
3233 result ~= "}";
3234 assert(result == "{[pA(pB)dA]dBdA}", result);
3235
3236 result = "{";
3237 {
3238 S s1;
3239 S s2;
3240 result ~= "[";
3241 try
3242 {
3243 s2 = s1;
3244 assert(0);
3245 }
3246 catch (Exception e)
3247 {}
3248 result ~= "]";
3249 }
3250 result ~= "}";
3251 assert(result == "{[pA(pB)dA]dBdAdBdA}", result);
3252
3253 return 1;
3254 }
3255 static assert(test10972()); // CTFE
3256
3257 /**********************************/
3258 // 11134
3259
3260 void test11134()
3261 {
3262 void test(S)()
3263 {
3264 S s;
3265 S[2] sa;
3266 S[2][] dsa = [[S(), S()]];
3267 dsa.reserve(dsa.length + 2); // avoid postblit calls by GC
3268
3269 S.count = 0;
3270 dsa ~= sa;
3271 assert(S.count == 2);
3272
3273 S.count = 0;
3274 dsa ~= [s, s];
3275 assert(S.count == 2);
3276 }
3277
3278 static struct SS
3279 {
3280 static int count;
3281 this(this) { ++count; }
3282 }
3283 test!SS();
3284
3285 struct NS
3286 {
3287 static int count;
3288 this(this) { ++count; }
3289 }
3290 test!NS();
3291 }
3292
3293 /**********************************/
3294 // 11197
3295
3296 struct S11197a
3297 {
3298 this(bool) {}
3299 this(this) {}
3300 }
3301
3302 struct S11197b
3303 {
3304 //this(bool) {}
3305 this(this) {}
3306 }
3307
3308 void test11197()
3309 {
3310 S11197a[][string] aa1;
3311 aa1["test"] ~= S11197a.init;
3312
3313 S11197b[][string] aa2;
3314 aa2["test"] ~= S11197b.init;
3315 }
3316
3317 /**********************************/
3318
3319 struct S7474 {
3320 float x;
3321 ~this() {}
3322 }
3323
3324 void fun7474(T...)() { T x; }
3325 void test7474() { fun7474!S7474(); }
3326
3327 /**********************************/
3328 // 11286
3329
3330 struct A11286
3331 {
3332 ~this() {}
3333 }
3334
3335 A11286 getA11286() pure nothrow
3336 {
3337 return A11286();
3338 }
3339
3340 void test11286()
3341 {
3342 A11286 a = getA11286();
3343 }
3344
3345 /**********************************/
3346 // 11505
3347
3348 struct Foo11505
3349 {
3350 Bar11505 b;
3351 }
3352
3353 struct Bar11505
3354 {
3355 ~this() @safe { }
3356 void* p;
3357 }
3358
3359 void test11505()
3360 {
3361 Foo11505 f;
3362 f = Foo11505();
3363 }
3364
3365 /**********************************/
3366 // 12045
3367
3368 bool test12045()
3369 {
3370 string dtor;
3371 void* ptr;
3372
3373 struct S12045
3374 {
3375 string val;
3376
3377 this(this) { assert(0); }
3378 ~this() { dtor ~= val; }
3379 }
3380
3381 auto makeS12045(bool thrown)
3382 {
3383 auto s1 = S12045("1");
3384 auto s2 = S12045("2");
3385 ptr = &s1;
3386
3387 if (thrown)
3388 throw new Exception("");
3389
3390 return s1; // NRVO
3391 }
3392
3393 dtor = null, ptr = null;
3394 try
3395 {
3396 S12045 s = makeS12045(true);
3397 assert(0);
3398 }
3399 catch (Exception e)
3400 {
3401 assert(dtor == "21", dtor);
3402 }
3403
3404 dtor = null, ptr = null;
3405 {
3406 S12045 s = makeS12045(false);
3407 assert(dtor == "2");
3408 if (!__ctfe) assert(ptr is &s); // NRVO
3409 }
3410 assert(dtor == "21");
3411
3412 return true;
3413 }
3414 static assert(test12045());
3415
3416 /**********************************/
3417 // 12591
3418
3419 struct S12591(T)
3420 {
3421 this(this)
3422 {}
3423 }
3424
3425 struct Tuple12591(Types...)
3426 {
3427 Types expand;
3428 this(Types values)
3429 {
3430 expand[] = values[];
3431 }
3432 }
3433
3434 void test12591()
3435 {
3436 alias T1 = Tuple12591!(S12591!int);
3437 }
3438
3439 /**********************************/
3440 // 12660
3441
3442 struct X12660
3443 {
3444 this(this) @nogc {}
3445 ~this() @nogc {}
3446 void opAssign(X12660) @nogc {}
3447 @nogc invariant() {}
3448 }
3449 struct Y12660
3450 {
3451 X12660 x;
3452
3453 this(this) @nogc {}
3454 ~this() @nogc {}
3455 @nogc invariant() {}
3456 }
3457 struct Z12660
3458 {
3459 Y12660 y;
3460 }
3461
3462 class C12660
3463 {
3464 this() @nogc {}
3465 @nogc invariant() {}
3466 }
3467
3468 void test12660() @nogc
3469 {
3470 X12660 x;
3471 x = x;
3472
3473 Y12660 y = { x };
3474 y = y;
3475
3476 Z12660 z = { y };
3477 z = z;
3478 }
3479
3480 /**********************************/
3481 // 12686
3482
3483 struct Foo12686
3484 {
3485 static int count;
3486
3487 invariant() { ++count; }
3488
3489 @disable this(this);
3490
3491 Foo12686 bar()
3492 {
3493 Foo12686 f;
3494 return f;
3495 }
3496 }
3497
3498 void test12686()
3499 {
3500 Foo12686 f;
3501 Foo12686 f2 = f.bar();
3502 version (unittest)
3503 { }
3504 else
3505 assert(Foo12686.count == 2);
3506 }
3507
3508 /**********************************/
3509 // 13089
3510
3511 struct S13089
3512 {
3513 @disable this(this); // non nothrow
3514 int val;
3515 }
3516
3517 void* p13089;
3518
3519 S13089[1000] foo13089() nothrow
3520 {
3521 typeof(return) data;
3522 p13089 = &data;
3523 return data;
3524 }
3525
3526 void test13089() nothrow
3527 {
3528 immutable data = foo13089();
3529 assert(p13089 == &data);
3530 }
3531
3532 /**********************************/
3533
3534 struct NoDtortest11763 {}
3535
3536 struct HasDtortest11763
3537 {
3538 NoDtortest11763 func()
3539 {
3540 return NoDtortest11763();
3541 }
3542 ~this() {}
3543 }
3544
3545 void test11763()
3546 {
3547 HasDtortest11763().func();
3548 }
3549
3550 /**********************************/
3551
3552 struct Buf { }
3553
3554 struct Variant
3555 {
3556 ~this() { }
3557
3558 Buf get() { Buf b; return b; }
3559 }
3560
3561 Variant value() { Variant v; return v; }
3562
3563 void test13303()
3564 {
3565 value.get();
3566 }
3567
3568 /**********************************/
3569
3570 struct S13673
3571 {
3572 string _name;
3573 ~this() {}
3574 }
3575
3576 string name13673;
3577
3578 void test13673()
3579 {
3580 S13673(name13673);
3581 S13673(name13673);
3582 }
3583
3584 /**********************************/
3585
3586 void test13586()
3587 {
3588 static struct S {
3589 __gshared int count;
3590 ~this() { ++count; printf("~S\n"); }
3591 }
3592
3593 static struct T {
3594 __gshared int count;
3595 ~this() { ++count; printf("~T\n"); }
3596 }
3597
3598 static int foo(bool flag)
3599 {
3600 if (flag)
3601 throw new Exception("hello");
3602 return 1;
3603 }
3604
3605 static void func(S s, int f, T t)
3606 {
3607 printf("func()\n");
3608 }
3609
3610 static class C
3611 {
3612 this(S s, int f, T t)
3613 {
3614 printf("C()\n");
3615 }
3616 }
3617
3618 {
3619 bool threw = false;
3620 try
3621 {
3622 func(S(), foo(true), T());
3623 printf("not reach\n");
3624 }
3625 catch (Exception e)
3626 {
3627 threw = true;
3628 }
3629 printf("threw %d S %d T %d\n", threw, S.count, T.count);
3630 assert(threw && S.count == 1 && T.count == 0);
3631 S.count = 0;
3632 T.count = 0;
3633 }
3634 {
3635 bool threw = false;
3636 try
3637 {
3638 func(S(), foo(false), T());
3639 printf("reached\n");
3640 }
3641 catch (Exception e)
3642 {
3643 threw = true;
3644 }
3645 printf("threw %d S %d T %d\n", threw, S.count, T.count);
3646 assert(!threw && S.count == 1 && T.count == 1);
3647 S.count = 0;
3648 T.count = 0;
3649 }
3650 {
3651 bool threw = false;
3652 try
3653 {
3654 new C(S(), foo(true), T());
3655 printf("not reach\n");
3656 }
3657 catch (Exception e)
3658 {
3659 threw = true;
3660 }
3661 printf("threw %d S %d T %d\n", threw, S.count, T.count);
3662 assert(threw && S.count == 1 && T.count == 0);
3663 S.count = 0;
3664 T.count = 0;
3665 }
3666 }
3667
3668 /**********************************/
3669 // 14443
3670
3671 T enforce14443(E : Throwable = Exception, T)(T value)
3672 {
3673 if (!value)
3674 throw new E("Enforcement failed");
3675 return value;
3676 }
3677
3678 struct RefCounted14443(T)
3679 if (!is(T == class) && !(is(T == interface)))
3680 {
3681 struct RefCountedStore
3682 {
3683 private struct Impl
3684 {
3685 T _payload;
3686 size_t _count;
3687 }
3688
3689 private Impl* _store;
3690
3691 private void initialize(A...)(auto ref A args)
3692 {
3693 import core.stdc.stdlib : malloc;
3694
3695 // enforce is necessary
3696 _store = cast(Impl*) enforce14443(malloc(Impl.sizeof));
3697
3698 // emulate 'emplace'
3699 static if (args.length > 0)
3700 _store._payload.tupleof = args;
3701 else
3702 _store._payload = T.init;
3703
3704 _store._count = 1;
3705 }
3706
3707 @property bool isInitialized() const nothrow @safe
3708 {
3709 return _store !is null;
3710 }
3711
3712 void ensureInitialized()
3713 {
3714 if (!isInitialized) initialize();
3715 }
3716
3717 }
3718 RefCountedStore _refCounted;
3719
3720 this(A...)(auto ref A args) if (A.length > 0)
3721 {
3722 _refCounted.initialize(args);
3723 }
3724
3725 this(this)
3726 {
3727 if (!_refCounted.isInitialized)
3728 return;
3729 ++_refCounted._store._count;
3730 //printf("RefCounted count = %d (inc)\n", _refCounted._store._count);
3731 }
3732
3733 ~this()
3734 {
3735 if (!_refCounted.isInitialized)
3736 return;
3737 assert(_refCounted._store._count > 0);
3738 if (--_refCounted._store._count)
3739 {
3740 //printf("RefCounted count = %u\n", _refCounted._store._count);
3741 return;
3742 }
3743
3744 import core.stdc.stdlib : free;
3745 free(_refCounted._store);
3746 _refCounted._store = null;
3747 }
3748
3749 void opAssign(typeof(this) rhs) { assert(0); }
3750 void opAssign(T rhs) { assert(0); }
3751
3752 @property ref T refCountedPayload()
3753 {
3754 _refCounted.ensureInitialized();
3755 return _refCounted._store._payload;
3756 }
3757
3758 alias refCountedPayload this;
3759 }
3760
3761 struct Path14443
3762 {
3763 struct Payload
3764 {
3765 int p;
3766 }
3767 RefCounted14443!Payload data;
3768 }
3769
3770 struct PathRange14443
3771 {
3772 Path14443 path;
3773 size_t i;
3774
3775 @property PathElement14443 front()
3776 {
3777 return PathElement14443(this, path.data.p);
3778 }
3779 }
3780
3781 struct PathElement14443
3782 {
3783 PathRange14443 range;
3784
3785 this(PathRange14443 range, int)
3786 {
3787 this.range = range;
3788 }
3789 }
3790
3791 void test14443()
3792 {
3793 auto path = Path14443(RefCounted14443!(Path14443.Payload)(12));
3794 assert(path.data.p == 12);
3795
3796 @property refCount() { return path.data._refCounted._store._count; }
3797 assert(refCount == 1);
3798
3799 {
3800 auto _r = PathRange14443(path);
3801 assert(refCount == 2);
3802 // foreach
3803 {
3804 auto element = _r.front;
3805 assert(refCount == 3); // fail with 2.067
3806 }
3807 assert(refCount == 2);
3808 }
3809 assert(refCount == 1);
3810 }
3811
3812 /**********************************/
3813 // 13661, 14022, 14023 - postblit/dtor call on static array assignment
3814
3815 bool test13661()
3816 {
3817 string op;
3818
3819 struct S
3820 {
3821 char x = 'x';
3822 this(this) { op ~= x-0x20; } // upper case
3823 ~this() { op ~= x; } // lower case
3824
3825 ref auto opAssign(T)(T arg)
3826 {
3827 assert(0);
3828 return this;
3829 }
3830 }
3831
3832 {
3833 S[2] a;
3834
3835 a[0].x = 'a';
3836 a[1].x = 'b';
3837 a = a.init;
3838 assert(op == "ab");
3839 assert(a[0].x == 'x' && a[1].x == 'x');
3840
3841 a[0].x = 'c';
3842 a[1].x = 'd';
3843 a = [S(), S()]; // equivalent a = a.init
3844 assert(op == "abcd");
3845 assert(a[0].x == 'x' && a[1].x == 'x');
3846 }
3847 assert(op == "abcdxx");
3848
3849 return true;
3850 }
3851 bool test13661a()
3852 {
3853 string op;
3854
3855 struct S
3856 {
3857 char x = 'x';
3858 this(this) { op ~= x-0x20; } // upper case
3859 ~this() { op ~= x; } // lower case
3860 }
3861
3862 {
3863 S[3] sa = [S('a'), S('b'), S('c')];
3864 S[2] sb = sa[1..3];
3865 assert(sa == [S('a'), S('b'), S('c')]);
3866 assert(sb == [S('b'), S('c')]);
3867 sb[0].x = 'x';
3868 sb[1].x = 'y';
3869 assert(sa != [S('a'), S('x'), S('y')]); // OK <- incorrectly fails
3870 assert(sa == [S('a'), S('b'), S('c')]); // OK <- incorrectly fails
3871 assert(sb == [S('x'), S('y')]);
3872 }
3873 return true;
3874 }
3875 static assert(test13661()); // CTFE
3876 static assert(test13661a());
3877
3878 bool test14022()
3879 {
3880 string op;
3881
3882 struct S
3883 {
3884 char x = 'x';
3885 this(this) { op ~= x-0x20; } // upper case
3886 ~this() { op ~= x; } // lower case
3887 }
3888
3889 S[2] makeSA() { return [S('p'), S('q')]; }
3890
3891 struct T
3892 {
3893 S[2] sb;
3894
3895 this(ref S[2] sa)
3896 {
3897 assert(op == "");
3898 this.sb = sa; // TOKconstruct
3899 assert(op == "BC", op);
3900 assert(sb == [S('b'), S('c')]);
3901 }
3902 void test(ref S[2] sa)
3903 {
3904 this.sb = sa; // dotvar: resolveSlice(newva)
3905 assert(op == "BxCy");
3906 }
3907 }
3908
3909 op = null;
3910 {
3911 S[2] sa = [S('a'), S('b')];
3912 T t; t.sb[0].x = 'x';
3913 t.sb[1].x = 'y';
3914 assert(op == "");
3915 t.sb = sa;
3916 assert(op == "AxBy");
3917 t.sb = makeSA();
3918 assert(op == "AxByab");
3919 }
3920 assert(op == "AxByabqpba");
3921
3922 op = null;
3923 {
3924 S[3] sa = [S('a'), S('b'), S('c')];
3925 T t = T(sa[1..3]);
3926 t.sb[0].x = 'x';
3927 t.sb[1].x = 'y';
3928 assert(sa == [S('a'), S('b'), S('c')]);
3929 assert(t.sb == [S('x'), S('y')]);
3930 assert(op == "BC");
3931 }
3932 assert(op == "BCyxcba");
3933
3934 op = null;
3935 {
3936 S[3] sx = [S('a'), S('b'), S('c')];
3937 T t; t.sb[0].x = 'x';
3938 t.sb[1].x = 'y';
3939 t.test(sx[1..3]);
3940 assert(op == "BxCy");
3941 assert(t.sb == [S('b'), S('c')]);
3942 }
3943 assert(op == "BxCycbcba");
3944
3945 return true;
3946 }
3947 static assert(test14022());
3948
3949 bool test14023()
3950 {
3951 string op;
3952
3953 struct S
3954 {
3955 char x = 'x';
3956 this(this) { op ~= x-0x20; } // upper case
3957 ~this() { op ~= x; } // lower case
3958 }
3959
3960 S[2] makeSA() { return [S('p'), S('q')]; }
3961
3962 struct T
3963 {
3964 S[2][1] sb;
3965 this(ref S[2] sa)
3966 {
3967 assert(op == "");
3968 this.sb[0] = sa; // TOKconstruct
3969 assert(sa == [S('b'), S('c')]);
3970 assert(sb[0] == [S('b'), S('c')]);
3971 }
3972 }
3973
3974 void test(ref S[2] sa)
3975 {
3976 S[2][] a;
3977 //a.length = 1; // will cause runtine AccessViolation
3978 a ~= (S[2]).init;
3979 assert(op == "");
3980 a[0] = sa; // index <-- resolveSlice(newva)
3981 assert(op == "BxCx");
3982 assert(a[0] == [S('b'), S('c')]);
3983 }
3984
3985 op = null;
3986 {
3987 S[3] sa = [S('a'), S('b'), S('c')];
3988 T t = T(sa[1..3]);
3989 t.sb[0][0].x = 'x';
3990 t.sb[0][1].x = 'y';
3991 assert(sa != [S('a'), S('x'), S('y')]); // OK <- incorrectly fails
3992 assert(sa == [S('a'), S('b'), S('c')]); // OK <- incorrectly fails
3993 assert(t.sb[0] == [S('x'), S('y')]);
3994 }
3995
3996 op = null;
3997 {
3998 S[2] sa = [S('a'), S('b')];
3999 S[2][] a = [[S('x'), S('y')]];
4000 assert(op == "");
4001 a[0] = sa;
4002 assert(op == "AxBy");
4003 a[0] = makeSA();
4004 assert(op == "AxByab");
4005 }
4006 assert(op == "AxByabba");
4007
4008 op = null;
4009 {
4010 S[3] sa = [S('a'), S('b'), S('c')];
4011 test(sa[1..3]);
4012 assert(op == "BxCx");
4013 }
4014 assert(op == "BxCxcba");
4015
4016 return true;
4017 }
4018 static assert(test14023());
4019
4020 /************************************************/
4021 // 13669 - dtor call on static array variable
4022
4023 bool test13669()
4024 {
4025 string dtor;
4026
4027 struct S
4028 {
4029 char x = 'x';
4030 ~this() { dtor ~= x; }
4031 }
4032
4033 { S[2] a; }
4034 assert(dtor == "xx");
4035 dtor = "";
4036
4037 { S[2] a = [S('a'), S('b')]; }
4038 assert(dtor == "ba"); // reverse order. See also: TypeInfo_StaticArray.destroy()
4039
4040 return true;
4041 }
4042 static assert(test13669());
4043
4044 /**********************************/
4045
4046 __gshared bool b13095 = false;
4047
4048 void bar13095() { throw new Exception(""); }
4049
4050 struct S13095
4051 {
4052 this(int) { printf("ctor %p\n", &this); bar13095(); }
4053
4054 ~this() { b13095 = true; printf("dtor %p\n", &this); }
4055 }
4056
4057 void test13095()
4058 {
4059 try {
4060 S13095(0);
4061 } catch(Exception) { printf("catch\n"); }
4062 assert(!b13095);
4063 }
4064
4065 /**********************************/
4066 // 14264
4067
4068 void test14264()
4069 {
4070 static int dtor;
4071 static struct Foo
4072 {
4073 ~this() { ++dtor; }
4074 T opCast(T:bool)() { return true; }
4075 }
4076
4077 Foo makeFoo()
4078 {
4079 return Foo();
4080 }
4081
4082 assert(dtor == 0);
4083
4084 makeFoo();
4085 assert(dtor == 1);
4086
4087 makeFoo;
4088 assert(dtor == 2);
4089
4090 if (makeFoo()) {}
4091 assert(dtor == 3);
4092
4093 if (makeFoo) {}
4094 assert(dtor == 4);
4095 }
4096
4097 /**********************************/
4098 // 14686
4099
4100 int test14686()
4101 {
4102 string r;
4103
4104 struct S
4105 {
4106 int n;
4107 this(this) { r ~= cast(char)('0' + n); }
4108 }
4109
4110 S s1 = S(1);
4111 S s2 = S(2);
4112 S[] a1 = [S(1)];
4113
4114 S[2] sa1 = [s1, s2];
4115 assert(r == "12", r); // OK
4116
4117 r = "";
4118 S[] a2 = a1 ~ s2; // runtime concatenation
4119 assert(r == "12", r); // OK <- NG only in CTFE
4120
4121 r = "";
4122 S[2] sa2a = [s1] ~ s2;
4123 assert(r == "12", r); // OK <- NG, s2 is not copied
4124
4125 r = "";
4126 S[2] sa2b = s2 ~ [s1];
4127 assert(r == "21", r); // OK <- NG, s2 is not copied
4128
4129 r = "";
4130 S[3] sa3a = ([s1] ~ [s1]) ~ s2;
4131 assert(r == "112", r); // OK <- NG, s2 is not copied
4132
4133 r = "";
4134 S[3] sa3b = s2 ~ ([s1] ~ [s1]);
4135 assert(r == "211", r); // OK <- NG, s2 is not copied
4136
4137 return 1;
4138 }
4139 static assert(test14686());
4140
4141 /**********************************/
4142 // 14815
4143
4144 int test14815()
4145 {
4146 uint dtorCount;
4147
4148 struct S
4149 {
4150 uint x;
4151 ~this() { ++dtorCount; }
4152 }
4153
4154 S[2] sa1;
4155 sa1[0].x = 42;
4156 sa1 = (S[2]).init; // S[2] <- rvalue
4157 assert(sa1[0].x == 0);
4158 assert(dtorCount == 2);
4159
4160 S[2] sa2;
4161 sa2[0].x = 42;
4162 S[] da2 = sa2[];
4163 da2[] = (S[2]).init[]; // S[] <- rvalue slice
4164 assert(sa2[0].x == 0);
4165 assert(dtorCount == 4);
4166
4167 S[2] sa3;
4168 S[2] sa4;
4169 sa3[0].x = 42;
4170 sa3 = sa4; // S[2] <- lvalue
4171 assert(sa3[0].x == 0);
4172 assert(dtorCount == 6);
4173
4174 S[2] sa5;
4175 S[] da4 = sa4[];
4176 da4[] = sa5[]; // S[] <- lvalue slice
4177 assert(sa4[0].x == 0);
4178 assert(dtorCount == 8);
4179
4180 return 1;
4181 }
4182 static assert(test14815());
4183
4184 /**********************************/
4185 // https://issues.dlang.org/show_bug.cgi?id=16197
4186
4187 struct Elem {
4188 static string r;
4189 int x = -1;
4190 this(this) { r ~= 'p'; printf("POSTBLIT %d\n", x++); }
4191 ~this() { r ~= 'd'; printf("DTOR %d\n" , x++); }
4192 }
4193
4194 struct Ctr {
4195 Elem[3] arr;
4196 }
4197
4198 void test16197() {
4199 { auto p = Ctr(); }
4200 assert(Elem.r == "ddd");
4201 }
4202
4203 /**********************************/
4204 // 14860
4205
4206 int test14860()
4207 {
4208 uint dtorCount;
4209
4210 struct S
4211 {
4212 uint x;
4213 ~this() { ++dtorCount; }
4214 }
4215
4216 S[] a = [S(42)];
4217 a[] = S();
4218
4219 assert(a[0].x == 0);
4220 assert(dtorCount == 1);
4221
4222 return 1;
4223 }
4224 static assert(test14860());
4225
4226 /**********************************/
4227 // 14696
4228
4229 void test14696(int len = 2)
4230 {
4231 string result;
4232
4233 struct S
4234 {
4235 int n;
4236
4237 void* get(void* p = null)
4238 {
4239 result ~= "get(" ~ cast(char)(n+'0') ~ ").";
4240 return null;
4241 }
4242
4243 ~this()
4244 {
4245 result ~= "dtor(" ~ cast(char)(n+'0') ~ ").";
4246 }
4247 }
4248
4249 S makeS(int n)
4250 {
4251 result ~= "makeS(" ~ cast(char)(n+'0') ~ ").";
4252 return S(n);
4253 }
4254 void foo(void* x, void* y = null)
4255 {
4256 result ~= "foo.";
4257 }
4258 void fooThrow(void* x, void* y = null)
4259 {
4260 result ~= "fooThrow.";
4261 throw new Exception("fail!");
4262 }
4263
4264 void check(void delegate() dg, string r, string file = __FILE__, size_t line = __LINE__)
4265 {
4266 import core.exception;
4267
4268 result = null;
4269 try { dg(); } catch (Exception e) {}
4270 if (result != r)
4271 throw new AssertError(result, file, line);
4272 }
4273
4274 // temporary in condition
4275 check({ foo(len == 2 ? makeS(1).get() : null); }, "makeS(1).get(1).foo.dtor(1).");
4276 check({ foo(len == 2 ? null : makeS(1).get() ); }, "foo.");
4277 check({ foo(len != 2 ? makeS(1).get() : null); }, "foo.");
4278 check({ foo(len != 2 ? null : makeS(1).get() ); }, "makeS(1).get(1).foo.dtor(1).");
4279
4280 // temporary in nesting conditions
4281 check({ foo(len >= 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "makeS(1).get(1).foo.dtor(1).");
4282 check({ foo(len >= 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "foo.");
4283 check({ foo(len >= 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "foo.");
4284 check({ foo(len >= 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "makeS(1).get(1).foo.dtor(1).");
4285 check({ foo(len >= 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "foo.");
4286 check({ foo(len >= 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "foo.");
4287 check({ foo(len >= 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "foo.");
4288 check({ foo(len >= 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "foo.");
4289 check({ foo(len > 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "foo.");
4290 check({ foo(len > 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "foo.");
4291 check({ foo(len > 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "foo.");
4292 check({ foo(len > 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "foo.");
4293 check({ foo(len > 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "makeS(1).get(1).foo.dtor(1).");
4294 check({ foo(len > 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "foo.");
4295 check({ foo(len > 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "foo.");
4296 check({ foo(len > 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "makeS(1).get(1).foo.dtor(1).");
4297
4298 // temporary in condition and throwing callee
4299 // check({ fooThrow(len == 2 ? makeS(1).get() : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
4300 // check({ fooThrow(len == 2 ? null : makeS(1).get() ); }, "fooThrow.");
4301 // check({ fooThrow(len != 2 ? makeS(1).get() : null); }, "fooThrow.");
4302 // check({ fooThrow(len != 2 ? null : makeS(1).get() ); }, "makeS(1).get(1).fooThrow.dtor(1).");
4303
4304 // temporary in nesting condititions and throwing callee
4305 // check({ fooThrow(len >= 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
4306 // check({ fooThrow(len >= 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "fooThrow.");
4307 // check({ fooThrow(len >= 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "fooThrow.");
4308 // check({ fooThrow(len >= 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "makeS(1).get(1).fooThrow.dtor(1).");
4309 // check({ fooThrow(len >= 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "fooThrow.");
4310 // check({ fooThrow(len >= 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "fooThrow.");
4311 // check({ fooThrow(len >= 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "fooThrow.");
4312 // check({ fooThrow(len >= 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "fooThrow.");
4313 // check({ fooThrow(len > 2 ? (len == 2 ? makeS(1).get() : null) : null); }, "fooThrow.");
4314 // check({ fooThrow(len > 2 ? (len == 2 ? null : makeS(1).get() ) : null); }, "fooThrow.");
4315 // check({ fooThrow(len > 2 ? (len != 2 ? makeS(1).get() : null) : null); }, "fooThrow.");
4316 // check({ fooThrow(len > 2 ? (len != 2 ? null : makeS(1).get() ) : null); }, "fooThrow.");
4317 // check({ fooThrow(len > 2 ? null : (len == 2 ? makeS(1).get() : null) ); }, "makeS(1).get(1).fooThrow.dtor(1).");
4318 // check({ fooThrow(len > 2 ? null : (len == 2 ? null : makeS(1).get() ) ); }, "fooThrow.");
4319 // check({ fooThrow(len > 2 ? null : (len != 2 ? makeS(1).get() : null) ); }, "fooThrow.");
4320 // check({ fooThrow(len > 2 ? null : (len != 2 ? null : makeS(1).get() ) ); }, "makeS(1).get(1).fooThrow.dtor(1).");
4321
4322 // temporaries in each conditions
4323 check({ foo(len == 2 ? makeS(1).get() : null, len == 2 ? makeS(2).get() : null); }, "makeS(1).get(1).makeS(2).get(2).foo.dtor(2).dtor(1).");
4324 check({ foo(len == 2 ? makeS(1).get() : null, len != 2 ? makeS(2).get() : null); }, "makeS(1).get(1).foo.dtor(1).");
4325 check({ foo(len != 2 ? makeS(1).get() : null, len == 2 ? makeS(2).get() : null); }, "makeS(2).get(2).foo.dtor(2).");
4326 check({ foo(len != 2 ? makeS(1).get() : null, len != 2 ? makeS(2).get() : null); }, "foo.");
4327
4328 // nesting temporaries in conditions
4329 check({ foo(len == 2 ? makeS(1).get(len == 2 ? makeS(2).get() : null) : null); }, "makeS(1).makeS(2).get(2).get(1).foo.dtor(2).dtor(1).");
4330 check({ foo(len == 2 ? makeS(1).get(len != 2 ? makeS(2).get() : null) : null); }, "makeS(1).get(1).foo.dtor(1).");
4331 check({ foo(len != 2 ? makeS(1).get(len == 2 ? makeS(2).get() : null) : null); }, "foo.");
4332 check({ foo(len != 2 ? makeS(1).get(len != 2 ? makeS(2).get() : null) : null); }, "foo.");
4333 }
4334
4335 /**********************************/
4336 // 14838
4337
4338 int test14838() pure nothrow @safe
4339 {
4340 int dtor;
4341
4342 struct S14838(T)
4343 {
4344 ~this() { ++dtor; }
4345 }
4346 struct X14838
4347 {
4348 S14838!int ms;
4349 const S14838!int cs;
4350
4351 S14838!int[2] ma;
4352 const S14838!int[2] ca;
4353
4354 S14838!int[2][2] ma2x2;
4355 const S14838!int[2][2] ca2x2;
4356
4357 // number of S14838 = 1*2 + 2*2 + 4*2 = 14
4358 }
4359
4360 void test(Dg)(scope Dg code)
4361 {
4362 dtor = 0;
4363 code();
4364 }
4365
4366 test(delegate{ S14838!int a; }); assert(dtor == 1);
4367 test(delegate{ const S14838!int a; }); assert(dtor == 1);
4368
4369 test(delegate{ S14838!int[2] a; }); assert(dtor == 2);
4370 test(delegate{ const S14838!int[2] a; }); assert(dtor == 2);
4371
4372 test(delegate{ S14838!int[2][2] a; }); assert(dtor == 4);
4373 test(delegate{ const S14838!int[2][2] a; }); assert(dtor == 4);
4374
4375 test(delegate{ X14838 a; }); assert(dtor == 1 * 14);
4376 test(delegate{ const X14838 a; }); assert(dtor == 1 * 14);
4377
4378 test(delegate{ X14838[2] a; }); assert(dtor == 2 * 14);
4379 test(delegate{ const X14838[2] a; }); assert(dtor == 2 * 14);
4380
4381 test(delegate{ X14838[2][2] a; }); assert(dtor == 4 * 14);
4382 test(delegate{ const X14838[2][2] a; }); assert(dtor == 4 * 14);
4383
4384 return 1;
4385 }
4386 static assert(test14838());
4387
4388 /**********************************/
4389
4390 struct S63
4391 {
4392 private long p = 87;
4393
4394 this(int x)
4395 {
4396 assert(p == 87);
4397 p += x;
4398 }
4399
4400 ~this() { }
4401
4402 this(this) { }
4403
4404 void funky() { assert(p == 90); }
4405
4406 static void tester()
4407 {
4408 S63(3).funky();
4409 }
4410 }
4411
4412 void test63()
4413 {
4414 S63.tester();
4415 }
4416
4417 /**********************************/
4418
4419 struct X64
4420 {
4421 static int dtor;
4422
4423 ~this() { ++dtor; }
4424 }
4425
4426 struct S64
4427 {
4428 int n;
4429 long[10] dummy; // S64 needs to be passed by stack
4430 }
4431
4432 S64 foo64()
4433 {
4434 return S64((X64(), 1));
4435 }
4436
4437 void test64()
4438 {
4439 auto s = foo64();
4440 assert(X64.dtor == 1);
4441 }
4442
4443 /**********************************/
4444
4445 struct S65
4446 {
4447 static string t;
4448
4449 void bar(int a, int b)
4450 {
4451 t ~= "d";
4452 }
4453 }
4454
4455 S65 foo65a()
4456 {
4457 S65.t ~= "a";
4458 return S65();
4459 }
4460
4461 int foo65b()
4462 {
4463 S65.t ~= "b";
4464 return 1;
4465 }
4466
4467 int foo65c()
4468 {
4469 S65.t ~= "c";
4470 return 2;
4471 }
4472
4473 void test65()
4474 {
4475 import core.stdc.stdio;
4476 foo65a().bar(foo65b(), foo65c());
4477 printf("'%.*s'\n", cast(int)S65.t.length, S65.t.ptr);
4478 assert(S65.t == "abcd");
4479 }
4480
4481 /**********************************/
4482 // 15661
4483
4484 struct X15661
4485 {
4486 ~this() {}
4487 }
4488
4489 X15661 createX15661() { return X15661(); }
4490
4491 struct Y15661
4492 {
4493 static int dtor;
4494
4495 @disable this();
4496 @disable this(this);
4497 this(X15661 a1, X15661 a2) {}
4498 ~this() { ++dtor; }
4499 }
4500
4501 struct Z15661
4502 {
4503 this(int)
4504 {
4505 b = Y15661(createX15661(), createX15661());
4506 assert(Y15661.dtor == 0);
4507 }
4508
4509 private Y15661 b;
4510 }
4511
4512 void test15661()
4513 {
4514 {
4515 auto v = Z15661(5);
4516 assert(Y15661.dtor == 0);
4517 }
4518 assert(Y15661.dtor == 1);
4519 }
4520
4521 /**********************************/
4522
4523 int main()
4524 {
4525 test1();
4526 test2();
4527 test3();
4528 test4();
4529 test5();
4530 test6();
4531 test7();
4532 test8();
4533 test9();
4534 test10();
4535 test11();
4536 test12();
4537 test13();
4538 test14();
4539 test15();
4540 test16();
4541 test17();
4542 test18();
4543 test19();
4544 test20();
4545 test21();
4546 test22();
4547 test23();
4548 test24();
4549 test25();
4550 test26();
4551 test27();
4552 test28();
4553 test29();
4554 test30();
4555 test31();
4556 test32();
4557 test33();
4558 test34();
4559 test35();
4560 test36();
4561 test37();
4562 test38();
4563 test39();
4564 test40();
4565 test41();
4566 test42();
4567 test43();
4568 test44();
4569 test45();
4570 test46();
4571 test47();
4572 test48();
4573 test49();
4574 test50();
4575 test51();
4576 test52();
4577
4578 test54();
4579 test55();
4580 test56();
4581 test57();
4582 test58();
4583 test59();
4584 test5737();
4585 test6119();
4586 test8741();
4587 test6364();
4588 test6499();
4589 test60();
4590 test4316();
4591 test6177();
4592 test6470();
4593 test6636();
4594 test6637();
4595 test7353();
4596 test61();
4597 test7506();
4598 test7516a();
4599 test7516b();
4600 test7516c();
4601 test7516d();
4602 test7516e();
4603 test7530();
4604 test62();
4605 test7579a();
4606 test7579b();
4607 test8335();
4608 test8356();
4609 test9386();
4610 test9441();
4611 test9720();
4612 test9899();
4613 test9907();
4614 test9985();
4615 //test17457(); // XBUG: NRVO implementation differs
4616 test9994();
4617 test10094();
4618 test10244();
4619 test10694();
4620 test10789();
4621 test10972();
4622 test11134();
4623 test11197();
4624 test7474();
4625 test11505();
4626 test12045();
4627 test12591();
4628 test12660();
4629 test12686();
4630 test13089();
4631 test11763();
4632 test13303();
4633 test13673();
4634 test13586();
4635 test14443();
4636 test13661();
4637 test13661a();
4638 test14022();
4639 test14023();
4640 test13669();
4641 test13095();
4642 test14264();
4643 test14686();
4644 test14815();
4645 test16197();
4646 test14860();
4647 test14696();
4648 test14838();
4649 test63();
4650 test64();
4651 test65();
4652 test15661();
4653
4654 printf("Success\n");
4655 return 0;
4656 }
4657