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