1 // PERMUTE_ARGS: -unittest -O -release -inline -fPIC -g
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.
19 extern (C) int printf(const(char*) fmt, ...);
21 template TypeTuple(T...) { alias TypeTuple = T; }
23 /**********************************/
29 ~this() { printf("~S()\n"); sdtor++; }
39 /**********************************/
45 ~this() { printf("~S2()\n"); sdtor2++; }
46 delete(void* p) { assert(sdtor2 == 1); printf("S2.delete()\n"); sdtor2++; }
56 /**********************************/
62 ~this() { printf("~S3()\n"); sdtor3++; assert(a == 3); }
79 /**********************************/
101 ~this() { printf("~T4()\n"); assert(sdtor4 == 0); sdtor4++; }
113 /**********************************/
120 printf("~M5()\n"); assert(sdtor5 == 1); sdtor5++;
127 ~this() { printf("~T5()\n"); assert(sdtor5 == 0); sdtor5++; }
137 /**********************************/
145 printf("~S6()\n"); assert(b == 7); assert(sdtor6 == 1); sdtor6++;
153 ~this() { printf("~T6()\n"); assert(a == 3); assert(sdtor6 == 0); sdtor6++; }
163 /**********************************/
173 assert(sdtor7 >= 1 && sdtor7 <= 3);
183 { printf("~T7() %d\n", sdtor7);
197 /**********************************/
206 printf("~S8() %d\n", sdtor8);
223 /**********************************/
231 printf("~S9() %d\n", sdtor9);
245 /**********************************/
254 printf("~S10() %d\n", sdtor10);
256 assert(sdtor10 == c);
269 assert(sdtor10 == 3);
272 /**********************************/
279 printf("~M11()\n"); assert(sdtor11 == 1); sdtor11++;
286 ~this() { printf("~T11()\n"); assert(sdtor11 == 0); sdtor11++; }
293 assert(sdtor11 == 2);
296 /**********************************/
302 ~this() { printf("~S12() %d\n", sdtor12); sdtor12++; }
316 assert(sdtor12 == 2);
319 /**********************************/
325 printf("S13.opAssign(%p)\n", &this);
335 assert((s = t) == 5);
339 /**********************************/
343 int opAssign(ref S14 s)
345 printf("S14.opAssign(%p)\n", &this);
355 assert((s = t) == 5);
359 /**********************************/
363 int opAssign(ref const S15 s)
365 printf("S15.opAssign(%p)\n", &this);
375 assert((s = t) == 5);
379 /**********************************/
383 int opAssign(S16 s, ...)
385 printf("S16.opAssign(%p)\n", &this);
395 assert((s = t) == 5);
399 /**********************************/
405 printf("S17.opAssign(%p)\n", &this);
415 assert((s = t) == 5);
419 /**********************************/
423 int opAssign(S18 s, int x = 7)
425 printf("S18.opAssign(%p)\n", &this);
436 assert((s = t) == 5);
440 /**********************************/
445 this(this) { printf("this(this) %p\n", &this); }
446 ~this() { printf("~this() %p\n", &this); }
452 void bar() { s.a++; }
463 /**********************************/
469 this(this) { printf("this(this) %p\n", &this); r ~= '='; }
470 ~this() { printf("~this() %p\n", &this); r ~= '~'; }
479 assert(S20.r == "=~=~=~");
485 assert(S20.r == "=~=~=~~~~~");
489 /**********************************/
495 this(this) { printf("this(this) %p\n", &this); r ~= '='; }
496 ~this() { printf("~this() %p\n", &this); r ~= '~'; }
503 assert(S21.r == "===");
506 assert(S21.r == "======");
513 assert(S21.r == "~~~~~~~~~~");
517 /**********************************/
523 this(this) { printf("this(this) %p\n", &this); r ~= '='; }
524 ~this() { printf("~this() %p\n", &this); r ~= '~'; }
533 assert(S22.r == "===~~~===~~~");
540 assert(S22.r == "~~~~~~~~~");
545 /************************************************/
549 int m = 4, n, o, p, q;
553 printf("S23(%d)\n", x);
555 assert(m == 4 && n == 0 && o == 0 && p == 0 && q == 0);
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);
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);
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);
580 /************************************************/
588 printf("S24(%d)\n", x);
590 assert(m == 0 && n == 0 && o == 0 && p == 0 && q == 0);
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);
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);
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);
615 /**********************************/
627 /**********************************/
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; }
642 this(this) { printf("Copying B: %d\n", member.id); assert(0); }
663 /**********************************/
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; }
692 /**********************************/
700 printf("A's copy\n");
710 printf("B's copy\n");
723 /**********************************/
729 this(int i) { this(0.0); s29 ~= "i"; }
730 this(double d) { s29 ~= "d"; }
733 class C29 { mixin Templ29; }
734 struct S29 { mixin Templ29; }
742 assert(s29 == "did");
745 assert(s29 == "diddi");
747 auto c2 = new C29(2.0);
748 assert(s29 == "diddid");
751 /**********************************/
756 this(T)(T args) { x = args + 1; }
765 /**********************************/
770 this(T...)(T args) { x = args[0] + 1; }
779 /**********************************/
787 printf("ctor %p(%d)\n", &this, i);
793 printf("postblit %p\n", &this);
799 printf("dtor %p\n", &this);
823 assert(S32.x == 0x101);
829 assert(S32.x == 0x101);
832 /**********************************/
840 printf("ctor %p(%d)\n", &this, i);
846 printf("postblit %p\n", &this);
852 printf("dtor %p\n", &this);
873 printf("S.x = %x\n", S33.x);
874 assert(S33.x == 0x210);
877 /**********************************/
882 printf("postblit %p\n", &this);
887 printf("dtor %p\n", &this);
896 for (int j = 0; j < xs.length; j++) {
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);
905 printf("loop done\n");
908 /**********************************/
914 printf("postblit %p\n", &this);
919 printf("dtor %p\n", &this);
930 printf("foreach x.i = %d\n", x.i);
933 printf("loop done\n");
938 /**********************************/
944 printf("postblit %p\n", &this);
949 printf("dtor %p\n", &this);
960 printf("foreach x.i = %d\n", x.i);
963 printf("loop done\n");
968 /**********************************/
974 printf("postblit %p\n", &this);
979 printf("dtor %p\n", &this);
989 printf("foreach x.i = %d\n", x[0].i);
992 printf("loop done\n");
997 /**********************************/
1000 __gshared int count;
1001 __gshared int postblit;
1004 printf("this(%d)\n", x);
1005 assert(this.x == 0);
1010 printf("this(this) with %d\n", x);
1011 assert(x == 1 || x == 2);
1016 printf("~this(%d)\n", x);
1017 assert(x == 1 || x == 2);
1037 assert(S38.count == 1);
1038 assert(S38.postblit == 0);
1040 assert(S38.count == 0);
1045 assert(S38.count == 1);
1046 assert(S38.postblit == 0);
1048 assert(S38.count == 0);
1052 /**********************************/
1057 this(int v){ x = v + 1; }
1058 void opAssign(int v){
1074 /**********************************/
1076 bool approxEqual(float a, float b)
1078 return a < b ? b-a < .001 : a-b < .001;
1083 const bool opEquals(const ref Point rhs)
1085 return approxEqual(x, rhs.x) && approxEqual(y, rhs.y);
1090 Point leftBottom, rightTop;
1097 a.leftBottom.x = 1e-8;
1103 /**********************************/
1106 this(int) immutable { }
1111 auto s = new immutable S41(3);
1112 //writeln(typeid(typeof(s)));
1113 static assert(is(typeof(s) == immutable(S41)*));
1115 auto t = immutable S41(3);
1116 //writeln(typeid(typeof(t)));
1117 static assert(is(typeof(t) == immutable(S41)));
1120 /**********************************/
1123 this(int) immutable {
1129 static assert(!__traits(compiles, new C42(3)));
1130 //writeln(typeid(typeof(c)));
1131 //static assert(is(typeof(c) == immutable(C42)));
1133 auto d = new immutable(C42)(3);
1134 //writeln(typeid(typeof(d)));
1135 static assert(is(typeof(d) == immutable(C42)));
1138 /**********************************/
1143 // this(int i, int* t) immutable { this.i = i; p = t; }
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)));
1156 /**********************************/
1161 this(int i, immutable(int)* t) immutable { this.i = i; this.p = t; }
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)));
1174 /**********************************/
1178 this(int[] data) immutable {
1179 next = new immutable(C45)(data[1 .. $]);
1187 /**********************************/
1190 struct SiberianHamster
1198 SiberianHamster basil = "cybil";
1199 assert(basil.rat == 813);
1202 /**********************************/
1213 static Vec8741 zzz = Vec8741(7);
1218 assert(Vec8741.zzz.m[0] == 7);
1219 assert(Vec8741.zzz.m[1] == 58);
1222 /**********************************/
1235 assert(Segfault3984(3).a == 3);
1238 /**********************************/
1248 /**********************************/
1255 void bar49(Foo49 a = Foo49(1))
1266 /**********************************/
1277 void aFunc(aStruct a = aStruct(44))
1279 assert(a.m_Int == 44);
1285 aClass a = new aClass();
1290 /**********************************/
1296 ~this() { ++A51_a; }
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);
1322 /**********************************/
1331 printf("this(this) %p\n", &this);
1336 printf("~this() %p\n", &this);
1352 printf("a: %p, b: %p\n", &a, &b);
1354 printf("s = '%.*s'\n", s52.length, s52.ptr);
1355 assert(s52 == "cabb");
1358 /**********************************/
1364 void opAssign(A53 a) {}
1365 int blah(A53 a) { return 0; }
1368 /**********************************/
1374 int bar() { return x; }
1378 printf("ctor %p(%d)\n", &this, i);
1384 printf("postblit %p\n", &this);
1390 printf("dtor %p\n", &this);
1397 void bar54(S54 s) { }
1399 S54 abc54() { return S54(1); }
1406 assert(S54.t == "ac");
1411 assert(S54.t == "c");
1414 int b = 1 && (){ bar54(S54(1)); return 1;}();
1416 assert(S54.t == "ac");
1419 int b = 0 && (){ bar54(S54(1)); return 1;}();
1421 assert(S54.t == "");
1424 int b = 0 || (){ bar54(S54(1)); return 1;}();
1426 assert(S54.t == "ac");
1429 int b = 1 || (){ bar54(S54(1)); return 1;}();
1431 assert(S54.t == "");
1435 { const S54 s = S54(1); }
1436 assert(S54.t == "ac");
1441 assert(S54.t == "ac");
1446 assert(S54.t == "ac");
1450 /**********************************/
1456 assert(t.count == 1); // (5)
1462 this(this) { ++count; }
1463 S55 copy() { return this; }
1466 /**********************************/
1472 int bar() { return x; }
1476 printf("ctor %p(%d)\n", &this, i);
1482 printf("postblit %p\n", &this);
1488 printf("dtor %p\n", &this);
1497 throw new Throwable("hello");
1509 i = S56(1).x + foo56() + 1;
1517 printf("i = %d, j = %d\n", i, j);
1522 /**********************************/
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; }
1533 S57 f(int n){ return S57(n); }
1539 if (auto s = S57(10))
1544 assert(dtor_cnt == 1);
1546 printf("----\n"); //+
1549 if (auto s = S57(10))
1551 assert(dtor_cnt == 2);
1555 assert(dtor_cnt == 3); // +/
1560 if (auto s = S57(10))
1563 throw new Exception("test");
1566 }catch (Exception e){}
1567 assert(dtor_cnt == 1);
1578 assert(dtor_cnt == 1);
1580 printf("----\n"); //+
1585 assert(dtor_cnt == 2);
1589 assert(dtor_cnt == 3); // +/
1597 throw new Exception("test");
1600 }catch (Exception e){}
1601 assert(dtor_cnt == 1);
1610 assert(dtor_cnt == 1);
1620 assert(dtor_cnt == 3);
1628 if (auto s = S57(10))
1631 throw new Exception("test");
1634 }catch (Exception e){}
1635 assert(dtor_cnt == 1);
1643 assert(dtor_cnt == 1);
1653 assert(dtor_cnt == 3);
1664 throw new Exception("test");
1667 }catch (Exception e){}
1668 assert(dtor_cnt == 1);
1671 /**********************************/
1692 /**********************************/
1700 @disable this(this);
1701 ~this(){ ++sdtor58; }
1713 auto s1 = makeS58();
1714 assert(ps58 == &s1);
1715 assert(sdtor58 == 0);
1718 /**********************************/
1725 throw new Throwable("Oops!");
1736 // auto c = C(); c.oops();
1751 /**********************************/
1758 static int destroyed;
1783 assert(S.copied == 1); // fail, s2 was not copied;
1784 assert(S.destroyed == 1); // ok, s2 was destroyed
1787 /**********************************/
1797 this(this) { ++postblit; }
1801 void takesVal(Test x) {}
1802 ref Test returnsRef(ref Test x) { return x; }
1804 void f(ref Test x) { takesVal( x ); }
1808 postblit = dtor = 0;
1809 takesVal(returnsRef(x));
1810 assert(postblit == 1);
1813 postblit = dtor = 0;
1815 assert(postblit == 1);
1819 /**********************************/
1835 printf("%d\n", foo.state);
1836 assert(foo.state == 1);
1845 /**********************************/
1850 string m = "<not set>";
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); }
1861 printf("Postblit - %.*s\n", m.length, m.ptr);
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; }
1870 S6499 bar() { return S6499("bar"); }
1871 S6499 baz()() { return S6499("baz"); }
1876 S6499 foo() { return S6499("foo"); }
1880 scope(exit) assert(sdtor == 0);
1885 scope(exit) assert(sdtor == 0);
1890 /**********************************/
1892 template isImplicitlyConvertible(From, To)
1894 enum bool isImplicitlyConvertible = is(typeof({
1895 void fun(ref From v) {
1926 S1 ms2 = ms; // mutable to mutable
1927 const(S1) cs2 = ms; // mutable to const // NG -> OK
1931 static assert(!__traits(compiles,{ // NG -> OK
1932 S1 ms2 = cs; // field has reference, then const to mutable is invalid
1934 const(S1) cs2 = cs; // const to const // NG -> OK
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
1944 S2 ms2 = ms; // mutable to mutable
1945 const(S2) cs2 = ms; // mutable to const // NG -> OK
1949 S2 ms2 = cs; // all fields are value, then const to mutable is OK
1950 const(S2) cs2 = cs; // const to const // NG -> OK
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
1959 /**********************************/
1964 this(this) @safe { }
1967 @safe void test4316()
1970 auto b = a; // Error: safe function 'main' cannot call system function'__cpctor'
1973 /**********************************/
1982 this(F6177[] p...) {}
1992 /**********************************/
1999 this(this){ ++spblit; }
2009 assert(S6470.spblit == 3);
2016 assert(S6470.spblit == 6);
2018 void func(S6470[] a){}
2020 assert(S6470.spblit == 9);
2023 /**********************************/
2034 void func6636(S6636[3] sa) {}
2045 /**********************************/
2052 this(this){ ++spblit; }
2057 void func(S6637[3] sa){}
2061 assert(S6637.spblit == 3);
2064 /**********************************/
2072 this(int x) { i = ci++; /*writeln("new: ", i);*/ }
2073 this(this) { i = ci++; /*writeln("copy ", i);*/ }
2074 ~this() { /*writeln("del ", i);*/ }
2076 S7353 save1() // produces 2 copies in total
2081 auto save2() // produces 3 copies in total
2085 pragma(msg, typeof(return));
2091 auto s = S7353(1), t = S7353(1);
2093 assert(S7353.ci == 3);
2095 S7353.ci = 0; //writeln("-");
2097 auto s = S7353(1), t = S7353(1);
2099 assert(S7353.ci == 3);
2103 /**********************************/
2110 struct S8036b // or class
2115 /**********************************/
2121 this.length = length;
2128 const(S61) copy(const S61 s)
2140 assert(copy(t) == u);
2141 assert(t == copy(u));
2144 /**********************************/
2155 this(int x) { i = ci++; /*writeln("new: ", i);*/ }
2156 this(this) { i = ci++; /*writeln("copy ", i);*/ }
2157 ~this() { ++di; /*writeln("del: ", i);*/ }
2166 auto s = S(1), t = S(1);
2169 assert(S.ci == 3); // line 23
2174 /**********************************/
2181 this(int n) { val = n; }
2182 this(this) { val *= 3; }
2185 // CondExp on return statement
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; }
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);
2207 // CondExp on function argument
2213 S func(S s) { return s; }
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 ); }
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);
2230 // CondExp on array literal
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 ]; }
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);
2252 // CondExp on rhs of cat assign
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; }
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);
2274 // CondExp on struct literal element
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 ); }
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);
2297 /**********************************/
2306 this(int n) { val = n; }
2307 this(this) { val *= 3; }
2310 S[] sa = new S[](1);
2320 /**********************************/
2329 int opBinary(string op)(in S62 rhs) const
2332 return this.length - rhs.length;
2335 @property int length() const
2342 assert(_length == 1);
2351 immutable result = S62.init - S62.init;
2354 /**********************************/
2361 // postblit can also have no body because isn't called
2362 @disable this(this) { assert(0); }
2365 @property S fs() { return S(); }
2366 @property S[3] fsa() { return [S(), S(), S()]; }
2370 static assert(!__traits(compiles, { S s2 = s1; })); // OK
2372 static assert(!__traits(compiles, { s2 = s1; })); // OK
2376 S[3] sa1 = [S(), S(), S()];
2377 static assert(!__traits(compiles, { S[3] sa2 = sa1; })); // fixed
2379 static assert(!__traits(compiles, { sa2 = sa1; })); // fixed
2380 sa2 = [S(), S(), S()];
2385 static assert(!__traits(compiles, { da2[] = da1[]; })); // fixed
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; }));
2403 // postblit asserts in runtime
2404 this(this) { assert(0); }
2407 @property S fs() { return S(); }
2408 @property S[3] fsa() { return [S(), S(), S()]; }
2416 S[3] sa1 = [S(), S(), S()];
2418 sa2 = [S(), S(), S()];
2424 // concatenation and appending always run postblits
2427 /**********************************/
2432 static int postblit;
2435 this(this) { ++postblit; }
2438 void f8335(ref S8335[3] arr)
2443 void g8335(lazy S8335[3] arr)
2445 assert(S8335.postblit == 0);
2447 assert(S8335.postblit == 3);
2450 void h8335(lazy S8335 s)
2452 assert(S8335.postblit == 0);
2454 assert(S8335.postblit == 1);
2461 assert(S8335.postblit == 0);
2462 assert(arr[0].i == 7);
2465 assert(S8335.postblit == 3);
2470 assert(S8335.postblit == 1);
2473 /**********************************/
2480 @disable this(this) { assert(0); }
2486 static assert(!__traits(compiles, {
2487 S fs() { return s; }
2490 static assert(!__traits(compiles, {
2491 S[3] fsa() { return sa; }
2495 /**********************************/
2498 T func8475(T)(T x) @safe pure
2503 template X8475(bool something)
2507 this(this) @safe pure {}
2508 void func(XY x) @safe pure
2510 XY y = x; //Error: see below
2517 alias X8475!(true).XY Xtrue;
2519 /**********************************/
2528 Foo9320 opBinary(string op)(Foo9320 other) {
2529 return Foo9320(mixin("x" ~ op ~ "other.x"));
2533 Foo9320 test9320(Foo9320 a, Foo9320 b, Foo9320 c) {
2534 return (a + b) / (a * b) - c;
2537 /**********************************/
2546 static @property string sop() { return cast(string)op[0..i]; }
2551 printf("Created %.*s...\n", name.length, name.ptr);
2552 assert(i + 1 < op.length);
2558 printf("Copied %.*s...\n", name.length, name.ptr);
2559 assert(i + 1 < op.length);
2565 printf("Deleted %.*s\n", name.length, name.ptr);
2566 assert(i + 1 < op.length);
2570 const int opCmp(ref const Test9386 t)
2572 return op[0] - t.op[0];
2588 assert(Test9386.sop == "aaaa");
2593 foreach (Test9386 test; tests)
2595 printf("\tForeach %.*s\n", test.name.length, test.name.ptr);
2596 Test9386.op[Test9386.i++] = 'x';
2599 assert(Test9386.sop == "bxcbxcbxcbxc");
2604 foreach (ref Test9386 test; tests)
2606 printf("\tForeach %.*s\n", test.name.length, test.name.ptr);
2607 Test9386.op[Test9386.i++] = 'x';
2609 assert(Test9386.sop == "xxxx");
2616 Test9386[Test9386] tests =
2617 [ Test9386("1") : Test9386("one"),
2618 Test9386("2") : Test9386("two"),
2619 Test9386("3") : Test9386("three"),
2620 Test9386("4") : Test9386("four") ];
2626 foreach (Test9386 k, Test9386 v; tests)
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';
2633 assert(Test9386.sop == "bbxccbbxccbbxccbbxcc");
2638 foreach (Test9386 k, ref Test9386 v; tests)
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';
2644 assert(Test9386.sop == "bxcbxcbxcbxc");
2650 /**********************************/
2653 auto x9441 = X9441(0.123);
2658 this(double x) { a = cast(int)(x * 100); }
2663 assert(x9441.a == 12);
2666 /**********************************/
2670 size_t _capacity; //Comment me
2671 int[] _pay; //Comment me
2673 size_t insertBack(Data d)
2675 immutable newLen = _pay.length + 3;
2676 _pay.length = newLen;
2677 _pay = _pay[0 .. newLen]; //Comment me
2695 _store._payload = Payload.init;
2700 printf("%d\n", _store._count);
2710 a._store._payload.insertBack(b); //Fails
2713 /**********************************/
2718 @safe pure nothrow ~this() {}
2726 void test9899() @safe pure nothrow
2728 MemberS9899 s; // 11
2731 /**********************************/
2736 static struct SX(bool hasCtor, bool hasDtor)
2739 static size_t assign;
2744 this(int i) { this.i = i; }
2747 void opAssign(SX rhs)
2749 printf("%08X(%d) from Rvalue %08X(%d)\n", &this.i, this.i, &rhs.i, rhs.i);
2753 void opAssign(ref SX rhs)
2755 printf("%08X(%d) from Lvalue %08X(%d)\n", &this.i, this.i, &rhs.i, rhs.i);
2763 printf("destroying %08X(%d)\n", &this.i, this.i);
2774 foreach (hasCtor; TypeTuple!(false, true))
2775 foreach (hasDtor; TypeTuple!(false, true))
2777 alias S = SX!(hasCtor, hasDtor);
2783 // Assignment from two kinds of rvalues
2784 assert(S.assign == 0);
2786 static if (hasDtor) assert(S.dtor == 1);
2787 assert(S.assign == 1);
2789 assert(S.assign == 2);
2790 static if (hasDtor) assert(S.dtor == 2);
2795 /**********************************/
2802 this(this) { assert(0); }
2806 auto ref makeS9985() @system
2815 S9985 s = makeS9985();
2816 assert(S9985.ptr == &s); // NRVO
2818 static const int n = 1;
2819 static auto ref retN()
2823 auto p = &(retN()); // OK
2825 alias pure nothrow @nogc @safe ref const(int) F1();
2826 static assert(is(typeof(retN) == F1));
2828 enum const(int) x = 1;
2829 static auto ref retX()
2833 static assert(!__traits(compiles, { auto q = &(retX()); }));
2834 alias pure nothrow @nogc @safe const(int) F2();
2835 static assert(is(typeof(retX) == F2));
2838 /**********************************/
2840 // https://issues.dlang.org/show_bug.cgi?id=17457
2842 void delegate() dg17457;
2850 @disable this(this);
2855 pragma(inline, false);
2861 auto x = foo17457();
2862 //printf("%p vs %p\n", &x, dg17457.ptr);
2863 assert(&x == dg17457.ptr);
2866 /**********************************/
2878 static assert( __traits(compiles, s.opAssign(s)));
2879 static assert(!__traits(compiles, s.__postblit()));
2881 assert(S.dtor == 0);
2883 assert(S.dtor == 1);
2886 /**********************************/
2900 /**********************************/
2905 static struct SX { pure nothrow @safe ~this() {} }
2906 static struct SY { pure nothrow @safe ~this() {} }
2907 static struct SZ { @disable ~this() {} }
2909 // function to check merge result of the dtor attributes
2910 static void check(S)() { S s; }
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() ));
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))
2948 static assert(!__traits(compiles, &check!Sx));
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) {} }
2958 // function to check merge result of the postblit attributes
2959 static void check(S)() { S s; S s2 = s; }
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() ));
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))
2997 static assert(!__traits(compiles, &check!Sx));
3001 /**********************************/
3004 struct S10160 { this(this) {} }
3006 struct X10160a { S10160 s; const int x; }
3007 struct X10160b { S10160 s; enum int x = 1; }
3015 /**********************************/
3021 const string[4] i2s = ()
3025 for (int i = 0; i < 4; ++i)
3027 char[1] buf = [cast(char)('0' + i)];
3028 string str = buf.idup;
3031 return tmp; // NRVO should work
3033 assert(p == cast(void*)&i2s[0]);
3034 assert(i2s == ["0", "1", "2", "3"]);
3037 /**********************************/
3043 this(this) pure nothrow @safe {}
3047 ~this() pure nothrow @safe {}
3051 this(this) pure nothrow @safe {}
3052 ~this() pure nothrow @safe {}
3061 ~this() pure nothrow @safe {}
3074 void check10079(S)(ref S s) pure nothrow @safe { s = S(); }
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));
3084 /**********************************/
3094 template DeclareConstructor(string fieldName)
3097 `this(typeof(_` ~ fieldName ~ `) value)` ~
3098 `{ this._` ~ fieldName ~ ` = value; }`;
3102 mixin DeclareConstructor!"str";
3103 mixin DeclareConstructor!"num";
3106 Foo value1 = Foo("D");
3107 Foo value2 = Foo(128);
3108 assert(value1._str == "D");
3109 assert(value2._num == 128);
3112 /**********************************/
3115 struct Foo10694 { ~this() { } }
3117 void test10694() pure
3120 __gshared Foo10694 i2;
3124 __gshared Foo10694 j2;
3128 /**********************************/
3133 static ~this() nothrow pure @safe
3136 static assert(!__traits(compiles, ++p));
3137 static assert(!__traits(compiles, ++global10787));
3140 shared static ~this() nothrow pure @safe
3143 static assert(!__traits(compiles, ++p));
3144 static assert(!__traits(compiles, ++global10787));
3147 /**********************************/
3155 this(int) { value = ++count; }
3156 ~this() { --count; }
3157 this(this) { value = ++count; assert(value == 3); }
3160 S10789 fun10789a(bool isCondExp)(bool cond)
3162 S10789 s1 = S10789(42), s2 = S10789(24);
3163 assert(S10789.count == 2);
3164 static if (isCondExp)
3166 return cond ? s1 : s2;
3177 auto fun10789b(bool isCondExp)(bool cond)
3179 S10789 s1 = S10789(42), s2 = S10789(24);
3180 assert(S10789.count == 2);
3181 static if (isCondExp)
3183 return cond ? s1 : s2;
3196 foreach (fun; TypeTuple!(fun10789a, fun10789b))
3197 foreach (isCondExp; TypeTuple!(false, true))
3200 S10789 s = fun!isCondExp(true);
3201 assert(S10789.count == 1);
3202 assert(s.value == 3);
3204 assert(S10789.count == 0);
3206 S10789 s = fun!isCondExp(false);
3207 assert(S10789.count == 1);
3208 assert(s.value == 3);
3210 assert(S10789.count == 0);
3214 /**********************************/
3223 this(this) { result ~= "pA"; version(none) printf("copied A\n"); }
3224 ~this() { result ~= "dA"; version(none) printf("destroy A\n"); }
3230 result ~= "(pB)"; version(none) printf("B says what?\n");
3231 throw new Exception("BOOM!");
3233 ~this() { result ~= "dB"; version(none) printf("destroy B\n"); }
3255 assert(result == "{[pA(pB)dA]dBdA}", result);
3272 assert(result == "{[pA(pB)dA]dBdAdBdA}", result);
3276 static assert(test10972()); // CTFE
3278 /**********************************/
3287 S[2][] dsa = [[S(), S()]];
3288 dsa.reserve(dsa.length + 2); // avoid postblit calls by GC
3292 assert(S.count == 2);
3296 assert(S.count == 2);
3302 this(this) { ++count; }
3309 this(this) { ++count; }
3314 /**********************************/
3331 S11197a[][string] aa1;
3332 aa1["test"] ~= S11197a.init;
3334 S11197b[][string] aa2;
3335 aa2["test"] ~= S11197b.init;
3338 /**********************************/
3345 void fun7474(T...)() { T x; }
3346 void test7474() { fun7474!S7474(); }
3348 /**********************************/
3356 A11286 getA11286() pure nothrow
3363 A11286 a = getA11286();
3366 /**********************************/
3386 /**********************************/
3398 this(this) { assert(0); }
3399 ~this() { dtor ~= val; }
3402 auto makeS12045(bool thrown)
3404 auto s1 = S12045("1");
3405 auto s2 = S12045("2");
3409 throw new Exception("");
3414 dtor = null, ptr = null;
3417 S12045 s = makeS12045(true);
3422 assert(dtor == "21", dtor);
3425 dtor = null, ptr = null;
3427 S12045 s = makeS12045(false);
3428 assert(dtor == "2");
3429 if (!__ctfe) assert(ptr is &s); // NRVO
3431 assert(dtor == "21");
3435 static assert(test12045());
3437 /**********************************/
3446 struct Tuple12591(Types...)
3451 expand[] = values[];
3457 alias T1 = Tuple12591!(S12591!int);
3460 /**********************************/
3467 void opAssign(X12660) @nogc {}
3468 @nogc invariant() {}
3476 @nogc invariant() {}
3486 @nogc invariant() {}
3489 void test12660() @nogc
3501 /**********************************/
3508 invariant() { ++count; }
3510 @disable this(this);
3522 Foo12686 f2 = f.bar();
3526 assert(Foo12686.count == 2);
3529 /**********************************/
3534 @disable this(this); // non nothrow
3540 S13089[1000] foo13089() nothrow
3542 typeof(return) data;
3547 void test13089() nothrow
3549 immutable data = foo13089();
3550 assert(p13089 == &data);
3553 /**********************************/
3555 struct NoDtortest11763 {}
3557 struct HasDtortest11763
3559 NoDtortest11763 func()
3561 return NoDtortest11763();
3568 HasDtortest11763().func();
3571 /**********************************/
3579 Buf get() { Buf b; return b; }
3582 Variant value() { Variant v; return v; }
3589 /**********************************/
3605 /**********************************/
3610 __gshared int count;
3611 ~this() { ++count; printf("~S\n"); }
3615 __gshared int count;
3616 ~this() { ++count; printf("~T\n"); }
3619 static int foo(bool flag)
3622 throw new Exception("hello");
3626 static void func(S s, int f, T t)
3633 this(S s, int f, T t)
3643 func(S(), foo(true), T());
3644 printf("not reach\n");
3650 printf("threw %d S %d T %d\n", threw, S.count, T.count);
3651 assert(threw && S.count == 1 && T.count == 0);
3659 func(S(), foo(false), T());
3660 printf("reached\n");
3666 printf("threw %d S %d T %d\n", threw, S.count, T.count);
3667 assert(!threw && S.count == 1 && T.count == 1);
3675 new C(S(), foo(true), T());
3676 printf("not reach\n");
3682 printf("threw %d S %d T %d\n", threw, S.count, T.count);
3683 assert(threw && S.count == 1 && T.count == 0);
3689 /**********************************/
3692 T enforce14443(E : Throwable = Exception, T)(T value)
3695 throw new E("Enforcement failed");
3699 struct RefCounted14443(T)
3700 if (!is(T == class) && !(is(T == interface)))
3702 struct RefCountedStore
3710 private Impl* _store;
3712 private void initialize(A...)(auto ref A args)
3714 import core.stdc.stdlib : malloc;
3716 // enforce is necessary
3717 _store = cast(Impl*) enforce14443(malloc(Impl.sizeof));
3719 // emulate 'emplace'
3720 static if (args.length > 0)
3721 _store._payload.tupleof = args;
3723 _store._payload = T.init;
3728 @property bool isInitialized() const nothrow @safe
3730 return _store !is null;
3733 void ensureInitialized()
3735 if (!isInitialized) initialize();
3739 RefCountedStore _refCounted;
3741 this(A...)(auto ref A args) if (A.length > 0)
3743 _refCounted.initialize(args);
3748 if (!_refCounted.isInitialized)
3750 ++_refCounted._store._count;
3751 //printf("RefCounted count = %d (inc)\n", _refCounted._store._count);
3756 if (!_refCounted.isInitialized)
3758 assert(_refCounted._store._count > 0);
3759 if (--_refCounted._store._count)
3761 //printf("RefCounted count = %u\n", _refCounted._store._count);
3765 import core.stdc.stdlib : free;
3766 free(_refCounted._store);
3767 _refCounted._store = null;
3770 void opAssign(typeof(this) rhs) { assert(0); }
3771 void opAssign(T rhs) { assert(0); }
3773 @property ref T refCountedPayload()
3775 _refCounted.ensureInitialized();
3776 return _refCounted._store._payload;
3779 alias refCountedPayload this;
3788 RefCounted14443!Payload data;
3791 struct PathRange14443
3796 @property PathElement14443 front()
3798 return PathElement14443(this, path.data.p);
3802 struct PathElement14443
3804 PathRange14443 range;
3806 this(PathRange14443 range, int)
3814 auto path = Path14443(RefCounted14443!(Path14443.Payload)(12));
3815 assert(path.data.p == 12);
3817 @property refCount() { return path.data._refCounted._store._count; }
3818 assert(refCount == 1);
3821 auto _r = PathRange14443(path);
3822 assert(refCount == 2);
3825 auto element = _r.front;
3826 assert(refCount == 3); // fail with 2.067
3828 assert(refCount == 2);
3830 assert(refCount == 1);
3833 /**********************************/
3834 // 13661, 14022, 14023 - postblit/dtor call on static array assignment
3843 this(this) { op ~= x-0x20; } // upper case
3844 ~this() { op ~= x; } // lower case
3846 ref auto opAssign(T)(T arg)
3860 assert(a[0].x == 'x' && a[1].x == 'x');
3864 a = [S(), S()]; // equivalent a = a.init
3865 assert(op == "abcd");
3866 assert(a[0].x == 'x' && a[1].x == 'x');
3868 assert(op == "abcdxx");
3879 this(this) { op ~= x-0x20; } // upper case
3880 ~this() { op ~= x; } // lower case
3884 S[3] sa = [S('a'), S('b'), S('c')];
3886 assert(sa == [S('a'), S('b'), S('c')]);
3887 assert(sb == [S('b'), S('c')]);
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')]);
3896 static assert(test13661()); // CTFE
3897 static assert(test13661a());
3906 this(this) { op ~= x-0x20; } // upper case
3907 ~this() { op ~= x; } // lower case
3910 S[2] makeSA() { return [S('p'), S('q')]; }
3919 this.sb = sa; // TOKconstruct
3920 assert(op == "BC", op);
3921 assert(sb == [S('b'), S('c')]);
3923 void test(ref S[2] sa)
3925 this.sb = sa; // dotvar: resolveSlice(newva)
3926 assert(op == "BxCy");
3932 S[2] sa = [S('a'), S('b')];
3933 T t; t.sb[0].x = 'x';
3937 assert(op == "AxBy");
3939 assert(op == "AxByab");
3941 assert(op == "AxByabqpba");
3945 S[3] sa = [S('a'), S('b'), S('c')];
3949 assert(sa == [S('a'), S('b'), S('c')]);
3950 assert(t.sb == [S('x'), S('y')]);
3953 assert(op == "BCyxcba");
3957 S[3] sx = [S('a'), S('b'), S('c')];
3958 T t; t.sb[0].x = 'x';
3961 assert(op == "BxCy");
3962 assert(t.sb == [S('b'), S('c')]);
3964 assert(op == "BxCycbcba");
3968 static assert(test14022());
3977 this(this) { op ~= x-0x20; } // upper case
3978 ~this() { op ~= x; } // lower case
3981 S[2] makeSA() { return [S('p'), S('q')]; }
3989 this.sb[0] = sa; // TOKconstruct
3990 assert(sa == [S('b'), S('c')]);
3991 assert(sb[0] == [S('b'), S('c')]);
3995 void test(ref S[2] sa)
3998 //a.length = 1; // will cause runtine AccessViolation
4001 a[0] = sa; // index <-- resolveSlice(newva)
4002 assert(op == "BxCx");
4003 assert(a[0] == [S('b'), S('c')]);
4008 S[3] sa = [S('a'), S('b'), S('c')];
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')]);
4019 S[2] sa = [S('a'), S('b')];
4020 S[2][] a = [[S('x'), S('y')]];
4023 assert(op == "AxBy");
4025 assert(op == "AxByab");
4027 assert(op == "AxByabba");
4031 S[3] sa = [S('a'), S('b'), S('c')];
4033 assert(op == "BxCx");
4035 assert(op == "BxCxcba");
4039 static assert(test14023());
4041 /************************************************/
4042 // 13669 - dtor call on static array variable
4051 ~this() { dtor ~= x; }
4055 assert(dtor == "xx");
4058 { S[2] a = [S('a'), S('b')]; }
4059 assert(dtor == "ba"); // reverse order. See also: TypeInfo_StaticArray.destroy()
4063 static assert(test13669());
4065 /**********************************/
4067 __gshared bool b13095 = false;
4069 void bar13095() { throw new Exception(""); }
4073 this(int) { printf("ctor %p\n", &this); bar13095(); }
4075 ~this() { b13095 = true; printf("dtor %p\n", &this); }
4082 } catch(Exception) { printf("catch\n"); }
4086 /**********************************/
4095 T opCast(T:bool)() { return true; }
4118 /**********************************/
4128 this(this) { r ~= cast(char)('0' + n); }
4135 S[2] sa1 = [s1, s2];
4136 assert(r == "12", r); // OK
4139 S[] a2 = a1 ~ s2; // runtime concatenation
4140 assert(r == "12", r); // OK <- NG only in CTFE
4143 S[2] sa2a = [s1] ~ s2;
4144 assert(r == "12", r); // OK <- NG, s2 is not copied
4147 S[2] sa2b = s2 ~ [s1];
4148 assert(r == "21", r); // OK <- NG, s2 is not copied
4151 S[3] sa3a = ([s1] ~ [s1]) ~ s2;
4152 assert(r == "112", r); // OK <- NG, s2 is not copied
4155 S[3] sa3b = s2 ~ ([s1] ~ [s1]);
4156 assert(r == "211", r); // OK <- NG, s2 is not copied
4160 static assert(test14686());
4162 /**********************************/
4172 ~this() { ++dtorCount; }
4177 sa1 = (S[2]).init; // S[2] <- rvalue
4178 assert(sa1[0].x == 0);
4179 assert(dtorCount == 2);
4184 da2[] = (S[2]).init[]; // S[] <- rvalue slice
4185 assert(sa2[0].x == 0);
4186 assert(dtorCount == 4);
4191 sa3 = sa4; // S[2] <- lvalue
4192 assert(sa3[0].x == 0);
4193 assert(dtorCount == 6);
4197 da4[] = sa5[]; // S[] <- lvalue slice
4198 assert(sa4[0].x == 0);
4199 assert(dtorCount == 8);
4203 static assert(test14815());
4205 /**********************************/
4206 // https://issues.dlang.org/show_bug.cgi?id=16197
4211 this(this) { r ~= 'p'; printf("POSTBLIT %d\n", x++); }
4212 ~this() { r ~= 'd'; printf("DTOR %d\n" , x++); }
4221 assert(Elem.r == "ddd");
4224 /**********************************/
4234 ~this() { ++dtorCount; }
4240 assert(a[0].x == 0);
4241 assert(dtorCount == 1);
4245 static assert(test14860());
4247 /**********************************/
4250 void test14696(int len = 2)
4258 void* get(void* p = null)
4260 result ~= "get(" ~ cast(char)(n+'0') ~ ").";
4266 result ~= "dtor(" ~ cast(char)(n+'0') ~ ").";
4272 result ~= "makeS(" ~ cast(char)(n+'0') ~ ").";
4275 void foo(void* x, void* y = null)
4279 void fooThrow(void* x, void* y = null)
4281 result ~= "fooThrow.";
4282 throw new Exception("fail!");
4285 void check(void delegate() dg, string r, string file = __FILE__, size_t line = __LINE__)
4287 import core.exception;
4290 try { dg(); } catch (Exception e) {}
4292 throw new AssertError(result, file, line);
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).");
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).");
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).");
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).");
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.");
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.");
4356 /**********************************/
4359 int test14838() pure nothrow @safe
4370 const S14838!int cs;
4373 const S14838!int[2] ca;
4375 S14838!int[2][2] ma2x2;
4376 const S14838!int[2][2] ca2x2;
4378 // number of S14838 = 1*2 + 2*2 + 4*2 = 14
4381 void test(Dg)(scope Dg code)
4387 test(delegate{ S14838!int a; }); assert(dtor == 1);
4388 test(delegate{ const S14838!int a; }); assert(dtor == 1);
4390 test(delegate{ S14838!int[2] a; }); assert(dtor == 2);
4391 test(delegate{ const S14838!int[2] a; }); assert(dtor == 2);
4393 test(delegate{ S14838!int[2][2] a; }); assert(dtor == 4);
4394 test(delegate{ const S14838!int[2][2] a; }); assert(dtor == 4);
4396 test(delegate{ X14838 a; }); assert(dtor == 1 * 14);
4397 test(delegate{ const X14838 a; }); assert(dtor == 1 * 14);
4399 test(delegate{ X14838[2] a; }); assert(dtor == 2 * 14);
4400 test(delegate{ const X14838[2] a; }); assert(dtor == 2 * 14);
4402 test(delegate{ X14838[2][2] a; }); assert(dtor == 4 * 14);
4403 test(delegate{ const X14838[2][2] a; }); assert(dtor == 4 * 14);
4407 static assert(test14838());
4409 /**********************************/
4413 private long p = 87;
4425 void funky() { assert(p == 90); }
4427 static void tester()
4438 /**********************************/
4450 long[10] dummy; // S64 needs to be passed by stack
4462 assert(X64.dtor == 1);
4465 /**********************************/
4471 void bar(int a, int b)
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");
4503 /**********************************/
4511 X15661 createX15661() { return X15661(); }
4518 @disable this(this);
4519 this(X15661 a1, X15661 a2) {}
4527 b = Y15661(createX15661(), createX15661());
4528 assert(Y15661.dtor == 0);
4538 assert(Y15661.dtor == 0);
4540 assert(Y15661.dtor == 1);
4543 /**********************************/
4676 printf("Success\n");