| /* |
| RUN_OUTPUT: |
| --- |
| 7 |
| 83 |
| 4 |
| 4 |
| 1.000000 2.000000 3.000000 |
| Success |
| --- |
| */ |
| |
| import core.stdc.stdio; |
| |
| // Test function inlining |
| |
| debug = NRVO; |
| |
| /************************************/ |
| |
| int foo(int i) |
| { |
| return i; |
| } |
| |
| int bar() |
| { |
| return foo(3) + 4; |
| } |
| |
| void test1() |
| { |
| printf("%d\n", bar()); |
| assert(bar() == 7); |
| } |
| |
| |
| /************************************/ |
| |
| struct Foo2 |
| { |
| int a,b,c,e,f,g; |
| } |
| |
| |
| int foo2(Foo2 f) |
| { |
| f.b += 73; |
| return f.b; |
| } |
| |
| int bar2() |
| { |
| Foo2 gg; |
| |
| gg.b = 6; |
| return foo2(gg) + 4; |
| } |
| |
| void test2() |
| { |
| printf("%d\n", bar2()); |
| assert(bar2() == 83); |
| } |
| |
| |
| /************************************/ |
| |
| struct Foo3 |
| { |
| int bar() { return y + 3; } |
| int y = 4; |
| } |
| |
| void test3() |
| { |
| Foo3 f; |
| |
| assert(f.bar() == 7); |
| } |
| |
| |
| /************************************/ |
| |
| void func(void function () v) |
| { |
| } |
| |
| void test4() |
| { |
| static void f1() { } |
| |
| func(&f1); |
| //func(f1); |
| } |
| |
| |
| /************************************/ |
| |
| void foo5(ubyte[16] array) |
| { |
| bar5(array.ptr); |
| } |
| |
| void bar5(ubyte *array) |
| { |
| } |
| |
| void abc5(ubyte[16] array) |
| { |
| foo5(array); |
| } |
| |
| void test5() |
| { |
| } |
| |
| /************************************/ |
| |
| struct Struct |
| { |
| real foo() |
| { |
| return 0; |
| } |
| |
| void bar(out Struct Q) |
| { |
| if (foo() < 0) |
| Q = this; |
| } |
| } |
| |
| void test6() |
| { |
| } |
| |
| /************************************/ |
| |
| struct S7(T) |
| { |
| immutable(T)[] s; |
| } |
| |
| T foo7(T)(T t) |
| { |
| enum S7!(T)[] i = [{"hello"},{"world"}]; |
| auto x = i[0].s; |
| return t; |
| } |
| |
| void test7() |
| { |
| auto x = foo7('c'); |
| } |
| |
| /************************************/ |
| |
| // https://issues.dlang.org/show_bug.cgi?id=10833 |
| string fun10833(T...)() |
| { |
| foreach (v ; T) |
| return v; |
| assert(0); |
| } |
| |
| void test10833() |
| { |
| auto a = fun10833!("bar")(); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=4825 |
| |
| int a8() { |
| int r; |
| return r; |
| } |
| |
| int b8() { |
| return a8(); |
| } |
| |
| void test8() { |
| void d() { |
| auto e = b8(); |
| } |
| static const int f = b8(); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=4841 |
| |
| auto fun4841a() |
| { |
| int i = 42; |
| struct Result |
| { |
| this(int u) {} |
| auto bar() |
| { |
| // refer context of fun4841a |
| return i; |
| } |
| } |
| return Result(); |
| } |
| void test4841a() |
| { |
| auto t = fun4841a(); |
| auto x = t.bar(); |
| assert(x == 42); |
| } |
| |
| auto fun4841b() |
| { |
| int i = 40; |
| auto foo() // hasNestedFrameRefs() == false |
| { |
| // |
| struct Result |
| { |
| this(int u) {} |
| auto bar() |
| { |
| // refer context of fun4841b |
| return i + 2; |
| } |
| } |
| return Result(); |
| } |
| return foo(); |
| } |
| void test4841b() |
| { |
| auto t = fun4841b(); |
| assert(cast(void*)t.tupleof[$-1] !is null); // Result to fun4841b |
| auto x = t.bar(); |
| assert(x == 42); |
| } |
| |
| auto fun4841c() |
| { |
| int i = 40; |
| auto foo() // hasNestedFrameRefs() == true |
| { |
| int g = 2; |
| struct Result |
| { |
| this(int u) {} |
| auto bar() |
| { |
| // refer context of fun4841c and foo |
| return i + g; |
| } |
| } |
| return Result(); |
| } |
| return foo(); |
| } |
| void test4841c() |
| { |
| auto t = fun4841c(); |
| assert( cast(void*)t.tupleof[$-1] !is null); // Result to foo |
| assert(*cast(void**)t.tupleof[$-1] !is null); // foo to fun4841c |
| auto x = t.bar(); |
| assert(x == 42); |
| } |
| |
| void test4841() |
| { |
| test4841a(); |
| test4841b(); |
| test4841c(); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=7261 |
| |
| struct AbstractTask |
| { |
| ubyte taskStatus; |
| } |
| |
| struct Task |
| { |
| AbstractTask base; |
| alias base this; |
| |
| void opAssign(Task rhs) |
| { |
| } |
| |
| ~this() |
| { |
| if (taskStatus != 3) { } |
| } |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9356 |
| |
| void test9356() |
| { |
| static inout(char)[] bar (inout(char)[] a) |
| { |
| return a; |
| } |
| |
| string result; |
| result ~= bar("abc"); |
| assert(result == "abc"); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12079 |
| |
| void test12079() |
| { |
| string[string][string] foo; |
| |
| foo.get("bar", null).get("baz", null); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12243 |
| |
| char f12243() { return 'a'; } |
| |
| void test12243() |
| { |
| string s; |
| s ~= f12243(); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11201 |
| |
| struct Foo11201 |
| { |
| int a; |
| float b; |
| |
| Foo11201 func()() const { return this; } |
| } |
| |
| auto f11201()(Foo11201 a) { return a; } |
| |
| void test11201() |
| { |
| auto a = Foo11201(0, 1); |
| |
| assert(f11201(a.func!()()) == a); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11223 |
| |
| struct Tuple11223(T...) |
| { |
| T values; |
| |
| void opAssign(Tuple11223 rhs) |
| { |
| if (0) |
| values = rhs.values; |
| else |
| assert(1); |
| } |
| } |
| |
| void test11223() |
| { |
| Tuple11223!string tmp; |
| tmp = Tuple11223!string(); |
| } |
| |
| /************************************/ |
| |
| |
| void foo3918() |
| { |
| import core.stdc.stdlib : alloca; |
| void[] mem = alloca(1024)[0..1024]; |
| } |
| |
| void test3918() |
| { |
| foreach(i; 0 .. 10_000_000) |
| { |
| foo3918(); |
| } |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11314 |
| |
| struct Tuple11314(T...) |
| { |
| T values; |
| |
| void opAssign(typeof(this) rhs) |
| { |
| if (0) |
| values[] = rhs.values[]; |
| else |
| assert(1); |
| } |
| } |
| |
| struct S11314 {} |
| |
| void test11314() |
| { |
| Tuple11314!S11314 t; |
| t = Tuple11314!S11314(S11314.init); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11224 |
| |
| S11224* ptr11224; |
| |
| struct S11224 |
| { |
| this(int) |
| { |
| ptr11224 = &this; |
| /*printf("ctor &this = %p\n", &this);*/ |
| } |
| this(this) |
| { |
| /*printf("cpctor &this = %p\n", &this);*/ |
| } |
| int num; |
| } |
| S11224 foo11224() |
| { |
| S11224 s = S11224(1); |
| //printf("foo &this = %p\n", &s); |
| assert(ptr11224 is &s); |
| return s; |
| } |
| void test11224() |
| { |
| auto s = foo11224(); |
| //printf("main &this = %p\n", &s); |
| assert(ptr11224 is &s); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11322 |
| |
| bool b11322; |
| uint n11322; |
| |
| ref uint fun11322() |
| { |
| if (b11322) |
| return n11322; |
| else |
| return n11322; |
| } |
| |
| void test11322() |
| { |
| fun11322()++; |
| assert(n11322 == 1); |
| fun11322() *= 5; |
| assert(n11322 == 5); |
| } |
| |
| /************************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=11394 |
| |
| debug(NRVO) static void* p11394a, p11394b, p11394c; |
| |
| static int[5] make11394(in int x) pure |
| { |
| typeof(return) a; |
| a[0] = x; |
| a[1] = x + 1; |
| a[2] = x + 2; |
| a[3] = x + 3; |
| a[4] = x + 4; |
| debug(NRVO) p11394a = cast(void*)a.ptr; |
| return a; |
| } |
| |
| struct Bar11394 |
| { |
| immutable int[5] arr; |
| |
| this(int x) |
| { |
| this.arr = make11394(x); // NRVO should work |
| debug(NRVO) p11394b = cast(void*)this.arr.ptr; |
| } |
| } |
| |
| void test11394() |
| { |
| auto b = Bar11394(5); |
| debug(NRVO) p11394c = cast(void*)b.arr.ptr; |
| //debug(NRVO) printf("p1 = %p\np2 = %p\np3 = %p\n", p11394a, p11394b, p11394c); |
| debug(NRVO) assert(p11394a == p11394b); |
| debug(NRVO) assert(p11394b == p11394c); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=12080 |
| |
| class TZ12080 {} |
| |
| struct ST12080 |
| { |
| ST12080 opBinary()() const pure nothrow |
| { |
| auto retval = ST12080(); |
| return retval; // NRVO |
| } |
| |
| long _stdTime; |
| immutable TZ12080 _timezone; |
| } |
| |
| class Foo12080 |
| { |
| |
| ST12080 bar; |
| bool quux; |
| |
| public ST12080 sysTime() |
| out {} |
| do |
| { |
| if (quux) |
| return ST12080(); |
| |
| return bar.opBinary(); |
| // returned value is set to __result |
| // --> Inliner wrongly created the second DeclarationExp for __result. |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=13503 |
| |
| void f13503a(string[] s...) |
| { |
| assert(s[0] == "Cheese"); |
| } |
| |
| auto f13503b(string arg) |
| { |
| string result = arg; |
| return result; |
| } |
| |
| string f13503c(string arg) |
| { |
| string result = arg; |
| return result; |
| } |
| |
| void test13503() |
| { |
| f13503a(f13503b("Cheese")); |
| f13503a(f13503c("Cheese")); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14267 |
| |
| // EXTRA_SOURCES: imports/a14267.d |
| import imports.a14267; |
| |
| void test14267() |
| { |
| foreach (m; __traits(allMembers, SysTime14267)) |
| { |
| static if (is(typeof(__traits(getMember, SysTime14267, m)))) |
| { |
| foreach (func; __traits(getOverloads, SysTime14267, m)) |
| { |
| auto prot = __traits(getProtection, func); |
| static if (__traits(isStaticFunction, func)) |
| { |
| static assert(func.stringof == "min()"); |
| auto result = func; |
| } |
| } |
| } |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=13244 |
| |
| struct MapResult13244(alias fun) |
| { |
| int[] input; |
| @property front() { return fun(input[0]); } |
| } |
| |
| int[] array13244(R)(R r) |
| { |
| int[] a; |
| a ~= r.front; |
| return a; |
| } |
| |
| void test13244() |
| { |
| auto arr = [[cast(ubyte)1]]; |
| foreach (ref x; arr) |
| { |
| auto m = MapResult13244!(c => x[c])([0]); |
| array13244(m); |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14306 |
| |
| struct MapResult(alias fun) |
| { |
| void front() |
| { |
| // while (1) { break; } |
| fun(1); |
| } |
| } |
| |
| void bar(R)(R r) |
| { |
| foreach (i; 0..100) |
| { |
| r.front(); |
| } |
| } |
| |
| struct S |
| { |
| int x; |
| int bump() |
| { |
| while (1) { break; } |
| ++x; |
| return x; |
| } |
| } |
| |
| void fun(ref S s) |
| { |
| MapResult!(y => s.bump())().bar; |
| // MapResult!((int x) => s.bump())().bar; |
| |
| if (s.x != 100) |
| assert(0); |
| } |
| |
| void test14306() |
| { |
| S t; |
| fun(t); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14754 |
| |
| auto aafunc14754(string k) |
| { |
| enum aa = [ "K": "V" ]; |
| auto p = k in aa; |
| return null; |
| } |
| |
| struct MapResult14754(alias fun, R) |
| { |
| R _input; |
| |
| @property auto ref front() |
| { |
| return fun(_input[0]); |
| } |
| } |
| |
| auto array14754(R)(R r) |
| { |
| alias E = typeof(r.front); |
| E[] result; |
| result ~= r.front; |
| return result; |
| } |
| |
| auto mapfun14754(R)(R words, string k) |
| { |
| return array14754(MapResult14754!(s => aafunc14754(k), R)(words)); |
| } |
| |
| void test14754() |
| { |
| auto r = mapfun14754([""], ""); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14606 |
| |
| struct S14606 |
| { |
| this(long stdTime) |
| { |
| _stdTime = stdTime; |
| } |
| |
| long _stdTime; |
| } |
| |
| S14606 getS14606() |
| { |
| S14606 sysTime = S14606(0); |
| return sysTime; |
| } |
| |
| struct T14606 |
| { |
| this(string) |
| { |
| uint[3] arr; |
| s = getS14606(); |
| } |
| |
| S14606 s; |
| } |
| |
| void test14606() |
| { |
| auto t = T14606(null); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=14753 |
| |
| pragma(inline) |
| void test14753(string) { } |
| |
| /**********************************/ |
| |
| struct S14975 |
| { |
| int bar; |
| |
| pragma(inline, true) this(int bar) |
| { |
| this.bar = bar; |
| } |
| } |
| |
| void test14975() |
| { |
| S14975 baz = 1; |
| if (baz.bar != 1) |
| assert(0); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=15210 |
| |
| struct BigInt15210 {} |
| |
| struct Tuple15210(Types...) |
| { |
| Types field; |
| |
| void opAssign(R)(R rhs) |
| { |
| field = rhs.field; |
| } |
| } |
| |
| void test15210() |
| { |
| alias X = Tuple15210!BigInt15210; |
| |
| X[BigInt15210] cache; |
| |
| auto x = X(); |
| |
| cache[BigInt15210()] = x; |
| } |
| |
| /**********************************/ |
| |
| int foo7625(int v) |
| { |
| return bar7625(2 * v); |
| } |
| |
| int bar7625(int a) |
| { |
| ++a; |
| if (a > 0) |
| return 1; |
| return baz(a); |
| } |
| |
| int baz(int a) |
| { |
| if (a > 0) |
| throw new Exception("a > 0"); |
| return a - 1; |
| } |
| |
| void test7625() |
| { |
| int x = foo7625(1); |
| if (x != 1) |
| assert(0); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9785 partial fix |
| |
| void test9785() |
| { |
| int j = 3; |
| |
| void loop(scope const void function(int x) dg) { |
| pragma(inline, true); |
| dg(++j); |
| } |
| |
| loop((x) { |
| pragma(inline, true); |
| printf("%d\n", x); |
| assert(x == 4); |
| }); |
| } |
| |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9785 partial fix |
| |
| void test9785_2() { |
| int j = 3; |
| |
| void loop(scope const void function(int x) dg) { |
| pragma(inline, true); |
| dg(++j); |
| } |
| |
| static void func(int x) { |
| pragma(inline, true); |
| printf("%d\n", x); |
| assert(x == 4); |
| } |
| |
| loop(&func); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=9785 partial fix |
| |
| void test9785_3() @nogc |
| { |
| int j = 3; |
| |
| void loop(scope const void delegate(int x) @nogc dg) @nogc { |
| pragma(inline, true); |
| dg(++j); |
| } |
| |
| loop((x) @nogc { |
| pragma(inline, true); |
| //printf("%d\n", x + j * 2); |
| assert(x == 4); |
| assert(j == 4); |
| }); |
| |
| j = 3; |
| void func(int x) @nogc { |
| pragma(inline, true); |
| //printf("%d\n", x + j * 2); |
| assert(x == 4); |
| assert(j == 4); |
| } |
| |
| loop(&func); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=15207 |
| |
| struct Vec15207 |
| { |
| float x, y, z; |
| |
| this(float x_, float y_, float z_) |
| { |
| x = x_; |
| y = y_; |
| z = z_; |
| } |
| |
| Vec15207 clone() |
| { |
| // When the variable 'res' is replaced with a STCref temporary, |
| // this line was accidentally changed to reference initialization. |
| Vec15207 res = this; |
| |
| return res; |
| } |
| } |
| |
| class C15207 |
| { |
| Vec15207 a; |
| |
| this() |
| { |
| a = Vec15207(1, 2, 3).clone(); |
| |
| assert(a.x == 1); |
| assert(a.y == 2); |
| assert(a.z == 3); |
| printf("%f %f %f\n", a.x, a.y, a.z); |
| } |
| } |
| |
| void test15207() |
| { |
| auto c = new C15207(); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=15253 |
| |
| struct MessageType15253 |
| { |
| MessageType15253[] messageTypes; |
| |
| const void toString1(scope void delegate(const(char)[]) sink) |
| { |
| messageTypes[0].toString1(sink); |
| } |
| } |
| |
| struct ProtoPackage15253 |
| { |
| MessageType15253[] messageTypes; |
| |
| const void toString1(scope void delegate(const(char)[]) sink) |
| { |
| messageTypes[0].toString1(sink); |
| } |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=15296 |
| |
| static int x15296; |
| |
| struct S15296 |
| { |
| // Can be expanded only as statements. |
| pragma(inline, true) |
| void bar(size_t , size_t ) |
| { |
| for (size_t w = 0; w < 2; w++) { ++x15296; } |
| } |
| |
| pragma(inline, true) |
| void foo(size_t a, size_t b) |
| { |
| bar(a, b); |
| } |
| } |
| |
| pragma(inline, true) |
| static void voidCall15296() |
| { |
| for (size_t w = 0; w < 3; w++) { ++x15296; } |
| } |
| |
| void test15296() |
| { |
| bool cond = true; |
| |
| S15296 s; |
| |
| // CallExp at the top of ExpStatement |
| x15296 = 0; |
| s.foo(0, 0); |
| assert(x15296 == 2); |
| |
| // CondExp at the top of ExpStatement |
| x15296 = 0; |
| (cond ? s.foo(0, 0) : voidCall15296()); |
| assert(x15296 == 2); |
| (cond ? voidCall15296() : s.foo(0, 0)); |
| assert(x15296 == 2 + 3); |
| |
| // CommaExp at the top of ExpStatement |
| x15296 = 0; |
| (s.foo(0, 0), voidCall15296()); |
| assert(x15296 == 3 + 2); |
| } |
| |
| // ---- |
| |
| struct File15296 |
| { |
| struct Impl {} |
| Impl* _p; |
| |
| pragma(inline, true) |
| ~this() { _p = null; } |
| |
| struct LockingTextWriter |
| { |
| pragma(inline, true) |
| this(ref File15296 f) |
| { |
| assert(f._p, "Attempting to write to closed File"); |
| } |
| } |
| |
| pragma(inline, true) |
| auto lockingTextWriter() { return LockingTextWriter(this); } |
| |
| pragma(inline, true) |
| void write() { auto w = lockingTextWriter(); } |
| |
| //pragma(inline, true) |
| static uint formattedWrite(Writer)(Writer w) { return 0; } |
| |
| pragma(inline, true) |
| void writef() { formattedWrite(lockingTextWriter()); } |
| } |
| |
| __gshared File15296 stdout15296 = {new File15296.Impl()}; |
| |
| pragma(inline, true) |
| @property File15296 trustedStdout15296() { return stdout15296; } |
| |
| // ---- |
| // reduced case from runnable/test34.d test34() |
| |
| void test15296b() |
| { |
| // trustedStdout() returns a temporary File object. Its dtor call |
| // should be deferred till the end of expanded writef body statements. |
| trustedStdout15296().writef(); |
| } |
| |
| // ---- |
| // reduced case from runnable/xtest46.d test136() |
| |
| struct Perm15296c |
| { |
| this(byte[] input) |
| { |
| foreach (elem; input) |
| { |
| // if vthis.isDataseg() is true in expandInline, |
| // its edtor should not be called. |
| stdout15296.write(); |
| } |
| } |
| } |
| |
| void test15296c() |
| { |
| auto perm2 = Perm15296c([0, 1, 2]); |
| } |
| |
| /**********************************/ |
| // https://issues.dlang.org/show_bug.cgi?id=17676 |
| __gshared bool bgEnable = 1; |
| |
| void test17676() nothrow |
| { |
| fullcollect(); |
| } |
| |
| size_t fullcollect() nothrow |
| { |
| if(bgEnable) |
| return fullcollectTrigger(); |
| |
| return fullcollectNow(); |
| } |
| |
| size_t fullcollectNow() nothrow |
| { |
| if (bgEnable) |
| assert(0); |
| pragma(inline, false); |
| return 1; |
| } |
| |
| size_t fullcollectTrigger() nothrow |
| { |
| pragma(inline, false); |
| return 0; |
| } |
| |
| /**********************************/ |
| |
| int main() |
| { |
| test1(); |
| test2(); |
| test3(); |
| test3918(); |
| test4(); |
| test5(); |
| test9356(); |
| test6(); |
| test7(); |
| test8(); |
| test4841(); |
| test11201(); |
| test11223(); |
| test11314(); |
| test11224(); |
| test11322(); |
| test11394(); |
| test13503(); |
| test13244(); |
| test14306(); |
| test14754(); |
| test14606(); |
| test14975(); |
| test15210(); |
| test7625(); |
| test9785(); |
| test9785_2(); |
| test9785_3(); |
| test15207(); |
| test15296(); |
| test15296b(); |
| test15296c(); |
| test17676(); |
| |
| printf("Success\n"); |
| return 0; |
| } |