blob: 4c99c59e8a96e3c95c04340e76d9ba9e45f19cba [file] [log] [blame]
// 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*)); // https://issues.dlang.org/show_bug.cgi?id=14442
static assert(is(typeof(this.outer) == Foo35)); // https://issues.dlang.org/show_bug.cgi?id=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)
{
}
}
/*******************************************/
enum dg56 = delegate { return 5; };
void test56()
{
auto inner() {
return dg56();
}
assert(inner() == 5);
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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);
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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();
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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");
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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);
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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);
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=8194
void test8194()
{
int foo;
static void bar()
{
typeof(foo) baz;
static assert(is(typeof(baz) == int));
}
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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;
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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)()));
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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
}));
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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);
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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();
}
+/
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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);
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=9315
auto test9315()
{
struct S
{
int i;
void bar() {}
}
pragma(msg, S.init.tupleof[$-1]);
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=9244
void test9244()
{
union U {
int i;
@safe int x() { return i; }
}
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=10495
struct X10495
{
@disable this();
}
struct Y10495(alias f)
{
void g() {}
}
class C10495
{
X10495 s = X10495.init;
void h()
{
Y10495!(a => a) st;
}
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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);
};
enum goo11297 = delegate (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();
xreduce!goo11297();
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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);
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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);
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=12981
template Mix12981(T)
{
class A
{
alias typeof(this.outer) x;
}
}
class B12981
{
mixin Mix12981!(int);
static assert(is(A.x == B12981));
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=13861
struct Foo13861(alias f)
{
struct Bar
{
Bar func()
{
return Bar(); // OK <- Segfault
}
}
}
void test13861()
{
Foo13861!(n => n) a;
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=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)]; });
}
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=15422
class App15422(T)
{
this() {}
auto test1(T val)
in {} do // 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 {} do
{
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.
}
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=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;
}
/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=19384
struct Vec
{
uint item;
ref uint august() return
{
return item;
// commenting next line removes bug
foreach(ref val; range()) return val;
assert(false);
}
uint* august2() return
{
return &item;
foreach(ref val; range()) return &val;
assert(false);
}
}
struct range
{
int opApply(scope int delegate(ref uint) dg) { return 0; }
}
void test19384()
{
Vec preds = Vec(0xDEAD);
void* ptr2 = &preds.august();
void* ptr3 = preds.august2();
assert(&preds == ptr2);
assert(&preds == ptr3);
}
/***************************************************/
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();
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();
test19384();
printf("Success\n");
return 0;
}