2804 lines
47 KiB
D
2804 lines
47 KiB
D
// REQUIRED_ARGS:
|
|
/*
|
|
TEST_OUTPUT:
|
|
---
|
|
null
|
|
---
|
|
*/
|
|
|
|
import core.stdc.stdio;
|
|
|
|
/*******************************************/
|
|
|
|
int bar(int a)
|
|
{
|
|
int foo(int b) { return b + 1; }
|
|
|
|
return foo(a);
|
|
}
|
|
|
|
void test1()
|
|
{
|
|
assert(bar(3) == 4);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
int bar2(int a)
|
|
{
|
|
static int c = 4;
|
|
|
|
int foo(int b) { return b + c + 1; }
|
|
|
|
return foo(a);
|
|
}
|
|
|
|
void test2()
|
|
{
|
|
assert(bar2(3) == 8);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
int bar3(int a)
|
|
{
|
|
static int foo(int b) { return b + 1; }
|
|
|
|
return foo(a);
|
|
}
|
|
|
|
void test3()
|
|
{
|
|
assert(bar3(3) == 4);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
int bar4(int a)
|
|
{
|
|
static int c = 4;
|
|
|
|
static int foo(int b) { return b + c + 1; }
|
|
|
|
return foo(a);
|
|
}
|
|
|
|
void test4()
|
|
{
|
|
assert(bar4(3) == 8);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
int bar5(int a)
|
|
{
|
|
int c = 4;
|
|
|
|
int foo(int b) { return b + c + 1; }
|
|
|
|
return c + foo(a);
|
|
}
|
|
|
|
void test5()
|
|
{
|
|
assert(bar5(3) == 12);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
int bar6(int a)
|
|
{
|
|
int c = 4;
|
|
|
|
int foob(int b) { return b + c + 1; }
|
|
int fooa(int b) { return foob(c + b) * 7; }
|
|
|
|
return fooa(a);
|
|
}
|
|
|
|
void test6()
|
|
{
|
|
assert(bar6(3) == 84);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
int bar7(int a)
|
|
{
|
|
static int c = 4;
|
|
|
|
static int foob(int b) { return b + c + 1; }
|
|
|
|
int function(int) fp = &foob;
|
|
|
|
return fp(a);
|
|
}
|
|
|
|
void test7()
|
|
{
|
|
assert(bar7(3) == 8);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
int bar8(int a)
|
|
{
|
|
int c = 4;
|
|
|
|
int foob(int b) { return b + c + 1; }
|
|
|
|
int delegate(int) fp = &foob;
|
|
|
|
return fp(a);
|
|
}
|
|
|
|
void test8()
|
|
{
|
|
assert(bar8(3) == 8);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
struct Abc9
|
|
{
|
|
int a;
|
|
int b;
|
|
int c = 7;
|
|
|
|
int bar(int x)
|
|
{
|
|
Abc9 *foo() { return &this; }
|
|
|
|
Abc9 *p = foo();
|
|
assert(p == &this);
|
|
return p.c + x;
|
|
}
|
|
}
|
|
|
|
void test9()
|
|
{
|
|
Abc9 x;
|
|
|
|
assert(x.bar(3) == 10);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class Abc10
|
|
{
|
|
int a;
|
|
int b;
|
|
int c = 7;
|
|
|
|
int bar(int x)
|
|
{
|
|
Abc10 foo() { return this; }
|
|
|
|
Abc10 p = foo();
|
|
assert(p == this);
|
|
return p.c + x;
|
|
}
|
|
|
|
}
|
|
|
|
void test10()
|
|
{
|
|
Abc10 x = new Abc10();
|
|
|
|
assert(x.bar(3) == 10);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
class Collection
|
|
{
|
|
int[3] array;
|
|
|
|
void opApply(void delegate(int) fp)
|
|
{
|
|
for (int i = 0; i < array.length; i++)
|
|
fp(array[i]);
|
|
}
|
|
}
|
|
|
|
int func11(Collection c)
|
|
{
|
|
int max = int.min;
|
|
|
|
void comp_max(int i)
|
|
{
|
|
if (i > max)
|
|
max = i;
|
|
}
|
|
|
|
c.opApply(&comp_max);
|
|
return max;
|
|
}
|
|
|
|
void test11()
|
|
{
|
|
Collection c = new Collection();
|
|
|
|
c.array[0] = 7;
|
|
c.array[1] = 26;
|
|
c.array[2] = 25;
|
|
|
|
int m = func11(c);
|
|
assert(m == 26);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void SimpleNestedFunction ()
|
|
{
|
|
int nest () { return 432; }
|
|
|
|
assert (nest () == 432);
|
|
int delegate () func = &nest;
|
|
assert (func () == 432);
|
|
}
|
|
|
|
void AccessParentScope ()
|
|
{
|
|
int value = 9;
|
|
|
|
int nest () { assert (value == 9); return 9; }
|
|
|
|
assert (nest () == 9);
|
|
}
|
|
|
|
void CrossNestedScope ()
|
|
{
|
|
int x = 45;
|
|
|
|
void foo () { assert (x == 45); }
|
|
void bar () { int z = 16; foo (); }
|
|
bar ();
|
|
}
|
|
|
|
void BadMultipleNested ()
|
|
{
|
|
int x;
|
|
|
|
void foo ()
|
|
{
|
|
void bar ()
|
|
{
|
|
//erroneous x = 4; // Should fail.
|
|
}
|
|
}
|
|
}
|
|
|
|
/* This one kind of depends upon memory layout. GlobalScopeSpoof should
|
|
be called with no "this" pointer; this is trying to ensure that
|
|
everything is working properly. Of course, in the DMD calling
|
|
convention it'll fail if the caller passes too much/little data. */
|
|
|
|
void GlobalScopeSpoof (int x, int y)
|
|
{
|
|
assert (x == y && y == 487);
|
|
}
|
|
|
|
void GlobalScope ()
|
|
{
|
|
void bar () { GlobalScopeSpoof (487, 487); }
|
|
bar ();
|
|
}
|
|
|
|
class TestClass
|
|
{
|
|
int x = 6400;
|
|
|
|
void foo ()
|
|
{
|
|
void bar () { assert (x == 6400); }
|
|
bar ();
|
|
}
|
|
}
|
|
|
|
void test12()
|
|
{
|
|
SimpleNestedFunction ();
|
|
AccessParentScope ();
|
|
CrossNestedScope ();
|
|
GlobalScope ();
|
|
(new TestClass).foo ();
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void test13()
|
|
{
|
|
struct Abc
|
|
{
|
|
int x = 3;
|
|
int y = 4;
|
|
}
|
|
|
|
Abc a;
|
|
|
|
assert(a.x == 3 && a.y == 4);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void test14()
|
|
{
|
|
struct Abc
|
|
{
|
|
int x = 3;
|
|
int y = 4;
|
|
|
|
int foo() { return y; }
|
|
}
|
|
|
|
Abc a;
|
|
|
|
assert(a.foo() == 4);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void test15()
|
|
{
|
|
static int z = 5;
|
|
|
|
struct Abc
|
|
{
|
|
int x = 3;
|
|
int y = 4;
|
|
|
|
int foo() { return y + z; }
|
|
}
|
|
|
|
Abc a;
|
|
|
|
assert(a.foo() == 9);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void test16()
|
|
{
|
|
static int z = 5;
|
|
|
|
static class Abc
|
|
{
|
|
int x = 3;
|
|
int y = 4;
|
|
|
|
int foo() { return y + z; }
|
|
}
|
|
|
|
Abc a = new Abc();
|
|
|
|
assert(a.foo() == 9);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void test17()
|
|
{
|
|
int function(int x) fp;
|
|
|
|
fp = function int(int y) { return y + 3; };
|
|
assert(fp(7) == 10);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void test18()
|
|
{
|
|
static int a = 3;
|
|
int function(int x) fp;
|
|
|
|
fp = function int(int y) { return y + a; };
|
|
assert(fp(7) == 10);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void test19()
|
|
{
|
|
int a = 3;
|
|
|
|
int delegate(int x) fp;
|
|
|
|
fp = delegate int(int y) { return y + a; };
|
|
assert(fp(7) == 10);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
class Collection20
|
|
{
|
|
int[3] array;
|
|
|
|
void opApply(void delegate(int) fp)
|
|
{
|
|
for (int i = 0; i < array.length; i++)
|
|
fp(array[i]);
|
|
}
|
|
}
|
|
|
|
int func20(Collection20 c)
|
|
{
|
|
int max = int.min;
|
|
|
|
c.opApply(delegate(int i) { if (i > max) max = i; });
|
|
return max;
|
|
}
|
|
|
|
void test20()
|
|
{
|
|
Collection20 c = new Collection20();
|
|
|
|
c.array[0] = 7;
|
|
c.array[1] = 26;
|
|
c.array[2] = 25;
|
|
|
|
int m = func20(c);
|
|
assert(m == 26);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
int bar21(int a)
|
|
{
|
|
int c = 3;
|
|
|
|
int foo(int b)
|
|
{
|
|
b += c; // 4 is added to b
|
|
c++; // bar.c is now 5
|
|
return b + c; // 12 is returned
|
|
}
|
|
c = 4;
|
|
int i = foo(a); // i is set to 12
|
|
return i + c; // returns 17
|
|
}
|
|
|
|
void test21()
|
|
{
|
|
int i = bar21(3); // i is assigned 17
|
|
assert(i == 17);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void foo22(void delegate() baz)
|
|
{
|
|
baz();
|
|
}
|
|
|
|
void bar22(int i)
|
|
{
|
|
int j = 14;
|
|
printf("%d,%d\n",i,j);
|
|
|
|
void fred()
|
|
{
|
|
printf("%d,%d\n",i,j);
|
|
assert(i == 12 && j == 14);
|
|
}
|
|
|
|
fred();
|
|
foo22(&fred);
|
|
}
|
|
|
|
void test22()
|
|
{
|
|
bar22(12);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void frelled(void delegate() baz)
|
|
{
|
|
baz();
|
|
}
|
|
|
|
class Foo23
|
|
{
|
|
void bar(int i)
|
|
{
|
|
int j = 14;
|
|
printf("%d,%d\n",i,j);
|
|
|
|
void fred()
|
|
{
|
|
printf("%d,%d\n",i,j);
|
|
assert(i == 12);
|
|
assert(j == 14);
|
|
}
|
|
|
|
frelled(&fred);
|
|
}
|
|
}
|
|
|
|
void test23()
|
|
{
|
|
Foo23 f = new Foo23();
|
|
|
|
f.bar(12);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void delegate () function (int x) store24;
|
|
|
|
void delegate () zoom24(int x)
|
|
{
|
|
return delegate void () { };
|
|
}
|
|
|
|
void test24()
|
|
{
|
|
store24 = &zoom24;
|
|
store24 (1) ();
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void test25()
|
|
{
|
|
delegate() { printf("stop the insanity!\n"); }();
|
|
delegate() { printf("stop the insanity! 2\n"); }();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
alias bool delegate(int) callback26;
|
|
|
|
|
|
bool foo26(callback26 a)
|
|
{
|
|
return a(12);
|
|
}
|
|
|
|
class Bar26
|
|
{
|
|
int func(int v)
|
|
{
|
|
printf("func(v=%d)\n", v);
|
|
foo26(delegate bool(int a)
|
|
{
|
|
printf("%d %d\n",a,v); return true;
|
|
assert(a == 12);
|
|
assert(v == 15);
|
|
assert(0);
|
|
} );
|
|
return v;
|
|
}
|
|
}
|
|
|
|
|
|
void test26()
|
|
{
|
|
Bar26 b = new Bar26();
|
|
|
|
b.func(15);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
class A27
|
|
{
|
|
uint myFunc()
|
|
{
|
|
uint myInt = 13;
|
|
uint mySubFunc()
|
|
{
|
|
return myInt;
|
|
}
|
|
return mySubFunc();
|
|
}
|
|
}
|
|
|
|
void test27()
|
|
{
|
|
A27 myInstance = new A27;
|
|
int i = myInstance.myFunc();
|
|
printf("%d\n", i);
|
|
assert(i == 13);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void Foo28(void delegate() call)
|
|
{
|
|
call();
|
|
}
|
|
|
|
class Bar28
|
|
{
|
|
int func()
|
|
{
|
|
int count = 0;
|
|
|
|
Foo28(delegate void() { ++count; } );
|
|
return count;
|
|
}
|
|
}
|
|
|
|
void test28()
|
|
{
|
|
Bar28 b = new Bar28();
|
|
int i = b.func();
|
|
assert(i == 1);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
class Foo29
|
|
{
|
|
void Func(void delegate() call)
|
|
{
|
|
for(int i = 0; i < 10; ++i)
|
|
call();
|
|
}
|
|
}
|
|
|
|
class Bar29
|
|
{
|
|
int Func()
|
|
{
|
|
int count = 0;
|
|
Foo29 ic = new Foo29();
|
|
|
|
ic.Func(delegate void() { ++count; } );
|
|
return count;
|
|
}
|
|
}
|
|
|
|
void test29()
|
|
{
|
|
Bar29 b = new Bar29();
|
|
int i = b.Func();
|
|
assert(i == 10);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
struct Foo30
|
|
{
|
|
int[] arr;
|
|
}
|
|
|
|
void Func30(Foo30 bar)
|
|
{
|
|
void InnerFunc(int x, int y)
|
|
{
|
|
int a = bar.arr[y]; // Ok
|
|
|
|
if(bar.arr[y]) // Access violation
|
|
{
|
|
}
|
|
}
|
|
|
|
InnerFunc(5,5);
|
|
}
|
|
|
|
|
|
void test30()
|
|
{
|
|
Foo30 abc;
|
|
|
|
abc.arr.length = 10;
|
|
Func30(abc);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void call31(int d, void delegate(int d) f)
|
|
{
|
|
assert(d == 100 || d == 200);
|
|
printf("d = %d\n", d);
|
|
f(d);
|
|
}
|
|
|
|
void test31()
|
|
{
|
|
call31(100, delegate void(int d1)
|
|
{
|
|
printf("d1 = %d\n", d1);
|
|
assert(d1 == 100);
|
|
call31(200, delegate void(int d2)
|
|
{
|
|
printf("d1 = %d\n", d1);
|
|
printf("d2 = %d\n", d2);
|
|
assert(d1 == 100);
|
|
assert(d2 == 200);
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void call32(int d, void delegate(int d) f)
|
|
{
|
|
assert(d == 100 || d == 200);
|
|
printf("d = %d\n", d);
|
|
f(d);
|
|
}
|
|
|
|
void test32()
|
|
{
|
|
call32(100, delegate void(int d1)
|
|
{
|
|
int a = 3;
|
|
int b = 4;
|
|
printf("d1 = %d, a = %d, b = %d\n", d1, a, b);
|
|
assert(a == 3);
|
|
assert(b == 4);
|
|
assert(d1 == 100);
|
|
|
|
call32(200, delegate void(int d2)
|
|
{
|
|
printf("d1 = %d, a = %d\n", d1, a);
|
|
printf("d2 = %d, b = %d\n", d2, b);
|
|
assert(a == 3);
|
|
assert(b == 4);
|
|
assert(d1 == 100);
|
|
assert(d2 == 200);
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void test33()
|
|
{
|
|
extern (C) int Foo1(int a, int b, int c)
|
|
{
|
|
assert(a == 1);
|
|
assert(b == 2);
|
|
assert(c == 3);
|
|
return 1;
|
|
}
|
|
|
|
extern (D) int Foo2(int a, int b, int c)
|
|
{
|
|
assert(a == 1);
|
|
assert(b == 2);
|
|
assert(c == 3);
|
|
return 2;
|
|
}
|
|
|
|
extern (Windows) int Foo3(int a, int b, int c)
|
|
{
|
|
assert(a == 1);
|
|
assert(b == 2);
|
|
assert(c == 3);
|
|
return 3;
|
|
}
|
|
|
|
assert(Foo1(1, 2, 3) == 1);
|
|
assert(Foo2(1, 2, 3) == 2);
|
|
assert(Foo3(1, 2, 3) == 3);
|
|
|
|
printf("test33 success\n");
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class Foo34
|
|
{
|
|
int x;
|
|
|
|
class Bar
|
|
{
|
|
int y;
|
|
|
|
int delegate() getDelegate()
|
|
{
|
|
assert(y == 8);
|
|
auto i = sayHello();
|
|
assert(i == 23);
|
|
return &sayHello;
|
|
}
|
|
}
|
|
Bar bar;
|
|
|
|
int sayHello()
|
|
{
|
|
printf("Hello\n");
|
|
assert(x == 47);
|
|
return 23;
|
|
}
|
|
|
|
this()
|
|
{
|
|
x = 47;
|
|
bar = new Bar();
|
|
bar.y = 8;
|
|
}
|
|
}
|
|
|
|
void test34()
|
|
{
|
|
Foo34 foo = new Foo34();
|
|
int delegate() saydg = foo.bar.getDelegate();
|
|
printf("This should print Hello:\n");
|
|
auto i = saydg();
|
|
assert(i == 23);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class Foo35
|
|
{
|
|
int x = 42;
|
|
void bar()
|
|
{
|
|
int y = 43;
|
|
new class Object
|
|
{
|
|
this()
|
|
{
|
|
//writefln("x = %s", x);
|
|
//writefln("y = %s", y);
|
|
assert(x == 42);
|
|
assert(y == 43);
|
|
//static assert(is(typeof(this.outer) == void*)); // Bugzilla 14442
|
|
static assert(is(typeof(this.outer) == Foo35)); // Bugzilla 15839
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
void test35()
|
|
{
|
|
Foo35 f = new Foo35();
|
|
f.bar();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class Foo36
|
|
{
|
|
int x = 42;
|
|
this()
|
|
{
|
|
int y = 43;
|
|
new class Object
|
|
{
|
|
this()
|
|
{
|
|
//writefln("x = %s", x);
|
|
//writefln("y = %s", y);
|
|
assert(x == 42);
|
|
assert(y == 43);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
void test36()
|
|
{
|
|
Foo36 f = new Foo36();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class Foo37
|
|
{
|
|
int x = 42;
|
|
void bar()
|
|
{
|
|
int y = 43;
|
|
void abc()
|
|
{
|
|
new class Object
|
|
{
|
|
this()
|
|
{
|
|
//writefln("x = %s", x);
|
|
//writefln("y = %s", y);
|
|
assert(x == 42);
|
|
assert(y == 43);
|
|
}
|
|
};
|
|
}
|
|
|
|
abc();
|
|
}
|
|
}
|
|
|
|
void test37()
|
|
{
|
|
Foo37 f = new Foo37();
|
|
f.bar();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void test38()
|
|
{
|
|
int status = 3;
|
|
|
|
int delegate() foo()
|
|
{
|
|
class C
|
|
{
|
|
int dg()
|
|
{
|
|
return ++status;
|
|
}
|
|
}
|
|
|
|
C c = new C();
|
|
|
|
return &c.dg;
|
|
}
|
|
|
|
int delegate() bar = foo();
|
|
|
|
if(status != 3)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
if(bar() != 4)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
if(status != 4)
|
|
{
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void test39()
|
|
{
|
|
int status;
|
|
|
|
int delegate() foo()
|
|
{
|
|
return &(new class
|
|
{
|
|
int dg()
|
|
{
|
|
return ++status;
|
|
}
|
|
}
|
|
).dg;
|
|
}
|
|
|
|
int delegate() bar = foo();
|
|
|
|
if(status != 0)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
if(bar() != 1)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
if(status != 1)
|
|
{
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
interface I40
|
|
{
|
|
void get( string s );
|
|
}
|
|
|
|
class C40
|
|
{
|
|
int a = 4;
|
|
|
|
void init()
|
|
{
|
|
I40 i = new class() I40
|
|
{
|
|
void get( string s )
|
|
{
|
|
func();
|
|
}
|
|
};
|
|
i.get("hello");
|
|
}
|
|
void func( ){ assert(a == 4); }
|
|
}
|
|
|
|
void test40()
|
|
{
|
|
C40 c = new C40();
|
|
c.init();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class C41
|
|
{ int a = 3;
|
|
|
|
void init()
|
|
{
|
|
class N
|
|
{
|
|
void get()
|
|
{
|
|
func();
|
|
}
|
|
}
|
|
N n = new N();
|
|
n.get();
|
|
}
|
|
void func()
|
|
{
|
|
assert(a == 3);
|
|
}
|
|
}
|
|
|
|
|
|
void test41()
|
|
{
|
|
C41 c = new C41();
|
|
c.init();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class C42
|
|
{ int a = 3;
|
|
|
|
void init()
|
|
{
|
|
class N
|
|
{
|
|
void init()
|
|
{
|
|
class M
|
|
{
|
|
void get()
|
|
{
|
|
func();
|
|
}
|
|
}
|
|
M m = new M();
|
|
m.get();
|
|
}
|
|
}
|
|
N n = new N();
|
|
n.init();
|
|
}
|
|
void func()
|
|
{
|
|
assert(a == 3);
|
|
}
|
|
}
|
|
|
|
void test42()
|
|
{
|
|
C42 c = new C42();
|
|
c.init();
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
int foo43(alias X)() { return X; }
|
|
|
|
void test43()
|
|
{
|
|
int x = 3;
|
|
|
|
void bar()
|
|
{
|
|
int y = 4;
|
|
assert(foo43!(x)() == 3);
|
|
assert(foo43!(y)() == 4);
|
|
}
|
|
|
|
bar();
|
|
|
|
assert(foo43!(x)() == 3);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
class Comb
|
|
{
|
|
}
|
|
|
|
Comb Foo44(Comb delegate()[] c...)
|
|
{
|
|
Comb ec = c[0]();
|
|
printf("1ec = %p\n", ec);
|
|
ec.toString();
|
|
printf("2ec = %p\n", ec);
|
|
return ec;
|
|
}
|
|
|
|
Comb c44;
|
|
|
|
static this()
|
|
{
|
|
c44 = new Comb;
|
|
}
|
|
|
|
void test44()
|
|
{
|
|
c44 = Foo44(Foo44(c44));
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class Bar45
|
|
{
|
|
void test()
|
|
{
|
|
a = 4;
|
|
Inner i = new Inner;
|
|
i.foo();
|
|
}
|
|
|
|
class Inner
|
|
{
|
|
void foo()
|
|
{
|
|
assert(a == 4);
|
|
Inner i = new Inner;
|
|
i.bar();
|
|
}
|
|
|
|
void bar()
|
|
{
|
|
assert(a == 4);
|
|
}
|
|
}
|
|
int a;
|
|
}
|
|
|
|
void test45()
|
|
{
|
|
Bar45 b = new Bar45;
|
|
assert(b.a == 0);
|
|
b.test();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
class Adapter
|
|
{
|
|
int a = 2;
|
|
|
|
int func()
|
|
{
|
|
return 73;
|
|
}
|
|
}
|
|
|
|
class Foo46
|
|
{
|
|
int b = 7;
|
|
|
|
class AnonAdapter : Adapter
|
|
{
|
|
int aa = 8;
|
|
|
|
this()
|
|
{
|
|
assert(b == 7);
|
|
assert(aa == 8);
|
|
}
|
|
}
|
|
|
|
void func()
|
|
{
|
|
Adapter a = cast( Adapter )( new AnonAdapter() );
|
|
assert(a.func() == 73);
|
|
assert(a.a == 2);
|
|
}
|
|
}
|
|
|
|
void test46()
|
|
{
|
|
Foo46 f = new Foo46();
|
|
f.func();
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
|
|
void test47()
|
|
{
|
|
void delegate() test =
|
|
{
|
|
struct Foo {int x=3;}
|
|
Foo f;
|
|
assert(f.x == 3);
|
|
};
|
|
test();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
struct Outer48
|
|
{
|
|
class Inner
|
|
{
|
|
this(int i) { b = i; }
|
|
int b;
|
|
}
|
|
|
|
int a = 6;
|
|
|
|
void f()
|
|
{
|
|
int nested()
|
|
{
|
|
auto x = new Inner(a);
|
|
return x.b + 1;
|
|
}
|
|
int i = nested();
|
|
assert(i == 7);
|
|
}
|
|
}
|
|
|
|
|
|
void test48()
|
|
{
|
|
Outer48 s;
|
|
s.f();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void test49()
|
|
{
|
|
int j = 10;
|
|
void mainlocal(int x)
|
|
{
|
|
printf("mainlocal: j = %d, x = %d\n", j, x);
|
|
assert(j == 10);
|
|
assert(x == 1);
|
|
}
|
|
|
|
void fun2()
|
|
{
|
|
int k = 20;
|
|
void fun2local(int x)
|
|
{
|
|
printf("fun2local: k = %d, x = %d\n", k, x);
|
|
assert(j == 10);
|
|
assert(k == 20);
|
|
assert(x == 2);
|
|
}
|
|
|
|
void fun1()
|
|
{
|
|
mainlocal(1);
|
|
fun2local(2);
|
|
}
|
|
|
|
fun1();
|
|
}
|
|
|
|
fun2();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void funa50(alias pred1, alias pred2)()
|
|
{
|
|
pred1(1);
|
|
pred2(2);
|
|
}
|
|
|
|
void funb50(alias pred1)()
|
|
{ int k = 20;
|
|
void funb50local(int x)
|
|
{
|
|
printf("funb50local: k = %d, x = %d\n", k, x);
|
|
assert(k == 20);
|
|
assert(x == 2);
|
|
}
|
|
funa50!(pred1, funb50local)();
|
|
}
|
|
|
|
void test50()
|
|
{
|
|
int j = 10;
|
|
void mainlocal(int x)
|
|
{
|
|
printf("mainlocal: j = %d, x = %d\n", j, x);
|
|
assert(j == 10);
|
|
assert(x == 1);
|
|
}
|
|
funb50!(mainlocal)();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void funa51(alias pred1, alias pred2)()
|
|
{
|
|
pred1(2);
|
|
pred2(1);
|
|
}
|
|
|
|
void funb51(alias pred1)()
|
|
{ int k = 20;
|
|
void funb51local(int x)
|
|
{
|
|
printf("funb51local: k = %d, x = %d\n", k, x);
|
|
assert(k == 20);
|
|
assert(x == 2);
|
|
}
|
|
funa51!(funb51local, pred1)();
|
|
}
|
|
|
|
void test51()
|
|
{
|
|
int j = 10;
|
|
void mainlocal(int x)
|
|
{
|
|
printf("mainlocal: j = %d, x = %d\n", j, x);
|
|
assert(j == 10);
|
|
assert(x == 1);
|
|
}
|
|
funb51!(mainlocal)();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
C52 c52;
|
|
|
|
class C52
|
|
{
|
|
int index = 7;
|
|
void test1(){
|
|
printf( "this = %p, index = %d\n", this, index );
|
|
assert(index == 7);
|
|
assert(this == c52);
|
|
}
|
|
void test()
|
|
{
|
|
class N
|
|
{
|
|
void callI()
|
|
{
|
|
printf("test1\n");
|
|
test1();
|
|
printf("test2\n");
|
|
if (index is -1)
|
|
{ // Access to the outer-super-field triggers the bug
|
|
printf("test3\n");
|
|
}
|
|
}
|
|
}
|
|
auto i = new N();
|
|
i.callI();
|
|
}
|
|
}
|
|
|
|
void test52()
|
|
{
|
|
auto c = new C52;
|
|
printf("c = %p\n", c);
|
|
c52 = c;
|
|
c.test();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void foo53(int i)
|
|
{
|
|
struct SS
|
|
{
|
|
int x,y;
|
|
int bar() { return x + i + 1; }
|
|
}
|
|
SS s;
|
|
s.x = 3;
|
|
assert(s.bar() == 11);
|
|
}
|
|
|
|
void test53()
|
|
{
|
|
foo53(7);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void test54()
|
|
{
|
|
int x = 40;
|
|
int fun(int i) { return x + i; }
|
|
|
|
struct A
|
|
{
|
|
int bar(int i) { return fun(i); }
|
|
}
|
|
|
|
A makeA()
|
|
{
|
|
// A a; return a;
|
|
return A();
|
|
}
|
|
|
|
A makeA2()
|
|
{
|
|
A a; return a;
|
|
//return A();
|
|
}
|
|
|
|
A a = makeA();
|
|
assert(a.bar(2) == 42);
|
|
|
|
A b = makeA2();
|
|
assert(b.bar(3) == 43);
|
|
|
|
auto c = new A;
|
|
assert(c.bar(4) == 44);
|
|
}
|
|
/*******************************************/
|
|
|
|
void test55()
|
|
{
|
|
int localvar = 7;
|
|
|
|
int inner(int delegate(ref int) dg) {
|
|
int k = localvar;
|
|
return 0;
|
|
}
|
|
|
|
int a = localvar * localvar; // This modifies the EAX register
|
|
|
|
foreach (entry; &inner)
|
|
{
|
|
}
|
|
}
|
|
|
|
/*******************************************/
|
|
// 4401
|
|
|
|
void test4401()
|
|
{
|
|
auto foo() {
|
|
return 3;
|
|
}
|
|
|
|
auto bar() nothrow pure {
|
|
return 3;
|
|
}
|
|
|
|
auto baz() @property pure @safe {
|
|
return 3;
|
|
}
|
|
|
|
auto zoo()() @property pure @safe nothrow {
|
|
return 3;
|
|
}
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
alias void delegate() dg_t;
|
|
|
|
void Y(dg_t delegate (dg_t) y)
|
|
{
|
|
struct F { void delegate(F) f; }
|
|
|
|
version (all)
|
|
{ // generates error
|
|
(dg_t delegate(F) a){return a(F((F b){return y(a(b))();})); }
|
|
((F b){return (){return b.f(b);};});
|
|
}
|
|
else
|
|
{
|
|
auto abc(dg_t delegate(F) a)
|
|
{
|
|
return a(F((F b){return y(a(b))();}));
|
|
}
|
|
|
|
abc((F b){return (){return b.f(b);};});
|
|
}
|
|
}
|
|
|
|
|
|
void test7428(){
|
|
dg_t foo(dg_t self)
|
|
{
|
|
void bar() { self(); }
|
|
return &bar;
|
|
}
|
|
|
|
Y(&foo);
|
|
}
|
|
|
|
/*******************************************/
|
|
// 4612
|
|
|
|
struct S4612a(alias x)
|
|
{
|
|
void* func() { void* p = &x; return p; }
|
|
}
|
|
|
|
struct S4612b(alias x)
|
|
{
|
|
int i;
|
|
void* func() { void* p = &x; return p; }
|
|
}
|
|
|
|
void test4612()
|
|
{
|
|
int a;
|
|
|
|
auto sa = S4612a!a();
|
|
assert(sa.func() == &a);
|
|
|
|
auto sb = S4612b!(a)();
|
|
assert(sb.func() == &a);
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
struct S4841(alias pred)
|
|
{
|
|
void unused_func();
|
|
}
|
|
|
|
void abc4841() {
|
|
int w;
|
|
S4841!(w) m;
|
|
}
|
|
|
|
void test4841() {
|
|
abc4841();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
|
|
void index7199()
|
|
{
|
|
void find()
|
|
{
|
|
bool hay()
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
find();
|
|
}
|
|
|
|
void test7199()
|
|
{
|
|
index7199();
|
|
}
|
|
|
|
/*******************************************/
|
|
// 7965
|
|
|
|
void test7965()
|
|
{
|
|
int x;
|
|
static int* px;
|
|
px = &x;
|
|
|
|
printf("&x = %p in main()\n", &x);
|
|
struct S1
|
|
{
|
|
char y;
|
|
void boom() {
|
|
printf("&x = %p in S1.boom()\n", &x);
|
|
assert(&x == px);
|
|
//x = 42; // makes the struct nested
|
|
}
|
|
}
|
|
S1 s1;
|
|
s1.boom();
|
|
|
|
struct S2
|
|
{
|
|
this(int n) {
|
|
printf("&x = %p in S2.this()\n", &x);
|
|
assert(&x == px);
|
|
}
|
|
char y;
|
|
}
|
|
S2 s2 = S2(10);
|
|
}
|
|
|
|
struct S7965
|
|
{
|
|
string str;
|
|
uint unused1, unused2 = 0;
|
|
}
|
|
|
|
auto f7965(alias fun)()
|
|
{
|
|
struct Result
|
|
{
|
|
S7965 s;
|
|
this(S7965 _s) { s = _s; } // required for the problem
|
|
void g() { assert(fun(s.str) == "xa"); }
|
|
}
|
|
|
|
return Result(S7965("a"));
|
|
}
|
|
|
|
void test7965a()
|
|
{
|
|
string s = "x";
|
|
f7965!(a => s ~= a)().g();
|
|
assert(s == "xa");
|
|
}
|
|
|
|
/*******************************************/
|
|
// 8188
|
|
|
|
mixin template Print8188(b...)
|
|
{
|
|
int doprint()
|
|
{
|
|
return b[0] * b[1];
|
|
}
|
|
}
|
|
|
|
class A8188
|
|
{
|
|
int x, y;
|
|
mixin Print8188!(x, y);
|
|
}
|
|
|
|
void test8188()
|
|
{
|
|
auto a = new A8188;
|
|
a.x = 2;
|
|
a.y = 5;
|
|
assert(a.doprint() == 10);
|
|
}
|
|
|
|
/*******************************************/
|
|
// 5082
|
|
|
|
struct S5082 { float x; }
|
|
|
|
struct Map5082a(alias fun)
|
|
{
|
|
typeof({ return fun(int.init); }()) cache;
|
|
}
|
|
|
|
struct Map5082b(alias fun)
|
|
{
|
|
typeof({ return fun(int.init); }()) cache;
|
|
|
|
S5082 front(int i) { return fun(i); }
|
|
}
|
|
|
|
void test5082()
|
|
{
|
|
auto temp = S5082(1);
|
|
auto func = (int v){ return temp; };
|
|
auto map1 = Map5082a!func();
|
|
auto map2 = Map5082b!func();
|
|
assert(map2.front(1) == temp);
|
|
}
|
|
|
|
|
|
/*******************************************/
|
|
// 8194
|
|
|
|
void test8194()
|
|
{
|
|
int foo;
|
|
static void bar()
|
|
{
|
|
typeof(foo) baz;
|
|
static assert(is(typeof(baz) == int));
|
|
}
|
|
}
|
|
|
|
/*******************************************/
|
|
// 8339
|
|
|
|
template map8339a(fun...)
|
|
{
|
|
auto map8339a(Range)(Range r) {
|
|
struct Result {
|
|
this(double[] input) {}
|
|
}
|
|
return Result(r);
|
|
}
|
|
}
|
|
template map8339b(fun...)
|
|
{
|
|
auto map8339b(Range)(Range r) {
|
|
struct Result {
|
|
this(double[] input) { fun[0](input.length); }
|
|
}
|
|
return Result(r);
|
|
}
|
|
}
|
|
template map8339c(fun...)
|
|
{
|
|
auto map8339c(Range)(Range r) {
|
|
static struct Result {
|
|
this(double[] input) {}
|
|
}
|
|
return Result(r);
|
|
}
|
|
}
|
|
template map8339d(fun...)
|
|
{
|
|
auto map8339d(Range)(Range r) {
|
|
static struct Result {
|
|
this(double[] input) { fun[0](input.length); }
|
|
}
|
|
return Result(r);
|
|
}
|
|
}
|
|
void copy8339(T)(T x)
|
|
{
|
|
T xSaved;
|
|
}
|
|
void test8339a()
|
|
{
|
|
double[] x;
|
|
int n;
|
|
|
|
// Result has context pointer, so cannot copy
|
|
static assert (!is(typeof({ copy8339(map8339a!(a=>a)(x)); })));
|
|
static assert (!is(typeof({ copy8339(map8339a!(a=>n)(x)); })));
|
|
|
|
// same as
|
|
static assert (!is(typeof({ copy8339(map8339b!(a=>a)(x)); })));
|
|
static assert (!is(typeof({ copy8339(map8339b!(a=>n)(x)); })));
|
|
|
|
// fun is never instantiated
|
|
copy8339(map8339c!(a=>a)(x));
|
|
copy8339(map8339c!(a=>n)(x));
|
|
|
|
// static nested struct doesn't have contest pointer
|
|
copy8339(map8339d!(a=>a)(x));
|
|
//copy8339(map8339d!(a=>n)(x)); // too strict case
|
|
|
|
}
|
|
|
|
template filter8339(alias pred)
|
|
{
|
|
auto filter8339(R)(R r) {
|
|
struct Result {
|
|
R range;
|
|
this(R r) { range = r; }
|
|
auto front() { return pred(0); }
|
|
}
|
|
return Result(r);
|
|
}
|
|
}
|
|
void test8339b()
|
|
{
|
|
static makefilter() { int n; return filter8339!(a=>n)([]); }
|
|
|
|
auto r1 = makefilter();
|
|
filter8339!(a=>a)(r1);
|
|
}
|
|
|
|
void test8339c()
|
|
{
|
|
class C(X) { X x; }
|
|
class C1 { C!C1 x; }
|
|
alias C!C1 C2;
|
|
|
|
struct Pair { C1 t; C2 u; void func(){} }
|
|
Pair pair;
|
|
}
|
|
|
|
/*******************************************/
|
|
// 8704
|
|
|
|
void check8704(T, int num)()
|
|
{
|
|
static if (num == 1) T t0;
|
|
static if (num == 2) T t1 = T();
|
|
static if (num == 3) T t2 = T(1);
|
|
}
|
|
|
|
void test8704()
|
|
{
|
|
struct S
|
|
{
|
|
int n;
|
|
void foo(){}
|
|
}
|
|
|
|
static assert(!is(typeof(check8704!(S, 1)())));
|
|
static assert(!is(typeof(check8704!(S, 2)())));
|
|
static assert(!is(typeof(check8704!(S, 3)())));
|
|
|
|
static assert(!__traits(compiles, check8704!(S, 1)()));
|
|
static assert(!__traits(compiles, check8704!(S, 2)()));
|
|
static assert(!__traits(compiles, check8704!(S, 3)()));
|
|
}
|
|
|
|
/*******************************************/
|
|
// 8923
|
|
|
|
void test8923a()
|
|
{
|
|
int val;
|
|
|
|
struct S // is nested struct
|
|
{
|
|
void foo() { val = 1; } // access to val through the hidden frame pointer
|
|
}
|
|
S s1a; s1a.foo();
|
|
S s1b = S(); s1b.foo();
|
|
S[1] s2a; s2a[0].foo();
|
|
S[1] s2b = S(); s2b[0].foo();
|
|
|
|
static struct U { S s; }
|
|
U u1a; u1a.s.foo();
|
|
U u1b = U(); u1b.s.foo();
|
|
U u1c = U(s1a); u1c.s.foo();
|
|
U[1] u2a; u2a[0].s.foo();
|
|
U[1] u2b = U(); u2b[0].s.foo();
|
|
U[1] u2c = U(s1a); u2c[0].s.foo();
|
|
static struct V { S[1] s; }
|
|
V v1a; v1a.s[0].foo();
|
|
V v1b = V(); v1b.s[0].foo();
|
|
V v1c = V(s1a); v1c.s[0].foo();
|
|
V[1] v2a; v2a[0].s[0].foo();
|
|
V[1] v2b = V(); v2b[0].s[0].foo();
|
|
V[1] v2c = V(s1a); v2c[0].s[0].foo();
|
|
|
|
static struct W { S s; this(S s){ this.s = s; } }
|
|
W w1a; w1a.s.foo();
|
|
W w1b = W(); w1b.s.foo();
|
|
W w1c = W(s1a); w1c.s.foo();
|
|
W[1] w2a; w2a[0].s.foo();
|
|
W[1] w2b = W(); w2b[0].s.foo();
|
|
W[1] w2c = W(s1a); w2c[0].s.foo();
|
|
static struct X { S[1] s; this(S s){ this.s[] = s; } }
|
|
X x1a; x1a.s[0].foo();
|
|
X x1b = X(); x1b.s[0].foo();
|
|
X x1c = X(s1a); x1c.s[0].foo();
|
|
X[1] x2a; x2a[0].s[0].foo();
|
|
X[1] x2b = X(); x2b[0].s[0].foo();
|
|
X[1] x2c = X(s1a); x2c[0].s[0].foo();
|
|
|
|
// Both declarations, Y and Z should raise errors,
|
|
// because their ctors don't initialize their field 's'.
|
|
static assert(!__traits(compiles, {
|
|
static struct Y { S s; this(S){} }
|
|
}));
|
|
/+ Y y1a; //y1a.s.foo();
|
|
Y y1b = Y(); y1b.s.foo();
|
|
Y y1c = Y(s1a);//y1c.s.foo();
|
|
Y[1] y2a; //y2a[0].s.foo();
|
|
Y[1] y2b = Y(); y2b[0].s.foo();
|
|
Y[1] y2c = Y(s1a);//y2c[0].s.foo(); +/
|
|
static assert(!__traits(compiles, {
|
|
static struct Z { S[1] s; this(S){} }
|
|
}));
|
|
/+ Z z1a; //z1a.s[0].foo();
|
|
Z z1b = Z(); z1b.s[0].foo();
|
|
Z z1c = Z(s1a);//z1c.s[0].foo();
|
|
Z[1] z2a; //z1a.s[0].foo();
|
|
Z[1] z2b = Z(); z1b.s[0].foo();
|
|
Z[1] z2c = Z(s1a);//z1c.s[0].foo(); // +/
|
|
}
|
|
|
|
struct Tuple8923(int v, T...)
|
|
{
|
|
T field;
|
|
static if (v == 1) this(T args) { } // should be an error
|
|
static if (v == 2) this(T args) { field = args; }
|
|
static if (v == 3) this(U...)(U args) { } // should be an error
|
|
static if (v == 4) this(U...)(U args) { field = args; }
|
|
//alias field this;
|
|
}
|
|
void test8923b()
|
|
{
|
|
int val;
|
|
struct S { void foo() { val = 1; } }
|
|
|
|
static assert(!__traits(compiles, Tuple8923!(1, S)(S()) ));
|
|
static assert(!__traits(compiles, Tuple8923!(3, S)(S()) ));
|
|
|
|
auto tup2 = Tuple8923!(2, S)(S());
|
|
tup2.field[0].foo(); // correctly initialized
|
|
|
|
auto tup4 = Tuple8923!(4, S)(S());
|
|
tup4.field[0].foo(); // correctly initialized
|
|
}
|
|
|
|
void test8923c()
|
|
{
|
|
int val;
|
|
|
|
struct S // is nested struct
|
|
{
|
|
void foo() { val = 1; } // access to val through the hidden frame pointer
|
|
}
|
|
S s1a; s1a.foo();
|
|
S s1b = S(); s1b.foo();
|
|
S[1] s2a; s2a[0].foo();
|
|
S[1] s2b = S(); s2b[0].foo();
|
|
|
|
// U,V,W,X are nested struct, but should work same as non-nested.
|
|
// 1: bare struct object. 2: static array of structs.
|
|
// a: default construction.
|
|
// b: construction by literal syntax which has no argument.
|
|
// c: construction by literal syntax which has one or more arguments.
|
|
|
|
struct U
|
|
{
|
|
S s;
|
|
void foo() { val = 2; }
|
|
}
|
|
U u1a; u1a.foo(); u1a.s.foo();
|
|
U u1b = U(); u1b.foo(); u1b.s.foo();
|
|
U u1c = U(s1a); u1c.foo(); u1c.s.foo();
|
|
U[1] u2a; u2a[0].foo(); u2a[0].s.foo();
|
|
U[1] u2b = U(); u2b[0].foo(); u2b[0].s.foo();
|
|
U[1] u2c = U(s1a); u2c[0].foo(); u2c[0].s.foo();
|
|
|
|
struct V
|
|
{
|
|
S[1] s;
|
|
void foo() { val = 2; }
|
|
}
|
|
V v1a; v1a.foo(); v1a.s[0].foo();
|
|
V v1b = V(); v1b.foo(); v1b.s[0].foo();
|
|
V v1c = V(s1a); v1c.foo(); v1c.s[0].foo();
|
|
V[1] v2a; v2a[0].foo(); v2a[0].s[0].foo();
|
|
V[1] v2b = V(); v2b[0].foo(); v2b[0].s[0].foo();
|
|
V[1] v2c = V(s1a); v2c[0].foo(); v2c[0].s[0].foo();
|
|
|
|
struct W
|
|
{
|
|
S s;
|
|
this(S s) { this.s = s; }
|
|
void foo() { val = 2; }
|
|
}
|
|
W w1a; w1a.foo(); w1a.s.foo();
|
|
W w1b = W(); w1b.foo(); w1b.s.foo();
|
|
W w1c = W(s1a); w1c.foo(); w1c.s.foo();
|
|
W[1] w2a; w2a[0].foo(); w2a[0].s.foo();
|
|
W[1] w2b = W(); w2b[0].foo(); w2b[0].s.foo();
|
|
W[1] w2c = W(s1a); w2c[0].foo(); w2c[0].s.foo();
|
|
|
|
struct X
|
|
{
|
|
S[1] s;
|
|
this(S s) { this.s[] = s; }
|
|
void foo() { val = 2; }
|
|
}
|
|
X x1a; x1a.foo(); x1a.s[0].foo();
|
|
X x1b = X(); x1b.foo(); x1b.s[0].foo();
|
|
X x1c = X(s1a); x1c.foo(); x1c.s[0].foo();
|
|
X[1] x2a; x2a[0].foo(); x2a[0].s[0].foo();
|
|
X[1] x2b = X(); x2b[0].foo(); x2b[0].s[0].foo();
|
|
X[1] x2c = X(s1a); x2c[0].foo(); x2c[0].s[0].foo();
|
|
|
|
// Both declarations, Y and Z should raise errors,
|
|
// because their ctors don't initialize their field 's'.
|
|
static assert(!__traits(compiles, {
|
|
struct Y1 { S s; this(S){} void foo() { val = 2; } }
|
|
}));
|
|
static assert(!__traits(compiles, {
|
|
struct Y2 { S s; this(T)(S){} void foo() { val = 2; } }
|
|
auto y2 = Y2!S(S()); // instantiate ctor
|
|
}));
|
|
|
|
static assert(!__traits(compiles, {
|
|
struct Z1 { S[1] s; this(S){} void foo() { val = 2; } }
|
|
}));
|
|
static assert(!__traits(compiles, {
|
|
struct Z2 { S[1] s; this(T)(S){} void foo() { val = 2; } }
|
|
auto z2 = Z2!S(S()); // instantiate ctor
|
|
}));
|
|
}
|
|
|
|
/*******************************************/
|
|
// 9003
|
|
|
|
void test9003()
|
|
{
|
|
int i;
|
|
struct NS {
|
|
int n1; // Comment to pass all asserts
|
|
int n2; // Uncomment to fail assert on line 19
|
|
int f() { return i; }
|
|
}
|
|
|
|
static struct SS1 {
|
|
NS ns;
|
|
}
|
|
SS1 ss1;
|
|
assert(ss1.ns != NS.init);
|
|
|
|
static struct SS2 {
|
|
NS ns1, ns2;
|
|
}
|
|
SS2 ss2;
|
|
assert(ss2.ns1 != NS.init); // line 19
|
|
assert(ss2.ns2 != NS.init);
|
|
|
|
static struct SS3 {
|
|
int i;
|
|
NS ns;
|
|
}
|
|
|
|
SS3 ss3;
|
|
assert(ss3.ns != NS.init);
|
|
|
|
static struct SS4 {
|
|
int i;
|
|
NS ns1, ns2;
|
|
}
|
|
|
|
SS4 ss4;
|
|
assert(ss4.ns1 != NS.init); // fails
|
|
assert(ss4.ns2 != NS.init); // fails
|
|
}
|
|
|
|
/*******************************************/
|
|
// 9006
|
|
|
|
void test9006()
|
|
{
|
|
int i;
|
|
struct NS
|
|
{
|
|
int n;
|
|
int[3] a; // Uncomment to fail assert on line 20 and pass on line 23
|
|
int f() { return i; }
|
|
}
|
|
NS ns;
|
|
assert(ns != NS.init);
|
|
ns = NS.init;
|
|
assert(ns == NS.init);
|
|
|
|
static struct SS { NS ns; }
|
|
assert(SS.init.ns == NS.init); // fails
|
|
assert(SS.init.ns != NS()); // fails
|
|
|
|
SS s;
|
|
assert(s.ns != NS.init); // line 20
|
|
assert(s != SS.init); // fails
|
|
s = SS.init;
|
|
assert(s.ns == NS.init); // line 23, fails
|
|
assert(s == SS.init);
|
|
}
|
|
|
|
/*******************************************/
|
|
// 9035
|
|
|
|
void test9035()
|
|
{
|
|
static struct S {}
|
|
|
|
void f(T)(auto ref T t)
|
|
{
|
|
static assert(!__traits(isRef, t));
|
|
}
|
|
|
|
f(S.init); // ok, rvalue
|
|
f(S()); // ok, rvalue
|
|
|
|
int i;
|
|
struct Nested
|
|
{
|
|
int j = 0; void f() { ++i; }
|
|
}
|
|
|
|
f(Nested()); // ok, rvalue
|
|
f(Nested.init); // fails, lvalue
|
|
|
|
assert(Nested.init.j == 0);
|
|
//(ref n) { n.j = 5; }(Nested.init);
|
|
assert(Nested.init.j == 0); // fails, j is 5
|
|
}
|
|
|
|
void test9035a()
|
|
{
|
|
int x;
|
|
struct S {
|
|
// no field
|
|
void foo() { x = 1; }
|
|
}
|
|
S s1;
|
|
S s2 = S();
|
|
assert(s1 != S.init); // OK
|
|
assert(s2 != S.init); // OK
|
|
assert(S() != S.init); // NG -> OK
|
|
}
|
|
|
|
/*******************************************/
|
|
// 9036
|
|
|
|
void test9036()
|
|
{
|
|
static int i;
|
|
static struct S
|
|
{
|
|
this(this) { ++i; }
|
|
}
|
|
|
|
S s = S.init;
|
|
assert(i == 0); // postblit not called
|
|
s = S.init;
|
|
assert(i == 0); // postblit not called
|
|
|
|
int k;
|
|
static int j = 0;
|
|
struct N
|
|
{
|
|
this(this)
|
|
{
|
|
++j;
|
|
assert(this.tupleof[$-1] != null); // fails
|
|
}
|
|
void f() { ++k; }
|
|
}
|
|
|
|
N n = N.init;
|
|
assert(j == 0); // fails, j = 1, postblit called
|
|
n = N.init;
|
|
assert(j == 0); // fails, j = 2, postblit called
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
/+
|
|
auto fun8863(T)(T* ret) { *ret = T(); }
|
|
|
|
void test8863()
|
|
{
|
|
int x = 1;
|
|
struct A
|
|
{
|
|
auto f()
|
|
{
|
|
assert(x == 1);
|
|
}
|
|
}
|
|
|
|
A a;
|
|
a.f();
|
|
fun8863!A(&a);
|
|
a.f();
|
|
}
|
|
+/
|
|
|
|
/*******************************************/
|
|
// 8774
|
|
|
|
void popFront8774()
|
|
{
|
|
int[20] abc; // smash stack
|
|
}
|
|
|
|
struct MapResult8774(alias fun)
|
|
{
|
|
void delegate() front()
|
|
{
|
|
return fun(1);
|
|
}
|
|
}
|
|
|
|
void test8774() {
|
|
|
|
int sliceSize = 100;
|
|
|
|
void delegate() foo( int i )
|
|
{
|
|
void delegate() closedPartialSum()
|
|
{
|
|
int ii = i ;
|
|
void bar()
|
|
{
|
|
printf("%d\n", sliceSize);
|
|
assert(sliceSize == 100);
|
|
}
|
|
return &bar;
|
|
}
|
|
return closedPartialSum();
|
|
}
|
|
|
|
auto threads = MapResult8774!foo();
|
|
|
|
auto dg = threads.front();
|
|
popFront8774();
|
|
|
|
printf("calling dg()\n");
|
|
dg();
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
int Bug8832(alias X)()
|
|
{
|
|
return X();
|
|
}
|
|
|
|
int delegate() foo8832()
|
|
{
|
|
int stack;
|
|
int heap = 3;
|
|
|
|
int nested_func()
|
|
{
|
|
++heap;
|
|
return heap;
|
|
}
|
|
return delegate int() { return Bug8832!(nested_func); };
|
|
}
|
|
|
|
void test8832()
|
|
{
|
|
auto z = foo8832();
|
|
auto p = foo8832();
|
|
assert(z() == 4);
|
|
p();
|
|
assert(z() == 5);
|
|
}
|
|
|
|
/*******************************************/
|
|
// 9315
|
|
|
|
auto test9315()
|
|
{
|
|
struct S
|
|
{
|
|
int i;
|
|
void bar() {}
|
|
}
|
|
pragma(msg, S.init.tupleof[$-1]);
|
|
}
|
|
|
|
/*******************************************/
|
|
// 9244
|
|
|
|
void test9244()
|
|
{
|
|
union U {
|
|
int i;
|
|
@safe int x() { return i; }
|
|
}
|
|
}
|
|
|
|
/*******************************************/
|
|
// 10495
|
|
|
|
struct X10495
|
|
{
|
|
@disable this();
|
|
}
|
|
|
|
struct Y10495(alias f)
|
|
{
|
|
void g() {}
|
|
}
|
|
|
|
class C10495
|
|
{
|
|
X10495 s = X10495.init;
|
|
|
|
void h()
|
|
{
|
|
Y10495!(a => a) st;
|
|
}
|
|
}
|
|
|
|
/*******************************************/
|
|
// 11385
|
|
|
|
auto map11385(alias fun, R)(R range)
|
|
{
|
|
return MapResult11385!(fun, R)(range);
|
|
}
|
|
struct MapResult11385(alias fun, R)
|
|
{
|
|
R range;
|
|
auto front() { return fun(range[0]); }
|
|
}
|
|
void test11385()
|
|
{
|
|
//import std.algorithm;
|
|
static auto fun1(T)(T a) { return a * 2; }
|
|
auto fun2(T)(T a) { return a * 2; }
|
|
[1].map11385!(a=>fun1(a)); // OK
|
|
[1].map11385!(a=>fun2(a)); // NG:XXX is a nested function and cannot be accessed from XXX
|
|
}
|
|
|
|
/*******************************************/
|
|
|
|
void xmap(alias g)(int t)
|
|
{
|
|
g(t);
|
|
}
|
|
|
|
enum foo11297 = function (int x)
|
|
{
|
|
//int bar(int y) { return x; } xmap!bar(7);
|
|
xmap!(y => x)(7);
|
|
};
|
|
|
|
void xreduce(alias f)()
|
|
{
|
|
f(4);
|
|
}
|
|
|
|
void test11297()
|
|
{
|
|
xreduce!foo11297();
|
|
}
|
|
|
|
/*******************************************/
|
|
// 11886
|
|
|
|
struct Lambda11886(alias fun)
|
|
{
|
|
auto opCall(A...)(A args) { return fun(args); }
|
|
}
|
|
void test11886()
|
|
{
|
|
int n = 10;
|
|
Lambda11886!(x => x + n) f;
|
|
assert(f(1) == 11); // Line 9
|
|
|
|
struct NS
|
|
{
|
|
auto foo(T)(T t) { return t * n; }
|
|
}
|
|
static assert(NS.tupleof.length == 1);
|
|
static assert(NS.sizeof == (void*).sizeof);
|
|
NS ns;
|
|
assert(ns.foo(2) == 20);
|
|
}
|
|
|
|
/*******************************************/
|
|
// 12234
|
|
|
|
void test12234()
|
|
{
|
|
class B
|
|
{
|
|
int a;
|
|
this(int aa) { a = aa; }
|
|
}
|
|
auto foo = {
|
|
return new B(1);
|
|
};
|
|
static assert(is(typeof(foo) == delegate));
|
|
|
|
auto b = foo();
|
|
assert(b.a == 1);
|
|
}
|
|
|
|
/*******************************************/
|
|
// 12981
|
|
|
|
template Mix12981(T)
|
|
{
|
|
class A
|
|
{
|
|
alias typeof(this.outer) x;
|
|
}
|
|
}
|
|
|
|
class B12981
|
|
{
|
|
mixin Mix12981!(int);
|
|
|
|
static assert(is(A.x == B12981));
|
|
}
|
|
|
|
/*******************************************/
|
|
// 13861
|
|
|
|
struct Foo13861(alias f)
|
|
{
|
|
struct Bar
|
|
{
|
|
Bar func()
|
|
{
|
|
return Bar(); // OK <- Segfault
|
|
}
|
|
}
|
|
}
|
|
|
|
void test13861()
|
|
{
|
|
Foo13861!(n => n) a;
|
|
}
|
|
|
|
/*******************************************/
|
|
// 14398
|
|
|
|
void test14398()
|
|
{
|
|
int outer;
|
|
|
|
struct Inner
|
|
{
|
|
this(this)
|
|
{
|
|
outer += 42;
|
|
}
|
|
}
|
|
|
|
struct Outer
|
|
{
|
|
Inner inner;
|
|
|
|
this(int dummy)
|
|
{
|
|
inner = Inner();
|
|
|
|
// hidden fields correctly set
|
|
assert(this.tupleof[$-1] !is null);
|
|
assert(inner.tupleof[$-1] !is null);
|
|
}
|
|
}
|
|
|
|
Outer[1] arr1 = [Outer(0)];
|
|
assert(outer == 0); // no postblit called on arr1 construction
|
|
auto arr2 = arr1;
|
|
assert(outer == 42); // inner is copied successfully
|
|
}
|
|
|
|
/*******************************************/
|
|
// 14846
|
|
|
|
void foo14846(Dg)(scope Dg code)
|
|
{
|
|
static assert(is(Dg == delegate));
|
|
code();
|
|
}
|
|
|
|
void test14846()
|
|
{
|
|
int x;
|
|
|
|
struct S
|
|
{
|
|
this(int n) { x = n; }
|
|
~this() { x = 99; }
|
|
}
|
|
|
|
foo14846({ S s; });
|
|
foo14846({ S s = S(); });
|
|
foo14846({ S s = S(1); });
|
|
foo14846({ S[3] s; });
|
|
|
|
foo14846({ S* p = new S(); });
|
|
foo14846({ S* p = new S(1); });
|
|
foo14846({ S[] a = [S()]; });
|
|
foo14846({ S[] a = [S(1)]; });
|
|
}
|
|
|
|
/*******************************************/
|
|
// 15422
|
|
|
|
class App15422(T)
|
|
{
|
|
this() {}
|
|
|
|
auto test1(T val)
|
|
in {} body // necessary to reproduce the crash
|
|
{
|
|
struct Foo
|
|
{
|
|
this(int k) {}
|
|
T a;
|
|
}
|
|
|
|
Foo foo;
|
|
foo.a = val;
|
|
|
|
// Frame of test2 function, allocated on heap.
|
|
assert(foo.tupleof[$-1] !is null);
|
|
|
|
//printf("&foo = %p\n", &foo); // stack
|
|
//printf("&this = %p\n", &this); // stack?
|
|
//printf("foo.vthis = %p\n", foo.tupleof[$-1]); // stack...!?
|
|
//assert(cast(void*)&this !is *cast(void**)&foo.tupleof[$-1], "bad");
|
|
// BUG: currently foo.vthis set to the address of 'this' variable on the stack.
|
|
// It's should be stomped to null, because Foo.vthis is never be used.
|
|
|
|
int[Foo] map;
|
|
map[foo] = 1; // OK <- crash
|
|
|
|
return foo;
|
|
}
|
|
|
|
auto test2(T val)
|
|
//in {} body
|
|
{
|
|
int closVar;
|
|
struct Foo
|
|
{
|
|
this(int k) { closVar = k; }
|
|
// Make val a closure variable.
|
|
|
|
T a;
|
|
}
|
|
|
|
Foo foo;
|
|
foo.a = val;
|
|
|
|
// Frame of test2 function, allocated on heap.
|
|
assert(foo.tupleof[$-1] !is null);
|
|
|
|
return foo;
|
|
}
|
|
}
|
|
|
|
void test15422a()
|
|
{
|
|
alias App = App15422!int;
|
|
App app1 = new App;
|
|
{
|
|
auto x = app1.test1(1);
|
|
auto y = app1.test1(1);
|
|
static assert(is(typeof(x) == typeof(y)));
|
|
|
|
// int (bitwise comparison)
|
|
assert(x.a == y.a);
|
|
|
|
assert(*cast(void**)&x.tupleof[$-1] is *cast(void**)&y.tupleof[$-1]);
|
|
|
|
// bitwise equality (needOpEquals() and needToHash() returns false)
|
|
assert(x == y);
|
|
|
|
// BUG
|
|
//assert(*cast(void**)&x.tupleof[$-1] is null);
|
|
//assert(*cast(void**)&y.tupleof[$-1] is null);
|
|
auto getZ() { auto z = app1.test1(1); return z; }
|
|
auto z = getZ();
|
|
assert(x.a == z.a);
|
|
//assert(x.tupleof[$-1] is z.tupleof[$-1]); // should pass
|
|
//assert(x == z); // should pass
|
|
|
|
x = y; // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.
|
|
}
|
|
App app2 = new App;
|
|
{
|
|
auto x = app1.test2(1);
|
|
auto y = app2.test2(1);
|
|
static assert(is(typeof(x) == typeof(y)));
|
|
|
|
// int (bitwise comparison)
|
|
assert(x.a == y.a);
|
|
|
|
// closure envirionments
|
|
assert(*cast(void**)&x.tupleof[$-1] !is *cast(void**)&y.tupleof[$-1]);
|
|
|
|
// Changed to bitwise equality (needOpEquals() and needToHash() returns false)
|
|
assert(x != y); // OK <- crash
|
|
|
|
x = y; // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.
|
|
}
|
|
}
|
|
|
|
void test15422b()
|
|
{
|
|
alias App = App15422!string;
|
|
App app1 = new App;
|
|
{
|
|
auto x = app1.test1("a".idup);
|
|
auto y = app1.test1("a".idup);
|
|
static assert(is(typeof(x) == typeof(y)));
|
|
|
|
// string (element-wise comparison)
|
|
assert(x.a == y.a);
|
|
|
|
assert(*cast(void**)&x.tupleof[$-1] is *cast(void**)&y.tupleof[$-1]);
|
|
|
|
// memberwise equality (needToHash() returns true)
|
|
assert(x == y);
|
|
// Lowered to: x.a == y.a && x.tupleof[$-1] is y.tupleof[$-1]
|
|
|
|
// BUG
|
|
//assert(*cast(void**)&x.tupleof[$-1] is null);
|
|
//assert(*cast(void**)&y.tupleof[$-1] is null);
|
|
auto getZ() { auto z = app1.test1("a".idup); return z; }
|
|
auto z = getZ();
|
|
assert(x.a == z.a);
|
|
//assert(x.tupleof[$-1] is z.tupleof[$-1]); // should pass
|
|
//assert(x == z); // should pass
|
|
|
|
x = y; // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.
|
|
}
|
|
App app2 = new App;
|
|
{
|
|
auto x = app1.test2("a".idup);
|
|
auto y = app2.test2("a".idup);
|
|
static assert(is(typeof(x) == typeof(y)));
|
|
|
|
// string (element-wise comparison)
|
|
assert(x.a == y.a);
|
|
|
|
// closure envirionments
|
|
assert(*cast(void**)&x.tupleof[$-1] !is *cast(void**)&y.tupleof[$-1]);
|
|
|
|
// Changed to memberwise equality (needToHash() returns true)
|
|
// Lowered to: x.a == y.a && x.tupleof[$-1] is y.tupleof[$-1]
|
|
assert(x != y); // OK <- crash
|
|
|
|
x = y; // OK, x.tupleof[$-1] = y.tupleof[$-1] is a blit copy.
|
|
}
|
|
}
|
|
|
|
/***************************************************/
|
|
// 15757
|
|
|
|
template map15757(fun...)
|
|
{
|
|
auto map15757(R)(R r)
|
|
{
|
|
return MapResult15757!(fun, R)(r);
|
|
}
|
|
}
|
|
|
|
struct MapResult15757(alias fun, R)
|
|
{
|
|
R _input;
|
|
|
|
this(R input)
|
|
{
|
|
_input = input;
|
|
}
|
|
}
|
|
|
|
void wrap15757(R)(R r)
|
|
{
|
|
struct M(R)
|
|
{
|
|
this(R r)
|
|
{
|
|
payload = r;
|
|
}
|
|
R payload;
|
|
}
|
|
|
|
M!R m = M!R(r);
|
|
}
|
|
|
|
void test15757() @safe
|
|
{
|
|
[1,2,3].map15757!(x => x*x).wrap15757;
|
|
}
|
|
|
|
/***************************************************/
|
|
|
|
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();
|
|
test4401();
|
|
test7428();
|
|
test4612();
|
|
test4841();
|
|
test7199();
|
|
test7965();
|
|
test7965a();
|
|
test8188();
|
|
|
|
test5082();
|
|
test8194();
|
|
test8339a();
|
|
test8339b();
|
|
test8339c();
|
|
test8923a();
|
|
test8923b();
|
|
test8923c();
|
|
test9003();
|
|
test9006();
|
|
test9035();
|
|
test9035a();
|
|
test9036();
|
|
// test8863();
|
|
test8774();
|
|
test8832();
|
|
test9315();
|
|
test9244();
|
|
test11385();
|
|
test11297();
|
|
test11886();
|
|
test12234();
|
|
test13861();
|
|
test14398();
|
|
test14846();
|
|
test15422a();
|
|
test15422b();
|
|
test15757();
|
|
|
|
printf("Success\n");
|
|
return 0;
|
|
}
|