/* TEST_OUTPUT: --- true g &Test109S(&Test109S()) tfoo tfoo Crash! --- */ import core.stdc.stdio; template Tuple(A...) { alias A Tuple; } template eval(A...) { const typeof(A[0]) eval = A[0]; } /************************************************/ int Foo1(int i) { if (i == 0) return 1; else return i * Foo1(i - 1); } void test1() { static int f = Foo1(5); printf("%d %d\n", f, 5*4*3*2); assert(f == 120); } /************************************************/ int find2(string s, char c) { if (s.length == 0) return -1; else if (c == s[0]) return 0; else return 1 + find2(s[1..$], c); } void test2() { static int f = find2("hello", 'l'); printf("%d\n", f); assert(f == 2); } /************************************************/ int bar3(int i) { int j; while (i) { j += i; i--; } return j; } void test3() { static b = bar3(7); printf("b = %d, %d\n", b, bar3(7)); assert(b == 28); } /************************************************/ int bar4(int i) { for (int j = 0; j < 10; j++) i += j; return i; } void test4() { static b = bar4(7); printf("b = %d, %d\n", b, bar4(7)); assert(b == 52); } /************************************************/ int bar5(int i) { int j; do { i += j; j++; } while (j < 10); return i; } void test5() { static b = bar5(7); printf("b = %d, %d\n", b, bar5(7)); assert(b == 52); } /************************************************/ int bar6(int i) { int j; do { i += j; j++; if (j == 4) break; } while (j < 10); return i; } void test6() { static b = bar6(7); printf("b = %d, %d\n", b, bar6(7)); assert(b == 13); } /************************************************/ int bar7(int i) { int j; do { i += j; j++; if (j == 4) return 80; } while (j < 10); return i; } void test7() { static b = bar7(7); printf("b = %d, %d\n", b, bar7(7)); assert(b == 80); } /************************************************/ int bar8(int i) { int j; do { j++; if (j == 4) continue; i += j; } while (j < 10); return i; } void test8() { static b = bar8(7); printf("b = %d, %d\n", b, bar8(7)); assert(b == 58); } /************************************************/ int bar9(int i) { int j; while (j < 10) { j++; if (j == 4) continue; i += j; } return i; } void test9() { static b = bar9(7); printf("b = %d, %d\n", b, bar9(7)); assert(b == 58); } /************************************************/ int bar10(int i) { int j; while (j < 10) { j++; if (j == 4) break; i += j; } return i; } void test10() { static b = bar10(7); printf("b = %d, %d\n", b, bar10(7)); assert(b == 13); } /************************************************/ int bar11(int i) { int j; while (j < 10) { j++; if (j == 4) return i << 3; i += j; } return i; } void test11() { static b = bar11(7); printf("b = %d, %d\n", b, bar11(7)); assert(b == 104); } /************************************************/ int bar12(int i) { for (int j; j < 10; j++) { if (j == 4) return i << 3; i += j; } return i; } void test12() { static b = bar12(7); printf("b = %d, %d\n", b, bar12(7)); assert(b == 104); } /************************************************/ int bar13(int i) { for (int j; j < 10; j++) { if (j == 4) break; i += j; } return i; } void test13() { static b = bar13(7); printf("b = %d, %d\n", b, bar13(7)); assert(b == 13); } /************************************************/ int bar14(int i) { for (int j; j < 10; j++) { if (j == 4) continue; i += j; } return i; } void test14() { static b = bar14(7); printf("b = %d, %d\n", b, bar14(7)); assert(b == 48); } /************************************************/ int bar15(int i) { foreach (k, v; "hello") { i <<= 1; if (k == 4) continue; i += v; } return i; } void test15() { static b = bar15(7); printf("b = %d, %d\n", b, bar15(7)); assert(b == 3344); } /************************************************/ int bar16(int i) { foreach_reverse (k, v; "hello") { i <<= 1; if (k == 4) continue; i += v; } return i; } void test16() { static b = bar16(7); printf("b = %d, %d\n", b, bar16(7)); assert(b == 1826); } /************************************************/ int bar17(int i) { foreach (k, v; "hello") { i <<= 1; if (k == 2) break; i += v; } return i; } void test17() { static b = bar17(7); printf("b = %d, %d\n", b, bar17(7)); assert(b == 674); } /************************************************/ int bar18(int i) { foreach_reverse (k, v; "hello") { i <<= 1; if (k == 2) break; i += v; } return i; } void test18() { static b = bar18(7); printf("b = %d, %d\n", b, bar18(7)); assert(b == 716); } /************************************************/ int bar19(int i) { assert(i > 0); foreach_reverse (k, v; "hello") { i <<= 1; if (k == 2) return 8; i += v; } return i; } void test19() { static b = bar19(7); printf("b = %d, %d\n", b, bar19(7)); assert(b == 8); } /************************************************/ int bar20(int i) { assert(i > 0); foreach (k, v; "hello") { i <<= 1; if (k == 2) return 8; i += v; } return i; } void test20() { static b = bar20(7); printf("b = %d, %d\n", b, bar20(7)); assert(b == 8); } /************************************************/ int bar21(int i) { assert(i > 0); foreach (v; Tuple!(57, 23, 8)) { i <<= 1; i += v; } return i; } void test21() { static b = bar21(7); printf("b = %d, %d\n", b, bar21(7)); assert(b == 338); } /************************************************/ int bar22(int i) { assert(i > 0); foreach_reverse (v; Tuple!(57, 23, 8)) { i <<= 1; i += v; } return i; } void test22() { static b = bar22(7); printf("b = %d, %d\n", b, bar22(7)); assert(b == 191); } /************************************************/ int bar23(int i) { assert(i > 0); foreach_reverse (v; Tuple!(57, 23, 8)) { i <<= 1; if (v == 23) return i + 1; i += v; } return i; } void test23() { static b = bar23(7); printf("b = %d, %d\n", b, bar23(7)); assert(b == 45); } /************************************************/ int bar24(int i) { assert(i > 0); foreach (v; Tuple!(57, 23, 8)) { i <<= 1; if (v == 23) return i + 1; i += v; } return i; } void test24() { static b = bar24(7); printf("b = %d, %d\n", b, bar24(7)); assert(b == 143); } /************************************************/ int bar25(int i) { assert(i > 0); foreach_reverse (v; Tuple!(57, 23, 8)) { i <<= 1; if (v == 23) break; i += v; } return i; } void test25() { static b = bar25(7); printf("b = %d, %d\n", b, bar25(7)); assert(b == 44); } /************************************************/ int bar26(int i) { assert(i > 0); foreach (v; Tuple!(57, 23, 8)) { i <<= 1; if (v == 23) break; i += v; } return i; } void test26() { static b = bar26(7); printf("b = %d, %d\n", b, bar26(7)); assert(b == 142); } /************************************************/ int bar27(int i) { foreach_reverse (v; Tuple!(57, 23, 8)) { i <<= 1; if (v == 23) continue; i += v; } return i; } void test27() { static b = bar27(7); printf("b = %d, %d\n", b, bar27(7)); assert(b == 145); } /************************************************/ int bar28(int i) { foreach (v; Tuple!(57, 23, 8)) { i <<= 1; if (v == 23) continue; i += v; } return i; } void test28() { static b = bar28(7); printf("b = %d, %d\n", b, bar28(7)); assert(b == 292); } /************************************************/ int bar29(int i) { switch (i) { case 1: i = 4; break; case 7: i = 3; break; default: assert(0); } return i; } void test29() { static b = bar29(7); printf("b = %d, %d\n", b, bar29(7)); assert(b == 3); } /************************************************/ int bar30(int i) { switch (i) { case 1: i = 4; break; case 8: i = 2; break; default: i = 3; break; } return i; } void test30() { static b = bar30(7); printf("b = %d, %d\n", b, bar30(7)); assert(b == 3); } /************************************************/ int bar31(string s) { int i; switch (s) { case "hello": i = 4; break; case "betty": i = 2; break; default: i = 3; break; } return i; } void test31() { static b = bar31("betty"); printf("b = %d, %d\n", b, bar31("betty")); assert(b == 2); } /************************************************/ int bar32(int i) { switch (i) { case 7: i = 4; goto case; case 5: i = 2; break; default: i = 3; break; } return i; } void test32() { static b = bar32(7); printf("b = %d, %d\n", b, bar32(7)); assert(b == 2); } /************************************************/ int bar33(int i) { switch (i) { case 5: i = 2; break; case 7: i = 4; goto case 5; default: i = 3; break; } return i; } void test33() { static b = bar33(7); printf("b = %d, %d\n", b, bar33(7)); assert(b == 2); } /************************************************/ int bar34(int i) { switch (i) { default: i = 3; break; case 5: i = 2; break; case 7: i = 4; goto default; } return i; } void test34() { static b = bar34(7); printf("b = %d, %d\n", b, bar34(7)); assert(b == 3); } /************************************************/ int bar35(int i) { L1: switch (i) { default: i = 3; break; case 5: i = 2; break; case 3: return 8; case 7: i = 4; goto default; } goto L1; } void test35() { static b = bar35(7); printf("b = %d, %d\n", b, bar35(7)); assert(b == 8); } /************************************************/ int square36(int x) { return x * x; } const int foo36 = square36(5); void test36() { assert(foo36 == 25); } /************************************************/ string someCompileTimeFunction() { return "printf(\"Wowza!\n\");"; } void test37() { mixin(someCompileTimeFunction()); } /************************************************/ string NReps(string x, int n) { string ret = ""; for (int i = 0; i < n; i++) { ret ~= x; } return ret; } void test38() { static x = NReps("3", 6); assert(x == "333333"); } /************************************************/ bool func39() { return true; } static if (func39()) { pragma(msg, "true"); } else { pragma(msg, "false"); } void test39() { } /************************************************/ string UpToSpace(string x) { int i = 0; while (i < x.length && x[i] != ' ') { i++; } return x[0..i]; } void test40() { const y = UpToSpace("first space was after first"); assert(y == "first"); } /************************************************/ int bar41(ref int j) { return 5; } int foo41(int i) { int x; x = 3; bar41(x); return i + x; } void test41() { const y = foo41(3); assert(y == 6); } /************************************************/ int bar42(ref int j) { return 5; } int foo42(int i) { int x; x = 3; bar42(x); return i + x; } void test42() { const y = foo42(3); assert(y == 6); } /************************************************/ int bar(string a) { int v; for (int i = 0; i < a.length; i++) { if (a[i] != ' ') { v += a.length; } } return v; } void test43() { const int foo = bar("a b c d"); assert(foo == 28); } /************************************************/ string foo44() { return ("bar"); } void test44() { const string bar = foo44(); assert(bar == "bar"); } /************************************************/ int square45(int n) { return (n * n); } void test45() { int bar = eval!(square45(5)); assert(bar == 25); } /************************************************/ const int[5] foo46 = [0,1,2,3,4]; void test46() { printf("%d\n", eval!(foo46[3])); } /************************************************/ string foo47() { string s; s = s ~ 't'; return s ~ "foo"; } void test47() { static const x = foo47(); pragma(msg, x); assert(x == "tfoo"); } /************************************************/ string foo48() { string s; s = s ~ 't'; s = s.idup; return s ~ "foo"; } void test48() { static const x = foo48(); pragma(msg, x); assert(x == "tfoo"); } /************************************************/ dstring testd49(dstring input) { if (input[3..5] != "rt") { return input[1..3]; } return "my"; } void test49() { static x = testd49("hello"); assert(x == "el"); } /************************************************/ string makePostfix50(int x) { string first; first = "bad"; if (x) { first = "ok"; makePostfix50(0); } return first; } void test50() { static const char [] q2 = makePostfix50(1); static assert(q2 == "ok", q2); } /************************************************/ int exprLength(string s) { int numParens=0; for (int i = 0; i < s.length; ++i) { if (s[i] == '(') { numParens++; } if (s[i] == ')') { numParens--; } if (numParens == 0) { return i; } } assert(0); } string makePostfix51(string operations) { if (operations.length < 2) return "x"; int x = exprLength(operations); string first="bad"; if (x > 0) { first = "ok"; string ignore = makePostfix51(operations[1..x]); } return first; } void test51() { string q = makePostfix51("(a+b)*c"); assert(q == "ok"); static const string q2 = makePostfix51("(a+b)*c"); static assert(q2 == "ok"); static assert(makePostfix51("(a+b)*c") == "ok"); } /************************************************/ int foo52(ref int x) { x = 7; return 3; } int bar52(int y) { y = 4; foo52(y); return y; } void test52() { printf("%d\n", bar52(2)); static assert(bar52(2) == 7); } /************************************************/ void bar53(out int x) { x = 2; } int foo53() { int y; bar53(y); return y; } void test53() { const int z = foo53(); assert(z == 2); } /************************************************/ void test54() { static assert(equals54("alphabet", "alphabet")); } bool equals54(string a, string b) { return (a == b); } /************************************************/ const string[2] foo55 = ["a", "b"]; string retsth55(int i) { return foo55[i]; } void test55() { enum res1 = eval!(foo55[0]); printf("%.*s\n", cast(int)res1.length, res1.ptr); enum res2 = eval!(retsth55(0)); printf("%.*s\n", cast(int)res2.length, res2.ptr); } /************************************************/ string retsth56(int i) { static const string[2] foo = ["a", "b"]; return foo[i]; } void test56() { enum result = eval!(retsth56(0)); printf("%.*s\n", cast(int)result.length, result.ptr); } /************************************************/ int g57() { pragma(msg, "g"); return 2; } const int a57 = g57(); void test57() { assert(a57 == 2); } /************************************************/ int[] Fun58(int x) { int[] result; result ~= x + 1; return result; } void test58() { static b = Fun58(1) ~ Fun58(2); assert(b.length == 2); assert(b[0] == 2); assert(b[1] == 3); } /************************************************/ int Index59() { int[] data = [1]; return data[0]; } void test59() { static assert(Index59() == 1); } /************************************************/ string[int] foo60() { return [3:"hello", 4:"betty"]; } void test60() { static assert(foo60()[3] == "hello"); static assert(foo60()[4] == "betty"); } /************************************************/ string[int] foo61() { return [3:"hello", 4:"betty", 3:"world"]; } void test61() { static assert(foo61()[3] == "world"); static assert(foo61()[4] == "betty"); } /************************************************/ string foo62(int k) { string[int] aa; aa = [3:"hello", 4:"betty"]; return aa[k]; } void test62() { static assert(foo62(3) == "hello"); static assert(foo62(4) == "betty"); } /************************************************/ void test63() { static auto x = foo63(); } int foo63() { pragma(msg, "Crash!"); return 2; } /************************************************/ dstring testd64(dstring input) { debug int x = 10; return "my"; } void test64() { static x = testd64("hello"); } /************************************************/ struct S65 { int i; int j = 3; } int foo(S65 s1, S65 s2) { return s1 == s2; } void test65() { static assert(foo(S65(1, 5), S65(1, 5)) == 1); static assert(foo(S65(1, 5), S65(1, 4)) == 0); } /************************************************/ struct S66 { int i; int j = 3; } int foo66(S66 s1) { return s1.j; } void test66() { static assert(foo66(S66(1, 5)) == 5); } /************************************************/ struct S67 { int i; int j = 3; } int foo67(S67 s1) { s1.j = 3; int i = (s1.j += 2); assert(i == 5); return s1.j + 4; } void test67() { static assert(foo67(S67(1, 5)) == 9); } /************************************************/ int foo68(int[] a) { a[1] = 3; int x = (a[0] += 7); assert(x == 8); return a[0] + a[1]; } void test68() { static assert(foo68( [1,5] ) == 11); } /************************************************/ int foo69(char[] a) { a[1] = 'c'; char x = (a[0] += 7); assert(x == 'h'); assert(x == a[0]); return a[0] + a[1] - 'a'; } void test69() { static assert(foo69(['a', 'b']) == 'j'); } /************************************************/ int foo70(int[string] a) { a["world"] = 5; auto x = (a["hello"] += 7); assert(x == 10); assert(x == a["hello"]); return a["hello"] + a["betty"] + a["world"]; } void test70() { static assert(foo70(["hello":3, "betty":4]) == 19); } /************************************************/ size_t foo71(int[string] a) { return a.length; } void test71() { static assert(foo71(["hello":3, "betty":4]) == 2); } /************************************************/ string[] foo72(int[string] a) { return a.keys; } void test72() { static assert(foo72(["hello":3, "betty":4]) == ["hello", "betty"]); } /************************************************/ int[] foo73(int[string] a) { return a.values; } void test73() { static assert(foo73(["hello":3, "betty":4]) == [3, 4]); } /************************************************/ bool b74() { string a = "abc"; return (a[$-1] == 'c'); } const c74 = b74(); void test74() { assert(c74 == true); } /************************************************/ struct FormatSpec { uint leading; bool skip; uint width; char modifier; char format; uint formatStart; uint formatLength; uint length; } FormatSpec GetFormat(string s) { FormatSpec result; return result; } FormatSpec GetFormat2(string s) { FormatSpec result = FormatSpec(); result.length = 0; assert(result.length < s.length); while (result.length < s.length) { ++result.length; } return result; } void test75() { static FormatSpec spec = GetFormat("asd"); assert(spec.leading == 0); assert(spec.modifier == char.init); static FormatSpec spec2 = GetFormat2("asd"); assert(spec2.length == 3); } /************************************************/ int f76() { int[3] a = void; a[0] = 1; assert(a[0] == 1); return 1; } const i76 = f76(); void test76() { } /************************************************/ struct V77 { int a; int b; } V77 f77() { int q = 0; int unused; int unused2; return V77(q, 0); } void test77() { const w = f77(); const v = f77().b; } /************************************************/ struct Bar78 { int x; } int foo78() { Bar78 b = Bar78.init; Bar78 c; b.x = 1; b = bar(b); return b.x; } Bar78 bar(Bar78 b) { return b; } void test78() { static x = foo78(); } /************************************************/ struct Bar79 { int y,x; } int foo79() { Bar79 b = Bar79.init; b.x = 100; for (size_t i = 0; i < b.x; i++) { } b.x++; b.x = b.x + 1; return b.x; } void test79() { static x = foo79(); printf("x = %d\n", x); assert(x == 102); } /************************************************/ void test80() { } /************************************************/ string foo81() { return ""; } string rod81(string[] a) { return a[0]; } void test81() { static x = rod81([foo81(), ""]); assert(x == ""); } /************************************************/ struct S82 { string name; } const S82 item82 = {"item"}; string mixItemList82() { return item82.name; } const string s82 = mixItemList82(); void test82() { assert(s82 == "item"); } /************************************************/ struct S83 { string name; } const S83[] items83 = [ {"item"}, ]; string mixItemList83() { string s; foreach (item; items83) s ~= item.name; return s; } const string s83 = mixItemList83(); void test83() { assert(s83 == "item"); } /************************************************/ struct S84 { int a; } int func84() { S84 [] s = [S84(7)]; return s[0].a; // Error: cannot evaluate func() at compile time } void test84() { const int x = func84(); assert(x == 7); } /************************************************/ struct S85 { int a; } size_t func85() { S85 [] s; s ~= S85(7); return s.length; } void test85() { const size_t x = func85(); assert(x == 1); } /************************************************/ struct Bar86 { int x; char[] s; } char[] foo86() { Bar86 bar; return bar.s; } void test86() { static x = foo86(); assert(x == null); } /************************************************/ struct Bar87 { int x; } int foo87() { Bar87 bar; bar.x += 1; bar.x++; return bar.x; } void test87() { static x = foo87(); assert(x == 2); } /************************************************/ int foo88() { char[] s; int i; if (s) { i |= 1; } if (s == null) { i |= 2; } if (s is null) { i |= 4; } if (s == "") { i |= 8; } if (s.length) { i |= 16; } if (s == ['c'][0..0]) { i |= 32; } if (null == s) { i |= 64; } if (null is s) { i |= 128; } if ("" == s) { i |= 256; } if (['c'][0..0] == s) { i |= 512; } return i; } void test88() { static x = foo88(); printf("x = %x\n", x); assert(x == (2|4|8|32|64|128|256|512)); } /************************************************/ template Tuple89(T...) { alias T val; } alias Tuple89!(int) Tup89; string gen89() { foreach (i, type; Tup89.val) { assert(i == 0); assert(is(type == int)); } return null; } void test89() { static const string text = gen89(); assert(text is null); } /************************************************/ string bar90(string z) { return z; } string foo90(string a, string b) { string f = a.length == 1 ? a: foo90("B", "C"); string g = b.length == 1 ? b: bar90(foo90("YYY", "A")); return f; } void test90() { static const string xxx = foo90("A", "xxx"); printf("%.*s\n", cast(int)xxx.length, xxx.ptr); assert(xxx == "A"); } /************************************************/ struct PR91 { } int foo91() { PR91 pr; pr = PR91(); return 0; } void test91() { static const i = foo91(); } /************************************************/ char find92(immutable(char)[7] buf) { return buf[3]; } void test92() { static const pos = find92("abcdefg"); assert(pos == 'd'); } /************************************************/ static string hello93() { string result = ""; int i = 0; for (;;) { result ~= `abc`; i += 1; if (i == 3) break; } return result; } void test93() { static string s = hello93(); assert(s == "abcabcabc"); } /************************************************/ int foo94 (string[] list, string s) { if (list.length == 0) return 1; else { return 2 + foo94(list[1..$], list[0]); } } void test94() { printf("test94\n"); static const int x = foo94(["a", "b"], ""); assert(x == 5); } /************************************************/ char[] func95(immutable char[] s) { char[] u = "".dup; u ~= s; u = u ~ s; return u; } void test95() { mixin(func95("{}")); } /************************************************/ char[] func96(string s) { char[] u = "".dup; u ~= s; u = u ~ s; return u; } void test96() { mixin(func96("{}")); } /************************************************/ string foo97() { string a; a ~= "abc"; // ok string[] b; b ~= "abc"; // ok string[][] c; c ~= ["abc", "def"]; string[][] d = []; d ~= ["abc", "def"]; // ok return "abc"; } void test97() { static const xx97 = foo97(); } /************************************************/ immutable(int)[] foo98(immutable(int)[][] ss) { immutable(int)[] r; r ~= ss[0]; // problem here return r; } void test98() { const r = foo98([[1], [2]]); } /************************************************/ struct Number { public int value; static Number opCall(int value) { Number n = void; n.value = value; return n; } } class Crash { Number number = Number(0); } void test99() { } /************************************************/ int[] map100 = ([4:true, 5:true]).keys; bool[] foo100 = ([4:true, 5:true]).values; void test100() { } /************************************************/ int foo101() { immutable bool [int] map = [4:true, 5:true]; foreach (x; map.keys) {} return 3; } static int x101 = foo101(); void test101() { } /************************************************/ int foo102() { foreach (i; 0 .. 1) return 1; return 0; } static assert(foo102() == 1); int bar102() { foreach_reverse (i; 0 .. 1) return 1; return 0; } static assert(bar102() == 1); void test102() { } /************************************************/ int foo103() { foreach (c; '0' .. '9') { } foreach_reverse (c; '9' .. '0') { } return 0; } enum x103 = foo103(); void test103() { } /************************************************/ struct S { int x; char y; } // Functions which should fail CTFE int badfoo() { S[2] c; int w = 4; c[w].x = 6; // array bounds error return 7; } int badglobal = 1; int badfoo3() { S[2] c; c[badglobal].x = 6; // global index error return 7; } int badfoo4() { static S[2] c; c[0].x = 6; // Cannot access static return 7; } /+ // This doesn't compile at runtime int badfoo5() { S[] c = void; c[0].x = 6; // c is uninitialized, and not a static array. return 1; } +/ int badfoo6() { S[] b = [S(7), S(15), S(56), S(12)]; b[-2..4] = S(17); // exceeding (negative) array bounds return 1; } int badfoo7() { S[] b = [S(7), S(15), S(56), S(12), S(67)]; S[] c = [S(17), S(4)]; b[1..4] = c[]; // slice mismatch in dynamic array return 1; } int badfoo8() { S[] b; b[1..3] = [S(17), S(4)]; // slice assign to uninitialized dynamic array return 1; } template Compileable(int z) { bool OK = true;} static assert(!is(typeof(Compileable!(badfoo()).OK))); static assert(!is(typeof(Compileable!( (){ S[] c; return c[7].x; // uninitialized error }()).OK ))); static assert( is(typeof(Compileable!(0).OK))); static assert(!is(typeof(Compileable!(badfoo3()).OK))); static assert(!is(typeof(Compileable!(badfoo4()).OK))); //static assert(!is(typeof(Compileable!(badfoo5()).OK))); static assert(!is(typeof(Compileable!(badfoo6()).OK))); static assert(!is(typeof(Compileable!(badfoo7()).OK))); static assert(!is(typeof(Compileable!(badfoo8()).OK))); // Functions which should pass CTFE int goodfoo1() { int[8] w; // use static array in CTFE w[] = 7; // full slice assign w[$ - 1] = 538; // use of $ in index assignment assert(w[6] == 7); return w[7]; } static assert(goodfoo1() == 538); int goodfoo2() { S[4] w = S(101); // Block-initialize array of structs w[$ - 2].x = 917; // use $ in index member assignment w[$ - 2].y = 58; // this must not clobber the prev assignment return w[2].x; // check we got the correct one } static assert(goodfoo2() == 917); static assert(is(typeof(Compileable!( (){ S[4] w = void; // uninitialized array of structs w[$ - 2].x = 217; // initialize one member return w[2].x; }()).OK ))); int goodfoo4() { S[4] b = [S(7), S(15), S(56), S(12)]; // assign from array literal assert(b[3] == S(12)); return b[2].x - 55; } static assert(goodfoo4()==1); int goodfoo5() { S[4] b = [S(7), S(15), S(56), S(12)]; b[0..2] = [S(2), S(6)]; // slice assignment from array literal assert(b[3] == S(12)); assert(b[1] == S(6)); return b[0].x; } static assert(goodfoo5() == 2); static assert(goodfoo5() == 2); // check for memory corruption int goodfoo6() { S[6] b = void; b[2..5] = [S(2), S(6), S(17)]; // slice assign to uninitialized var assert(b[4] == S(17)); return b[3].x; } static assert(goodfoo6() == 6); int goodfoo7() { S[8] b = void; b[2..5] = S(217); // slice assign to uninitialized var assert(b[4] == S(217)); return b[3].x; } static assert(goodfoo7() == 217); int goodfoo8() { S[] b = [S(7), S(15), S(56), S(12), S(67)]; b[2..4] = S(17); // dynamic array block slice assign assert(b[3] == S(17)); assert(b[4] == S(67)); return b[0].x; } static assert(goodfoo8() == 7); // --------- CTFE MEMBER FUNCTION TESTS -------- struct Q { int x; char y; int opOpAssign(string op)(int w) if (op == "+") { x += w; return x + w; } Q opOpAssign(string op)(int w) if (op == "-") { x -= w; return this; } int boo() { return 4; } int coo() { return x; } int foo() { return coo(); } int doo(int a) { Q z = Q(a, 'x'); z.x += 5; return z.coo() + 3 * x; } void goo(int z) { x = z; } int hoo(int y, int z) { return y + z; } void joo(int z) { x += z; } } int memtest1() { Q b = Q(15, 'a'); return b.hoo(3, 16); // simple const function } static assert(memtest1() == 19); int memtest2() { Q b = Q(15, 'x'); b.x -= 10; return b.coo(); } static assert(memtest2() == 5); int memtest3() { Q b = Q(15, 'x'); b.x -= 10; return b.foo(); } static assert(memtest3() == 5); int memtest4() { Q b = Q(12, 'x'); return b.doo(514); } static assert(memtest4() == 519 + 3 * 12); int memtest5() { Q b = Q(132, 'x'); b.goo(4178); // Call modifying member return b.x; } static assert(memtest5() == 4178); int memtest6() { Q q = Q(1); q += 3; // operator overloading return q.x; } static assert(memtest6() == 4); static assert(!is(typeof(Compileable!(Q += 2).OK))); // Mustn't cause segfault int memtest7() { Q q = Q(57); q -= 35; return q.x; } static assert(memtest7() == 57 - 35); int memtest8() { Q[3] w; w[2].x = 17; w[2].joo(6); // Modify member of array w[1].x += 18; return w[2].coo(); } static assert(memtest8() == 6 + 17); // --------- CTFE REF PASSING TESTS -------- // https://issues.dlang.org/show_bug.cgi?id=1950 - CTFE doesn't work correctly for structs passed by ref struct S1950 { int x; } int foo1950() { S1950 s = S1950(5); // explicitly initialized bar1950(s); return s.x; } void bar1950(ref S1950 w) { w.x = 10; } static assert(foo1950() == 10); // OK <- Fails, x is 0 int foo1950b() { S1950 s; // uninitialized bar1950(s); return s.x; } static assert(foo1950b() == 10); // OK <- Fails, x is 0 // More extreme case, related to 1950 void bar1950c(ref int w) { w = 87; } int foo1950c() { int[5] x; x[] = 56; bar1950c(x[1]); // Non-trivial ref parameters return x[1]; } static assert(foo1950c() == 87); void bar1950d(ref int[] w) { w[1..$] = 87; w[0] += 15; } int foo1950d() { int[] x = [1, 2, 3, 4, 5]; x[1..$] = 56; bar1950d(x); // Non-trivial ref parameters assert(x[0] == 16); return x[1]; } static assert(foo1950d() == 87); // Nested functions int nested(int x) { int y = 3; int inner(int w) { int z = 2; ++z; y += w; return x + 3; } int z = inner(14); assert(y == 17); inner(8); assert(y == 17 + 8); return z + y; } static assert(nested(7) == 17 + 8 + 10); static assert(nested(7) == 17 + 8 + 10); // Recursive nested functions int nested2(int x) { int y = 3; int inner(int w) { int z = 2; ++z; ++y; if (w <= 1) return x + 3; else return inner(w - 1); } int z = inner(14); assert(y == 17); inner(8); assert(y == 17 + 8); return z + y; } static assert(nested2(7) == 17 + 8 + 10); // https://issues.dlang.org/show_bug.cgi?id=1605 // D1 & D2. break in switch with goto breaks in ctfe int bug1605() { int i = 0; while (true) { goto LABEL; LABEL: if (i != 0) return i; i = 27; } assert(i == 27); return 88; // unreachable } static assert(bug1605() == 27); // https://issues.dlang.org/show_bug.cgi?id=2564 // D2 only. CTFE: the index in a tuple foreach is uninitialized (bogus error) // NOTE: Beware of optimizer bug 3264. int bug2564() { enum int Q = 0; string [2] s = ["a", "b"]; assert(s[Q].dup == "a"); return 0; } static int bug2564b = bug2564(); // https://issues.dlang.org/show_bug.cgi?id=1461 // D1 + D2. Local variable as template alias parameter breaks CTFE void bug1461() { int x; static assert(Gen1461!(x).generate() == null); } template Gen1461(alias A) { string generate() { return null; } } /************************************************/ string foo104(string[] a...) { string result = ""; foreach (s; a) result ~= s; return result; } mixin (foo104("int ", "x;")); /************************************************/ struct SwineFlu { int a; int b; } struct Infection { SwineFlu y; } struct IveGotSwineFlu { Infection x; int z; int oink() { return x.y.a + 10; } } int quarantine() { IveGotSwineFlu d; return d.oink(); } struct Mexico { Infection x; int z = 2; int oink() { return z + x.y.b; } } int mediafrenzy() { Mexico m; return m.oink; } static assert(quarantine() == 10); static assert(mediafrenzy() == 2); /************************************************/ int ctfeArrayTest(int z) { int[] a = new int[z]; a[$ - 3] = 6; assert(a.length == z); return a[$ - 3]; } static assert(ctfeArrayTest(15) == 6); /************************************************/ char bugzilla1298() { char [4] q = "abcd".dup; char [4] r = ['a', 'b', 'c', 'd']; assert(q == r); q[0..2] = "xy"; q[2] += 3; return q[2]; } static assert(bugzilla1298() == 'f'); int bugzilla1790(Types...)() { foreach (T; Types) { } return 0; } const int bugs1790 = bugzilla1790!("")(); char ctfeStrTest1() { char [8] s = void; s[2..4] = 'x'; assert(s.length == 8); return s[3]; } static assert(ctfeStrTest1() == 'x'); //--------- DELEGATE TESTS ------ // Function + delegate literals inside CTFE int delegtest1() { assert(function int(int a){ return 7 + a; }(16) == 23); return delegate int(int a){ return 7 + a; }(6); } int delegtest2() { int innerfunc1() { return delegate int(int a){ return 7 + a; }(6); } int delegate() f = &innerfunc1; return 3 * f(); } int delegtest3() { int function() f = &delegtest1; return 3 * f(); } struct DelegStruct { int a; int bar(int x) { return a + x; } } int delegtest4() { DelegStruct s; s.a = 5; auto f = &s.bar; return f(3); } alias int delegate(int) DelegType; // Test arrays of delegates int delegtest5() { DelegStruct s; s.a = 5; DelegType[4] w; w[] = &s.bar; return w[2](3); } // Test arrays of structs of delegates struct FoolishStruct { DelegType z; } int delegtest6() { DelegStruct s; s.a = 5; FoolishStruct[3] k; DelegType u = &s.bar; k[1].z = u; return k[1].z(3); } static assert(delegtest1() == 13); static assert(delegtest2() == 39); static assert(delegtest3() == 39); static assert(delegtest4() == 8); static assert(delegtest5() == 8); static assert(delegtest6() == 8); // Function + delegate literals, module scope static assert(function int(int a){ return 17 + a; }(16) == 33); static assert( (int a){ return 7 + a; }(16) == 23); // --- Test lazy --- int lazyTest1(lazy int y) { return y + 1; } int lazyTest2(int x) { return lazyTest1(x); } static assert(lazyTest1(7) == 8); static assert(lazyTest2(17) == 18); /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=4020 // https://issues.dlang.org/show_bug.cgi?id=4027 // D2 only struct PostblitCrash { int x; mixin("this(this) { ++x; }"); } int bug4020() { PostblitCrash f; f.x = 3; f = f; f = f; return f.x; } static assert(bug4020() == 5); string delegate() bug4027(string s) { return { return s; }; } // If it compiles, it must not generate wrong code on D2. static if (is(typeof((){ static const s = bug4027("aaa")(); }()))) { static assert(bug4027("aaa")() == "aaa"); static assert(bug4027("bbb")() == "bbb"); } // --- void bug4004a(ref int a) { assert(a == 7); a += 3; } void bug4004b(ref int b) { b = 7; bug4004a(b); } int bug4004c() { int offset = 5; bug4004b(offset); return offset; } static assert(bug4004c() == 10); // --- int bug4019() { int[int] aa; aa[1] = 2; aa[4] = 6; return aa[1] + aa[4]; } static assert(bug4019() == 8); // --- string delegate() bug4029a() { return { return "abc"[]; }; } string bug4029() { return bug4029a()(); } static assert(bug4029() == "abc"); /************************************************/ int bug4078() { int[] arr = new int[1]; return arr[0]; } static assert(bug4078() == 0); int bug4052() { int[] arr = new int[1]; int s; foreach (x; arr) s += x; foreach (x; arr) s += x * x; return 4052; } static assert(bug4052() == 4052); int bug4252() { char [] s = "abc".dup; s[15] = 'd'; // Array bounds error return 3; } static assert(!is(typeof(Compileable!(bug4252())))); size_t setlen1() { int[] w = new int[4]; w[] = 7; w.length = 6; return 21 + w.length; } static assert(setlen1() == 27); size_t setlen2() { int[] w; w.length = 15; assert(w[3] == 0); w[2] = 8; w[14] = 7; w.length = 12; // check shrinking assert(w[2] == 8); return 2 + w.length; } static assert(setlen2() == 14); /************************************************/ int bug4257(ref int x) { return 3; } int bug4257c(int x) { return 3; } struct Struct4257 { int foo() { return 2; } } void bug4257b() { int y; static assert(!is(typeof(Compileable!(bug4257(y))))); static assert(!is(typeof(Compileable!(bug4257c(y))))); Struct4257 s; static assert(!is(typeof(Compileable!(s.foo())))); } /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=5117 static int dummy5117 = test5117(); int test5117() { S5117 s; s.change(); assert(s.value == 1); // (7) succeeds R5117 r; r.s.change(); assert(r.s.value == 1); // (11) fails, value == 0 return 0; } struct S5117 { int value; void change() { value = 1; } } struct R5117 { S5117 s; } /************************************************/ enum dummy5117b = test5117b(); int test5117b() { S5117b s; getRef5117b(s).change(); assert(s.value == 1); // fails, value == 0 return 0; } ref S5117b getRef5117b(return ref S5117b s) { return s; } struct S5117b { int value; void change() { value = 1; } } /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=6439 struct A6439 { this(uint a, uint b) { begin = a; end = b; } union { struct { uint begin, end; } uint[2] arr; } } void test6439() { enum y = A6439(10, 20); A6439 y2 = A6439(10, 20); assert(y2.begin == y.begin && y2.end == y.end); //passes assert(y.arr != [0,0]); assert(y.arr == [10,20]); assert(y.arr == y2.arr); } /************************************************/ // from tests/fail_compilation/fail147 static assert(!is(typeof(Compileable!( (int i){ int x = void; ++x; // used before initialization return i + x; }(3) )))); // https://issues.dlang.org/show_bug.cgi?id=6504 regression void test6504() { for (int i = 0; i < 3; ++i) { char[] x2 = "xxx" ~ ['c']; assert(x2[1] == 'x'); x2[1] = 'q'; } } // https://issues.dlang.org/show_bug.cgi?id=8818 regression void test8818() { static bool test() { string op1 = "aa"; string op2 = "b"; assert("b" >= "aa"); assert(op2 >= op1); return true; } static assert(test()); assert(test()); } /************************************************/ struct Test104Node { int val; Test104Node* next; } Test104Node* CreateList(int[] arr) { if (!arr.length) return null; Test104Node* ret = new Test104Node; ret.val = arr[0]; ret.next = CreateList(arr[1..$]); return ret; } const(Test104Node)* root = CreateList([1, 2, 3, 4, 5]); void test104() { assert(root.val == 1); assert(root.next.val == 2); assert(root.next.next.val == 3); assert(root.next.next.next.val == 4); assert(root.next.next.next.next.val == 5); } /************************************************/ interface ITest105a { string test105a() const; } class Test105a : ITest105a { char a; int b; char c = 'C'; int d = 42; string test105a() const { return "test105a"; } } interface ITest105b { string test105b() const; } class Test105b : Test105a, ITest105b { char e; int f; this(char _e, int _f, char _a, int _b) pure { e = _e; f = _f; a = _a; b = _b; } string test105b() const { return "test105b"; } } const Test105b t105b = new Test105b('E', 88, 'A', 99); const Test105a t105a = new Test105b('E', 88, 'A', 99); const ITest105b t105ib = new Test105b('E', 88, 'A', 99); const ITest105a t105ia = new Test105b('E', 88, 'A', 99); __gshared Test105b t105gs = new Test105b('E', 88, 'A', 99); shared Test105b t105bs = new shared(Test105b)('E', 88, 'A', 99); immutable Test105b t105bi = new immutable(Test105b)('E', 88, 'A', 99); void test105() { assert(t105b.a == 'A'); assert(t105b.b == 99); assert(t105b.c == 'C'); assert(t105b.d == 42); assert(t105b.e == 'E'); assert(t105b.f == 88); assert(t105b.test105a() == "test105a"); assert(t105b.test105b() == "test105b"); assert(t105a.a == 'A'); assert(t105a.b == 99); assert(t105a.c == 'C'); assert(t105a.d == 42); assert(t105a.test105a() == "test105a"); assert(t105ia.test105a() == "test105a"); assert(t105ib.test105b() == "test105b"); assert(t105a.classinfo is Test105b.classinfo); //t105b.d = -1; //assert(t105b.d == -1); //assert(t105a.d == 42); assert(t105gs.a == 'A'); assert(t105gs.b == 99); assert(t105gs.c == 'C'); assert(t105gs.d == 42); assert(t105gs.e == 'E'); assert(t105gs.f == 88); assert(t105gs.test105a() == "test105a"); assert(t105gs.test105b() == "test105b"); assert(t105bs.a == 'A'); assert(t105bs.b == 99); assert(t105bs.c == 'C'); assert(t105bs.d == 42); assert(t105bs.e == 'E'); assert(t105bs.f == 88); assert(t105bi.a == 'A'); assert(t105bi.b == 99); assert(t105bi.c == 'C'); assert(t105bi.d == 42); assert(t105bi.e == 'E'); assert(t105bi.f == 88); assert(t105bi.test105a() == "test105a"); assert(t105bi.test105b() == "test105b"); } int bug9938() { assert(t105ia.test105a() == "test105a"); return 1; } static assert(t105ia.test105a() == "test105a"); static assert(bug9938()); /************************************************/ struct Test106 { Test106* f; Test106* s; } Test106* ctfe106() { auto s = new Test106; auto s2 = new Test106; s.f = s2; s.s = s2; assert(s.f is s.s); return s; } const(Test106)* t106 = ctfe106(); void test106() { assert(t106.f is t106.s); } /************************************************/ class Test107 { Test107 a; Test107 b; this() { } this(int) { a = new Test107(); b = a; assert(a is b); } } const Test107 t107 = new Test107(1); void test107() { assert(t107.a is t107.b); } /************************************************/ /* interface Getter { int getNum() const; } class Test108 : Getter { int f; this(int v) inout { f = v; } int getNum() const { return f; } } enum const(Test108) t108 = new Test108(38); void test108() { const Test108 obj = t108; assert(obj.classinfo is Test108.classinfo); assert(obj.f == 38); const Getter iobj = t108; assert(iobj.getNum() == 38); assert((cast(Object)iobj).classinfo is Test108.classinfo); assert(t108 is t108); } */ /***** https://issues.dlang.org/show_bug.cgi?id=5678 *****/ /* struct Bug5678 { this(int) {} } enum const(Bug5678)* b5678 = new const(Bug5678)(0); void test5678() { assert(b5678 is b5678); }*/ /************************************************/ class Test109C { this(){ this.c = this; } Test109C c; } const t109c = new Test109C(); struct Test109S { this(int){ this.s = &this; } Test109S* s; } const t109s = new Test109S(0); pragma(msg, t109s); // Make sure there is no infinite recursion. void test109() { assert(t109c.c is t109c); assert(t109s.s is t109s); } /************************************************/ struct Test110f { int f1; Test110s f2; } struct Test110s { this(int, int, int){} } auto test110 = [Test110f(1, Test110s(1, 2, 3))]; /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=6907 // FIXME: Shouldn't this go in core.memory now that `delete` has been removed? int test6907() { import core.memory : __delete; int dtor1; class C { ~this() { ++dtor1; } } // delete on Object { Object o; if (!__ctfe) __delete(o); } { scope o = new Object(); } { Object o = new Object(); if (!__ctfe) __delete(o); } // delete on C { C c; if (!__ctfe) __delete(c); } { { scope c = new C(); } assert(dtor1 == 1); } { { scope Object o = new C(); } assert(dtor1 == 2); } { C c = new C(); if (__ctfe) { c.__dtor(); c = null; } else __delete(c); assert(dtor1 == 3); } { Object o = new C(); if (__ctfe) { (cast(C)o).__dtor(); o = null; } else __delete(o); assert(dtor1 == 4); } int dtor2; struct S1 { ~this() { ++dtor2; } } // delete on S1 { S1* p; // https://issues.dlang.org/show_bug.cgi?id=22779 // Uncomment after druntime fix version (none) { if (!__ctfe) __delete(p); } } { S1* p = new S1(); if (__ctfe) { (*p).__dtor(); destroy(p); } else __delete(p); assert(dtor2 == 1); } // delete on S1[] { S1[] a = [S1(), S1()]; if (__ctfe) { a[1].__dtor(); a[0].__dtor(); destroy(a); } else __delete(a); assert(dtor2 == 3); } return 1; } static assert(test6907()); /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=9023 bool test9023() { string[][string] aas; assert(aas.length == 0); aas["a"] ~= "anything"; assert(aas.length == 1); assert(aas["a"] == ["anything"]); aas["a"] ~= "more"; assert(aas.length == 1); assert(aas["a"] == ["anything", "more"]); int[int] aan; assert(aan.length == 0); auto x = aan[0]++; assert(x == 0); assert(aan.length == 1); assert(aan[0] == 1); return true; } static assert(test9023()); /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=15817 S[] split15817(S)(S s) { size_t istart; S[] result; foreach (i, c ; s) result ~= s[istart .. i]; return result; } int test15817() { auto targets = `a1`.split15817; uint[string] counts; foreach (a; targets) counts[a]++; assert(counts == ["":1u, "a":1]); return 1; } static assert(test15817()); /************************************************/ interface IBug9954 { string foo() const; } class Bug9954 : IBug9954 { string foo() const { return "hello"; } } IBug9954 makeIBug9954() { return new Bug9954; } const IBug9954 b9954 = makeIBug9954(); void test9954() { assert(b9954.foo() == "hello"); } /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=10483 struct Bug10483 { int[3][4] val; } struct Outer10483 { Bug10483 p = Bug10483(67); } int k10483a = Outer10483.init.p.val[2][2]; // ICE(expression.c) void test10483() { int k10483b = Outer10483.init.p.val[2][2]; // Segfault (backend/type.c) } /************************************************/ struct S10669 { uint x; } static const S10669 iid0_10669 = S10669(0); class C10669 { static const S10669 iid1_10669 = S10669(1); }; const S10669 IID0_10669 = iid0_10669; const S10669 IID1_10669 = C10669.iid1_10669; /************************************************/ TypeInfo getTi() { return typeid(int); } auto t112 = getTi(); void test112() { assert(t112.toString() == "int"); } /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=10687 enum Foo10687 : uint { A, B, C, D, E } immutable uint[5][] m10687 = [[0, 1, 2, 3, 4]]; void test10687() { static immutable uint[5] a1 = [0, 1, 2, 3, 4]; auto a2 = cast(immutable(Foo10687[5]))a1; static a3 = cast(immutable(Foo10687[5]))a1; auto foos1 = cast(immutable(Foo10687[5][]))m10687; static foos2 = cast(immutable(Foo10687[5][]))m10687; } /************************************************/ void test113() { import core.math; static void compare(real a, real b) { assert(fabs(a - b) < 128 * real.epsilon); } static if (__traits(compiles, (){ enum real ctval1 = yl2x(3.14, 1); })) { enum real ctval1 = yl2x(3.14, 1); enum real ctval2 = yl2x(2e1500L, 3); enum real ctval3 = yl2x(1, 5); real rtval1 = yl2x(3.14, 1); real rtval2 = yl2x(2e1500L, 3); real rtval3 = yl2x(1, 5); compare(ctval1, rtval1); compare(ctval2, rtval2); compare(ctval3, rtval3); } static if (__traits(compiles, (){ enum real ctval4 = yl2xp1(3.14, 1); })) { enum real ctval4 = yl2xp1(3.14, 1); enum real ctval5 = yl2xp1(2e1500L, 3); enum real ctval6 = yl2xp1(1, 5); real rtval4 = yl2xp1(3.14, 1); real rtval5 = yl2xp1(2e1500L, 3); real rtval6 = yl2xp1(1, 5); compare(ctval4, rtval4); compare(ctval5, rtval5); compare(ctval6, rtval6); } } /************************************************/ bool test114() { string fizzBuzz() { string result = "fizz "; return result ~= "buzz"; } assert(fizzBuzz() == "fizz buzz"); return true; } static assert(test114()); /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=14140 struct S14140 { union { float[3][1] A; float[3] flat; } this(in float[] args...) { flat[] = args[]; } } class C14140 { union { float[3][1] A; float[3] flat; } this(in float[] args...) { flat[] = args[]; } } immutable s14140 = S14140(0, 1, 0); const c14140 = new C14140(0, 1, 0); void test14140() { auto s = s14140; assert(s.flat == [0, 1, 0]); auto c = c14140; assert(c.flat == [0, 1, 0]); } /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=14862 struct S14862 { union { struct { uint hi, lo; } ulong data; } this(ulong data) { this.data = data; } } void test14862() { S14862 s14862 = S14862(123UL); enum S14862 e14862 = S14862(123UL); static S14862 g14862 = S14862(123UL); assert(s14862.data == 123UL); // OK assert(e14862.data == 123UL); // OK assert(g14862.data == 123UL); // OK <- fail } /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=15681 void test15681() { static struct A { float value; } static struct S { A[2] values; this(float) { values[0].value = 0; values[1].value = 1; } } auto s1 = S(1.0f); assert(s1.values[0].value == 0); // OK assert(s1.values[1].value == 1); // OK enum s2 = S(1.0f); static assert(s2.values[0].value == 0); // OK <- NG static assert(s2.values[1].value == 1); // OK assert(s2.values[0].value == 0); // OK <- NG assert(s2.values[1].value == 1); // OK } /************************************************/ // toPrec void testToPrec() { import core.math; enum real ctpir = 0xc.90fdaa22168c235p-2; enum double ctpid = 0x1.921fb54442d18p+1; enum float ctpif = 0x1.921fb6p+1; static assert(toPrec!float(ctpir) == ctpif); static assert(toPrec!double(ctpir) == ctpid); static assert(toPrec!real(ctpir) == ctpir); static assert(toPrec!float(ctpid) == ctpif); static assert(toPrec!double(ctpid) == ctpid); static assert(toPrec!real(ctpid) == ctpid); static assert(toPrec!float(ctpif) == ctpif); static assert(toPrec!double(ctpif) == ctpif); static assert(toPrec!real(ctpif) == ctpif); assert(toPrec!float(ctpir) == ctpif); assert(toPrec!double(ctpir) == ctpid); assert(toPrec!real(ctpir) == ctpir); assert(toPrec!float(ctpid) == ctpif); assert(toPrec!double(ctpid) == ctpid); assert(toPrec!real(ctpid) == ctpid); assert(toPrec!float(ctpif) == ctpif); assert(toPrec!double(ctpif) == ctpif); assert(toPrec!real(ctpif) == ctpif); static real rtpir = 0xc.90fdaa22168c235p-2; static double rtpid = 0x1.921fb54442d18p+1; static float rtpif = 0x1.921fb6p+1; assert(toPrec!float(rtpir) == rtpif); assert(toPrec!double(rtpir) == rtpid); assert(toPrec!real(rtpir) == rtpir); assert(toPrec!float(rtpid) == rtpif); assert(toPrec!double(rtpid) == rtpid); assert(toPrec!real(rtpid) == rtpid); assert(toPrec!float(rtpif) == rtpif); assert(toPrec!double(rtpif) == rtpif); assert(toPrec!real(rtpif) == rtpif); } /************************************************/ auto test20366() { const(char)[] s = ['h', 'e', 'l', '\xef', '\xbd', '\x8c', 'o']; foreach_reverse (dchar c; s) { } return true; } static assert(test20366()); /************************************************/ bool test20400() { char[] s = cast(char[])"1234"; char[] ret = s[2 .. $]; ret.length += 1; ret[$-1] = '5'; assert(ret == "345"); return true; } static assert(test20400()); /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=21878 struct A21878 { int i; ref inout(int) opIndex(size_t idx) inout return { return i; } } struct B21878 { A21878[1] a; ref inout(int) opIndex(size_t idx) inout return { return a[0][idx]; } } bool ctfeFunc21878() { A21878 a; a[0] = 42; assert(a[0] == 42); // OK B21878 b; b[0] = 42; assert(b[0] == 42); // OK <- fails return true; } void test21878() { enum eval = ctfeFunc21878(); ctfeFunc21878(); // succeeds at runtime } /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=20133 void bar20133(ref string text) { text = text[1 .. $]; assert(text.length < 3); if (text.length == 2) assert(text == "oo"); if (text.length == 1) assert(text == "o"); if (text.length == 0) assert(text == ""); string tcopy = text; if (tcopy.length > 0) bar20133(tcopy); assert(tcopy.length < 2); if (tcopy.length == 1) assert(tcopy == "o"); if (tcopy.length == 0) assert(tcopy == ""); } void bar20133_2(ref string text) { auto ptext = &text; *ptext = text[1 .. $]; assert(text.length < 3); if (text.length == 2) assert(text == "oo"); if (text.length == 1) assert(text == "o"); if (text.length == 0) assert(text == ""); string tcopy = text; if (tcopy.length > 0) bar20133_2(tcopy); assert(tcopy.length < 2); if (tcopy.length == 1) assert(tcopy == "o"); if (tcopy.length == 0) assert(tcopy == ""); } alias fun20133 = { string input = "foo"; bar20133(input); assert(input == "oo"); return input; }; alias fun20133_2 = { string input = "foo"; bar20133_2(input); assert(input == "oo"); return input; }; void test20133() { enum ctest = fun20133(); enum ctest2 = fun20133_2(); auto rtest = fun20133(); auto rtest2 = fun20133_2(); } /************************************************/ // https://issues.dlang.org/show_bug.cgi?id=22530 class D22530 { } class C22530 { D22530 y = new D22530; alias y this; } void test22530() { // fixed static assert(cast(D22530)(new C22530) is null); static assert((1 ? cast(D22530)(new C22530) : new D22530) is null); // runtime version already works assert(cast(D22530)(new C22530) is null); assert((1 ? cast(D22530)(new C22530) : new D22530) is null); } /************************************************/ int main() { test1(); test2(); test3(); test4(); test5(); test6(); test7(); test8(); test9(); test10(); test11(); test12(); test13(); test14(); test15(); test16(); test17(); test18(); test19(); test20(); test21(); test22(); test23(); test24(); test25(); test26(); test27(); test28(); test29(); test30(); test31(); test32(); test33(); test34(); test35(); test36(); test37(); test38(); test39(); test40(); test41(); test42(); test43(); test44(); test45(); test46(); test47(); test48(); test49(); test50(); test51(); test52(); test53(); test54(); test55(); test56(); test57(); test58(); test59(); test60(); test61(); test62(); test63(); test64(); test65(); test66(); test67(); test68(); test69(); test70(); test71(); test72(); test73(); test74(); test75(); test76(); test77(); test78(); test79(); test80(); test81(); test82(); test83(); test84(); test85(); test86(); test87(); test88(); test89(); test90(); test91(); test92(); test93(); test94(); test95(); test96(); test97(); test98(); test99(); test100(); test101(); test102(); test103(); test104(); test105(); test106(); test107(); //test108(); test109(); test112(); test113(); test114(); test6439(); test6504(); test8818(); test6907(); test9023(); test15817(); test9954(); test14140(); test14862(); test15681(); test20366(); test20400(); test21878(); test20133(); test22530(); printf("Success\n"); return 0; }