blob: 6b1e89b65ff8e35e4561ce2a04d6396037a91d06 [file] [log] [blame]
/*
TEST_OUTPUT:
---
true
g
&Test109S(&Test109S(<recursion>))
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;
version(D_Version2) { mixin("return this;"); } else { mixin("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()
{
version(D_Version2) { mixin("enum int Q = 0;"); }else {mixin("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);
/************************************************/
version(D_Version2)
{
// 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);
}
}
/************************************************/
// 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();
test6439();
test6504();
test8818();
test6907();
test9023();
test15817();
test9954();
test14140();
test14862();
test15681();
test20366();
test20400();
test21878();
test20133();
test22530();
printf("Success\n");
return 0;
}