2 import core.stdc.stdio;
4 struct S { int a,b,c,d; }
6 alias int delegate() dg_t;
7 alias int delegate(int) dg1_t;
14 /************************************/
32 printf("bar = %d\n", dg());
36 /************************************/
59 printf("bar = %d\n", dg());
63 /************************************/
84 printf("bar = %d\n", dg());
88 /************************************/
113 printf("bar = %d\n", dg());
117 /************************************/
147 /************************************/
178 /************************************/
182 int[3] a = [10,11,12];
204 /************************************/
230 /************************************/
267 /************************************/
294 printf("bar = %d\n", dg());
299 /************************************/
322 printf("bar = %d\n", dg());
326 /************************************/
354 printf("bar = %d\n", dg());
358 /************************************/
386 printf("bar = %d\n", dg());
391 /************************************/
419 printf("bar = %d\n", dg());
423 /************************************/
451 printf("bar = %d\n", dg());
455 /************************************/
470 return a + x + y + 3;
486 printf("bar = %d\n", dg());
490 /************************************/
506 return a + x + y + 3;
522 printf("bar = %d\n", dg());
526 /************************************/
533 int foo() { return a + 3; }
548 /************************************/
550 void abc19(void delegate() dg)
559 static S19 call(int v)
578 auto s = S19.call(5);
589 /************************************/
591 void enforce20(lazy int msg)
608 /************************************/
610 void thrash21() { char[128] x = '\xfe'; }
612 void delegate() dg21;
613 int g_input = 11, g_output;
621 // both 'private' and 'final' to make non-virtual
622 private final void actual()
641 assert(g_output == 13);
644 /************************************/
646 void thrash22() { char[128] x = '\xfe'; }
648 void delegate() dg22;
656 int j; /* Making f access this variable causes f's chain to be am's
657 frame. Otherwise, f's chain would be the A instance. */
668 gi22 = x; /* No checkedNestedReference for A.am.this,
669 so it is never placed in a closure. */
691 /************************************/
696 struct S { int a, b, c; }
699 static int delegate() makeSum1(S s)
701 with (s) return { return a + b + c; };
703 static int delegate() makeSum2(S[1] sa)
705 with (sa[0]) return { return a + b + c; };
707 static int delegate() makeSum3(SS ss)
709 with (ss.obj) return { return a + b + c; };
711 static int delegate() makeSum4(SS[1] ssa)
713 with (ssa[0].obj) return { return a + b + c; };
720 sum = makeSum1(s); assert(sum() == 90);
721 sum = makeSum2([s]); assert(sum() == 90);
722 sum = makeSum3(ss); assert(sum() == 90);
723 sum = makeSum4([ss]); assert(sum() == 90);
726 /************************************/
729 int delegate() foo1841()
739 return delegate int() { return nested_func(); };
742 int delegate() foo1841b()
752 int more_nested() { return nested_func(); }
753 return delegate int() { return more_nested(); };
770 /************************************/
773 void writeln5911(const(char)[] str) {}
775 void logout5911(lazy const(char)[] msg) { writeln5911(msg); }
779 string str = "hello world";
780 logout5911((){ return str; }()); // closure 1
784 throw new Exception("exception!!");
789 logout5911(e.toString()); // closure2 SEGV : e is null.
793 /************************************/
796 auto get9685a(alias fun)()
813 auto bar = get9685a!(() => a)();
814 auto qux = bar.clone;
815 //printf("bar context pointer : %p\n", bar.tupleof[$-1]);
816 //printf("qux context pointer : %p\n", qux.tupleof[$-1]);
817 assert(bar.tupleof[$-1] == qux.tupleof[$-1]);
818 assert(qux.data == 15);
821 auto get9685b(alias fun)()
830 return Foo(data + x);
838 auto bar = get9685b!(() => a)();
839 auto qux = bar.clone;
840 //printf("bar context pointer : %p\n", bar.tupleof[$-1]);
841 //printf("qux context pointer : %p\n", qux.tupleof[$-1]);
842 assert(bar.tupleof[$-1] == qux.tupleof[$-1]);
843 assert(qux.data == 15);
846 /************************************/
853 Dg delegate() action;
856 static void fn(void delegate()) { }
858 int x; fn({ x++; }); // required
864 int x; void unusedFun() { x++; } // required
866 return Dg(() => dg); // lambda returns garbage instead of dg
869 return dg = Dg(&createDg2);
874 auto dgs = [createDg12406()];
875 //printf("dgs[%2d].action = %p:%p\n", 0, dgs[$-1].action.ptr, dgs[$-1].action.funcptr);
876 foreach (i; 1 .. 10+1)
878 dgs ~= dgs[i-1].action();
879 //printf("dgs[%2d].action = %p:%p\n", i, dgs[$-1].action.ptr, dgs[$-1].action.funcptr);
882 foreach (i, dgx; dgs)
886 // All closures are equal with dgs[0].
887 assert(dgx.action.ptr is dgs[0].action.ptr);
888 assert(dgx.action.funcptr is dgs[0].action.funcptr); // is: createDg2
892 // Each closures has unique context.
893 for (size_t j = i + 2; j < dgs.length; j += 2)
894 assert(dgx.action.ptr !is dgs[j].action.ptr);
895 assert(dgx.action.funcptr is dgs[1].action.funcptr); // is: lambda () => dg
900 /************************************/
905 static auto makeS(int x)
910 int get() { return x; } // x will be a closure variable
915 assert(s.get() == 1);
916 // By inlining get() function call, it's rewritten to:
917 // assert(*(s.tupleof[$-1] + x.offset) == 1);
918 // --> In DotVarExp::toElem(), x->offset should be already nonzero.
923 // This is questionable case. Currently it works without any errors,
924 // but not sure it's really intentional
926 struct S14730x(alias f)
928 auto foo()() { return f(0); }
933 auto makeS14730x() //@nogc
937 //assert(s.foo() == 10);
943 auto s = makeS14730x();
944 assert(s.tupleof[$-1] !is null);
946 // instantiationg foo outside of makeS will place the variable x in closure
947 // *after* the semantic3 completion of makeS() function.
948 assert(s.foo() == 10);
951 /************************************/