new file mode 100644
@@ -0,0 +1,34 @@
+// https://issues.dlang.org/show_bug.cgi?id=21538
+// REQUIRED_ARGS: -preview=dip1000
+
+interface I
+{
+ void f(void delegate() @safe dg) @safe;
+}
+
+class CI : I
+{
+ override void f(void delegate() @system dg) @safe { }
+}
+
+abstract class A
+{
+ void f(void delegate() @safe dg) @safe;
+}
+
+class CA : A
+{
+ override void f(void delegate() @system dg) @safe { }
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=20904
+auto blah(void delegate())
+{
+}
+
+void delegate()[string] r;
+void main()
+{
+ void delegate() nothrow a;
+ r["v"] = a;
+}
new file mode 100644
@@ -0,0 +1,3 @@
+// REQUIRED_ARGS: -main -c
+
+void foo() { }
@@ -111,3 +111,15 @@ void* useTls()
void* a3 = &globalNoreturn;
return a1 < a2 ? a2 : a3;
}
+
+/***************************************************/
+
+noreturn testfn(noreturn function() fn)
+{
+ fn();
+}
+
+noreturn testdg(noreturn delegate() dg)
+{
+ dg();
+}
new file mode 100644
@@ -0,0 +1,26 @@
+alias AliasSeq(T...) = T;
+
+class A
+{
+ int z = 3;
+}
+
+class B : A
+{
+ int a = 1;
+}
+
+class C : B
+{
+ int b = 2;
+ alias tup = AliasSeq!(b, a, z);
+}
+
+void main()
+{
+ static const ins = new C;
+ static assert(&ins.tup[0] == &ins.b);
+ static assert(&ins.tup[1] == &ins.a);
+ static assert(&ins.tup[2] == &ins.z);
+ static assert(ins.tup == AliasSeq!(2,1,3));
+}
new file mode 100644
@@ -0,0 +1,37 @@
+// PERMUTE_ARGS -preview=dip1000
+// https://issues.dlang.org/show_bug.cgi?id=19873
+int* ed(scope int* x)
+{
+ auto y = x;
+ return y;
+}
+
+int* et(scope int* x) @trusted
+{
+ auto y = x;
+ return y;
+}
+
+int* es(scope int* x) @system
+{
+ auto y = x;
+ return y;
+}
+
+auto ad(scope int* x)
+{
+ auto y = x;
+ return y;
+}
+
+auto at(scope int* x) @trusted
+{
+ auto y = x;
+ return y;
+}
+
+auto as(scope int* x) @system
+{
+ auto y = x;
+ return y;
+}
new file mode 100644
@@ -0,0 +1,21 @@
+// https://issues.dlang.org/show_bug.cgi?id=21719
+
+struct S
+{
+ auto f()
+ {
+ } // inferred to be @safe @nogc pure nothrow
+}
+
+class C
+{
+ auto f() // should also infer the same attributes
+ {
+ }
+}
+
+pure @nogc nothrow @safe void test(S s, C c)
+{
+ s.f;
+ c.f;
+}
new file mode 100644
@@ -0,0 +1,19 @@
+// https://issues.dlang.org/show_bug.cgi?id=22254
+
+struct Template(T) { T t; }
+
+Template!Bar a;
+Template!Bar b;
+
+immutable struct Bar { }
+
+static assert(is(typeof(a) == typeof(b)));
+static assert(is(typeof(a) == Template!(immutable Bar)));
+
+Template!C c1;
+Template!C c2;
+
+immutable class C { }
+
+static assert(is(typeof(c1) == typeof(c2)));
+static assert(is(typeof(c1) == Template!(immutable C)));
new file mode 100644
@@ -0,0 +1,18 @@
+// https://issues.dlang.org/show_bug.cgi?id=22510
+
+struct S
+{
+ int b;
+
+ @disable this(this);
+ this (scope ref inout S) inout
+ {
+ this.b = b;
+ }
+}
+
+void main()
+{
+ auto scoped_s = S(4);
+ auto heap_s = new S(42);
+}
new file mode 100644
@@ -0,0 +1,35 @@
+/++
+https://issues.dlang.org/show_bug.cgi?id=21538
+
+TEST_OUTPUT:
+---
+fail_compilation/covariant_override.d(23): Error: function `@safe void covariant_override.CI.f(void delegate() @safe dg)` does not override any function, did you mean to override `@safe void covariant_override.I.f(void delegate() @system dg)`?
+fail_compilation/covariant_override.d(34): Error: function `@safe void covariant_override.CA.f(void delegate() @safe dg)` does not override any function, did you mean to override `@safe void covariant_override.A.f(void delegate() @system dg)`?
+fail_compilation/covariant_override.d(20): Error: class `covariant_override.CI` interface function `void f(void delegate() @system dg) @safe` is not implemented
+---
+++/
+
+static assert(!is(void delegate() @system : void delegate() @safe));
+static assert( is(void delegate() @safe : void delegate() @system));
+
+interface I
+{
+ void f(void delegate() @system dg) @safe;
+}
+
+class CI : I
+{
+ // this overrride should not be legal
+ override void f(void delegate() @safe dg) @safe { }
+}
+
+abstract class A
+{
+ void f(void delegate() @system dg) @safe;
+}
+
+class CA : A
+{
+ // this overrride should not be legal
+ override void f(void delegate() @safe dg) @safe { }
+}
@@ -5,8 +5,8 @@ fail_compilation/fail10964.d(28): Error: function `fail10964.S.__postblit` is no
fail_compilation/fail10964.d(29): Error: function `fail10964.S.__postblit` is not `nothrow`
fail_compilation/fail10964.d(30): Error: function `fail10964.S.__postblit` is not `nothrow`
fail_compilation/fail10964.d(33): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(34): Error: function `fail10964.S.__postblit` is not `nothrow`
-fail_compilation/fail10964.d(35): Error: function `fail10964.S.__postblit` is not `nothrow`
+fail_compilation/fail10964.d(34): Error: function `core.internal.array.construction._d_arraysetctor!(S[], S)._d_arraysetctor` is not `nothrow`
+fail_compilation/fail10964.d(35): Error: function `core.internal.array.construction._d_arrayctor!(S[], S)._d_arrayctor` is not `nothrow`
fail_compilation/fail10964.d(22): Error: `nothrow` function `fail10964.foo` may throw
---
*/
@@ -1,24 +1,26 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail10968.d(39): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(39): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(40): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(40): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here
fail_compilation/fail10968.d(41): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
fail_compilation/fail10968.d(41): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(44): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(44): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here
-fail_compilation/fail10968.d(45): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(45): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(42): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(42): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(43): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(43): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here
fail_compilation/fail10968.d(46): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
fail_compilation/fail10968.d(46): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
-fail_compilation/fail10968.d(27): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(47): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(47): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(47): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arraysetctor!(SA[], SA)._d_arraysetctor`
+fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(48): Error: `@safe` function `fail10968.bar` cannot call `@system` function `fail10968.SA.__postblit`
+fail_compilation/fail10968.d(29): `fail10968.SA.__postblit` is declared here
+fail_compilation/fail10968.d(48): Error: `pure` function `fail10968.bar` cannot call impure function `core.internal.array.construction._d_arrayctor!(SA[], SA)._d_arrayctor`
---
*/
@@ -49,12 +51,12 @@ void bar() pure @safe
/*
TEST_OUTPUT:
---
-fail_compilation/fail10968.d(72): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
-fail_compilation/fail10968.d(73): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
fail_compilation/fail10968.d(74): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
-fail_compilation/fail10968.d(77): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
-fail_compilation/fail10968.d(78): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(75): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(76): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
fail_compilation/fail10968.d(79): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(80): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
+fail_compilation/fail10968.d(81): Error: struct `fail10968.SD` is not copyable because it has a disabled postblit
---
*/
@@ -1,25 +1,25 @@
/*
-REQUIRED_ARGS: -de
+REQUIRED_ARGS: -de -revert=intpromote
TEST_OUTPUT:
---
-fail_compilation/fail16997.d(31): Deprecation: integral promotion not done for `~c`, use '-preview=intpromote' switch or `~cast(int)(c)`
-fail_compilation/fail16997.d(32): Deprecation: integral promotion not done for `-c`, use '-preview=intpromote' switch or `-cast(int)(c)`
-fail_compilation/fail16997.d(33): Deprecation: integral promotion not done for `+c`, use '-preview=intpromote' switch or `+cast(int)(c)`
-fail_compilation/fail16997.d(36): Deprecation: integral promotion not done for `~w`, use '-preview=intpromote' switch or `~cast(int)(w)`
-fail_compilation/fail16997.d(37): Deprecation: integral promotion not done for `-w`, use '-preview=intpromote' switch or `-cast(int)(w)`
-fail_compilation/fail16997.d(38): Deprecation: integral promotion not done for `+w`, use '-preview=intpromote' switch or `+cast(int)(w)`
-fail_compilation/fail16997.d(41): Deprecation: integral promotion not done for `~sb`, use '-preview=intpromote' switch or `~cast(int)(sb)`
-fail_compilation/fail16997.d(42): Deprecation: integral promotion not done for `-sb`, use '-preview=intpromote' switch or `-cast(int)(sb)`
-fail_compilation/fail16997.d(43): Deprecation: integral promotion not done for `+sb`, use '-preview=intpromote' switch or `+cast(int)(sb)`
-fail_compilation/fail16997.d(46): Deprecation: integral promotion not done for `~ub`, use '-preview=intpromote' switch or `~cast(int)(ub)`
-fail_compilation/fail16997.d(47): Deprecation: integral promotion not done for `-ub`, use '-preview=intpromote' switch or `-cast(int)(ub)`
-fail_compilation/fail16997.d(48): Deprecation: integral promotion not done for `+ub`, use '-preview=intpromote' switch or `+cast(int)(ub)`
-fail_compilation/fail16997.d(51): Deprecation: integral promotion not done for `~s`, use '-preview=intpromote' switch or `~cast(int)(s)`
-fail_compilation/fail16997.d(52): Deprecation: integral promotion not done for `-s`, use '-preview=intpromote' switch or `-cast(int)(s)`
-fail_compilation/fail16997.d(53): Deprecation: integral promotion not done for `+s`, use '-preview=intpromote' switch or `+cast(int)(s)`
-fail_compilation/fail16997.d(56): Deprecation: integral promotion not done for `~us`, use '-preview=intpromote' switch or `~cast(int)(us)`
-fail_compilation/fail16997.d(57): Deprecation: integral promotion not done for `-us`, use '-preview=intpromote' switch or `-cast(int)(us)`
-fail_compilation/fail16997.d(58): Deprecation: integral promotion not done for `+us`, use '-preview=intpromote' switch or `+cast(int)(us)`
+fail_compilation/fail16997.d(31): Deprecation: integral promotion not done for `~c`, remove '-revert=intpromote' switch or `~cast(int)(c)`
+fail_compilation/fail16997.d(32): Deprecation: integral promotion not done for `-c`, remove '-revert=intpromote' switch or `-cast(int)(c)`
+fail_compilation/fail16997.d(33): Deprecation: integral promotion not done for `+c`, remove '-revert=intpromote' switch or `+cast(int)(c)`
+fail_compilation/fail16997.d(36): Deprecation: integral promotion not done for `~w`, remove '-revert=intpromote' switch or `~cast(int)(w)`
+fail_compilation/fail16997.d(37): Deprecation: integral promotion not done for `-w`, remove '-revert=intpromote' switch or `-cast(int)(w)`
+fail_compilation/fail16997.d(38): Deprecation: integral promotion not done for `+w`, remove '-revert=intpromote' switch or `+cast(int)(w)`
+fail_compilation/fail16997.d(41): Deprecation: integral promotion not done for `~sb`, remove '-revert=intpromote' switch or `~cast(int)(sb)`
+fail_compilation/fail16997.d(42): Deprecation: integral promotion not done for `-sb`, remove '-revert=intpromote' switch or `-cast(int)(sb)`
+fail_compilation/fail16997.d(43): Deprecation: integral promotion not done for `+sb`, remove '-revert=intpromote' switch or `+cast(int)(sb)`
+fail_compilation/fail16997.d(46): Deprecation: integral promotion not done for `~ub`, remove '-revert=intpromote' switch or `~cast(int)(ub)`
+fail_compilation/fail16997.d(47): Deprecation: integral promotion not done for `-ub`, remove '-revert=intpromote' switch or `-cast(int)(ub)`
+fail_compilation/fail16997.d(48): Deprecation: integral promotion not done for `+ub`, remove '-revert=intpromote' switch or `+cast(int)(ub)`
+fail_compilation/fail16997.d(51): Deprecation: integral promotion not done for `~s`, remove '-revert=intpromote' switch or `~cast(int)(s)`
+fail_compilation/fail16997.d(52): Deprecation: integral promotion not done for `-s`, remove '-revert=intpromote' switch or `-cast(int)(s)`
+fail_compilation/fail16997.d(53): Deprecation: integral promotion not done for `+s`, remove '-revert=intpromote' switch or `+cast(int)(s)`
+fail_compilation/fail16997.d(56): Deprecation: integral promotion not done for `~us`, remove '-revert=intpromote' switch or `~cast(int)(us)`
+fail_compilation/fail16997.d(57): Deprecation: integral promotion not done for `-us`, remove '-revert=intpromote' switch or `-cast(int)(us)`
+fail_compilation/fail16997.d(58): Deprecation: integral promotion not done for `+us`, remove '-revert=intpromote' switch or `+cast(int)(us)`
---
*/
deleted file mode 100644
@@ -1,12 +0,0 @@
-// REQUIRED_ARGS: -preview=dip1000
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail809.d(11): Error: scope variable `dg_` may not be returned
----
-*/
-int delegate() test(lazy int dg)
-{
- int delegate() dg_ = &dg;
- return dg_;
-}
@@ -120,7 +120,7 @@ fail_compilation/fob2.d(515): Error: variable `fob2.test52.p` has undefined stat
}
-@live void test52()
+@live void test52() @safe
{
int x = 5;
auto p = &x;
new file mode 100644
@@ -0,0 +1,10 @@
+module imports.test20023b;
+
+auto threw()() @safe
+{
+ try
+ throw new Exception("Hello");
+ catch (Exception e)
+ return e;
+ assert(0);
+}
@@ -14,14 +14,14 @@ fail_compilation/retscope.d(49): Error: address of struct temporary returned by
-int* foo1(return scope int* p) { return p; } // ok
+int* foo1(return scope int* p) @safe { return p; } // ok
-int* foo2()(scope int* p) { return p; } // ok, 'return' is inferred
+int* foo2()(scope int* p) @safe { return p; } // ok, 'return' is inferred
alias foo2a = foo2!();
-int* foo3(scope int* p) { return p; } // error
+int* foo3(scope int* p) @safe { return p; } // error
-int* foo4(bool b)
+int* foo4(bool b) @safe
{
int i;
int j;
@@ -1,18 +1,52 @@
/* TEST_OUTPUT:
+PERMUTE_ARGS -dip1000
---
-fail_compilation/test15191.d(17): Error: cannot take address of `ref return` of `foo()` in `@safe` function `bar`
+fail_compilation/test15191.d(31): Error: returning `&identity(x)` escapes a reference to local variable `x`
+fail_compilation/test15191.d(37): Error: returning `&identityPtr(x)` escapes a reference to local variable `x`
+fail_compilation/test15191.d(43): Error: cannot take address of `ref return` of `identityPtr()` in `@safe` function `addrOfRefTransitive`
+fail_compilation/test15191.d(43): Error: returning `&identityPtr(x)` escapes a reference to local variable `x`
---
*/
-
// https://issues.dlang.org/show_bug.cgi?id=15191
+// https://issues.dlang.org/show_bug.cgi?id=22519
-ref int foo(return ref int s)@safe
+@safe:
+ref int foo(return ref int s)
{
return s;
}
-int* bar(return ref int s) @safe
+int* bar(return ref int s)
{
return &foo(s);
}
+
+ref int identity(ref return int x) {return x;}
+ref int* identityPtr(ref return int* x) {return x;}
+
+int* addrOfRefEscape()
+{
+ int x;
+ return &identity(x);
+}
+
+int** addrOfRefSystem() @system
+{
+ int* x;
+ return &identityPtr(x);
+}
+
+int** addrOfRefTransitive()
+{
+ int* x;
+ return &identityPtr(x);
+}
+
+int gInt;
+ref int getGlobalInt() {return gInt;}
+
+int* addrOfRefGlobal()
+{
+ return &getGlobalInt();
+}
new file mode 100644
@@ -0,0 +1,20 @@
+/*
+https://issues.dlang.org/show_bug.cgi?id=15399
+REQUIRED_ARGS: -preview=dip1000
+TEST_OUTPUT:
+---
+fail_compilation/test17977.d(19): Error: address of variable `__slList3` assigned to `elem` with longer lifetime
+---
+*/
+
+@safe:
+struct List {
+ int* data;
+ ~this();
+ int* front() return;
+}
+
+void test()
+{
+ auto elem = List().front;
+}
new file mode 100644
@@ -0,0 +1,16 @@
+// REQUIRED_ARGS: -preview=dip1000 -preview=dip1008 -Ifail_compilation/extra-files
+// https://issues.dlang.org/show_bug.cgi?id=20023
+/*
+TEST_OUTPUT:
+---
+fail_compilation/imports/test20023b.d(8): Error: scope variable `e` may not be returned
+fail_compilation/test20023.d(15): Error: template instance `imports.test20023b.threw!()` error instantiating
+---
+*/
+import imports.test20023b;
+
+@safe:
+void main()
+{
+ threw!()();
+}
new file mode 100644
@@ -0,0 +1,63 @@
+/********************************************
+TEST_OUTPUT:
+---
+fail_compilation/traits_initSymbol.d(105): Error: struct / class type expected as argument to __traits(initSymbol) instead of `int`
+fail_compilation/traits_initSymbol.d(106): Error: struct / class type expected as argument to __traits(initSymbol) instead of `S[2]`
+fail_compilation/traits_initSymbol.d(107): Error: struct / class type expected as argument to __traits(initSymbol) instead of `123`
+---
+*/
+#line 100
+
+struct S { int i = 4; }
+
+void test1()
+{
+ const void[] initInt = __traits(initSymbol, int);
+ const void[] initArray = __traits(initSymbol, S[2]);
+ const void[] initValue = __traits(initSymbol, 123);
+}
+
+/********************************************
+TEST_OUTPUT:
+---
+fail_compilation/traits_initSymbol.d(203): Error: cannot determine the address of the initializer symbol during CTFE
+fail_compilation/traits_initSymbol.d(203): called from here: `(*function () pure nothrow @nogc @safe => S)()`
+---
+*/
+#line 200
+
+void test2()
+{
+ enum initLen = (() => __traits(initSymbol, S))();
+}
+
+/********************************************
+TEST_OUTPUT:
+---
+fail_compilation/traits_initSymbol.d(305): Error: struct / class type expected as argument to __traits(initSymbol) instead of `traits_initSymbol.Interface`
+---
+*/
+#line 300
+
+interface Interface {}
+
+void test3()
+{
+ const void[] initInterface = __traits(initSymbol, Interface);
+}
+
+/********************************************
+TEST_OUTPUT:
+---
+fail_compilation/traits_initSymbol.d(404): Error: expected 1 arguments for `initSymbol` but had 0
+fail_compilation/traits_initSymbol.d(405): Error: expected 1 arguments for `initSymbol` but had 2
+---
+*/
+#line 400
+
+
+void test4()
+{
+ const void[] tmp = __traits(initSymbol);
+ const void[] tmo = __traits(initSymbol, Interface, S);
+}
new file mode 100644
@@ -0,0 +1,163 @@
+alias T = MyStruct!float;
+
+struct MyStruct(U)
+{
+ U x;
+ U y;
+
+ this(U xx, U yy)
+ {
+ x = xx;
+ y = yy;
+ }
+
+ MyStruct!U opBinary(string op)(MyStruct!U z) const
+ {
+ alias C = typeof(return);
+ auto w = C(this.x, this.y);
+ return w.opOpAssign!(op)(z);
+ }
+
+ MyStruct!U opBinaryRight(string op)(MyStruct!U z) const
+ {
+ return opBinary!(op)(z);
+ }
+
+ ref MyStruct opOpAssign(string op, U)(const MyStruct!U z)
+ {
+ mixin ("x "~op~"= z.x;");
+ mixin ("y "~op~"= z.y;");
+ return this;
+ }
+
+ MyStruct!U opBinary(string op, R)(R z) const
+ if (is(R == int) || is(R == float))
+ {
+ alias C = typeof(return);
+ auto w = C(this.x, this.y);
+ return w.opOpAssign!(op)(z);
+ }
+
+ MyStruct!U opBinaryRight(string op, R)(R z) const
+ if (is(R == int) || is(R == float))
+ {
+ return opBinary!(op)(z);
+ }
+
+ ref MyStruct opOpAssign(string op, R)(const R z)
+ if (is(R == int) || is(R == float))
+ {
+ mixin ("x "~op~"= z;");
+ return this;
+ }
+}
+
+void main()
+{
+ T c = MyStruct!float(1.0f, 1.0f);
+ T[] arr = [T(1,1), T(2,2), T(3,3), T(4,4), T(5,5), T(6,6)];
+ T[] result = new T[arr.length];
+
+ // part 2
+
+ result[0] = c * c;
+ assert(result[0] == T(1, 1));
+
+ result[0] = arr[1] * arr[2];
+ assert(result[0] == T(6, 6));
+
+ int[] intarr = [6, 5, 4, 3, 2, 1];
+
+ result[] = arr[] * arr[];
+ assert(result[] == [T(1, 1), T(4, 4), T(9, 9), T(16, 16), T(25, 25), T(36, 36)]);
+
+ result[] = arr[] * 3;
+ assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+ result[] = 3 * arr[];
+ assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+
+ result[] = arr[];
+ result[1..3] = arr[1..3] * 2.0f;
+ assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(4, 4), T(5, 5), T(6, 6)]);
+ result[1..3] = 2.0f * arr[1..3];
+ assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(4, 4), T(5, 5), T(6, 6)]);
+
+ result[] = arr[];
+ result[1..$] = arr[1..$] * 2.0f;
+ assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(8, 4), T(10, 5), T(12, 6)]);
+ result[1..$] = 2.0f * arr[1..$];
+ assert(result[] == [T(1, 1), T(4, 2), T(6, 3), T(8, 4), T(10, 5), T(12, 6)]);
+
+ result[] = intarr[] * arr[];
+ assert(result[] == [T(6, 1), T(10, 2), T(12, 3), T(12, 4), T(10, 5), T(6, 6)]);
+ result[] = arr[] * intarr[];
+ assert(result[] == [T(6, 1), T(10, 2), T(12, 3), T(12, 4), T(10, 5), T(6, 6)]);
+
+ result[] = intarr[] * T(2,3);
+ assert(result[] == [T(12, 3), T(10, 3), T(8, 3), T(6, 3), T(4, 3), T(2, 3)]);
+ result[] = T(2,3) * intarr[];
+ assert(result[] == [T(12, 3), T(10, 3), T(8, 3), T(6, 3), T(4, 3), T(2, 3)]);
+
+ result[] = intarr[] * c;
+ assert(result[] == [T(6, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]);
+ result[] = c * intarr[];
+ assert(result[] == [T(6, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]);
+
+ result[] = arr[];
+ result[1..3] = intarr[1..3] * c;
+ assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(4, 4), T(5, 5), T(6, 6)]);
+ result[1..3] = c * intarr[1..3];
+ assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(4, 4), T(5, 5), T(6, 6)]);
+
+ result[1..$] = intarr[1..$] * c;
+ assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]);
+ result[1..$] = c * intarr[1..$];
+ assert(result[] == [T(1, 1), T(5, 1), T(4, 1), T(3, 1), T(2, 1), T(1, 1)]);
+
+ result[] = arr[];
+ result[1..3] = intarr[1..3] * arr[1..3];
+ assert(result[] == [T(1, 1), T(10, 2), T(12, 3), T(4, 4), T(5, 5), T(6, 6)]);
+ result[1..3] = arr[1..3] * intarr[1..3];
+ assert(result[] == [T(1, 1), T(10, 2), T(12, 3), T(4, 4), T(5, 5), T(6, 6)]);
+
+ result[] = [1,2,3,4,5,6] * c;
+ assert(result[] == [T(1, 1), T(2, 1), T(3, 1), T(4, 1), T(5, 1), T(6, 1)]);
+ result[] = c * [1,2,3,4,5,6];
+ assert(result[] == [T(1, 1), T(2, 1), T(3, 1), T(4, 1), T(5, 1), T(6, 1)]);
+
+ result[] = arr[] * [1,2,3,4,5,6];
+ assert(result[] == [T(1, 1), T(4, 2), T(9, 3), T(16, 4), T(25, 5), T(36, 6)]);
+ result[] = [1,2,3,4,5,6] * arr[];
+ assert(result[] == [T(1, 1), T(4, 2), T(9, 3), T(16, 4), T(25, 5), T(36, 6)]);
+
+ result[] = [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c] * [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c];
+ assert(result[] == [T(1, 1), T(4, 1), T(9, 1), T(16, 1), T(25, 1), T(36, 1)]);
+
+ result[] = [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c] * [1,2,3,4,5,6];
+ assert(result[] == [T(1, 1), T(4, 1), T(9, 1), T(16, 1), T(25, 1), T(36, 1)]);
+ result[] = [1,2,3,4,5,6] * [c, 2 * c, 3 * c, 4 * c, 5 * c, 6 * c];
+ assert(result[] == [T(1, 1), T(4, 1), T(9, 1), T(16, 1), T(25, 1), T(36, 1)]);
+
+ result[] = arr[] * c;
+ assert(result[] == [T(1, 1), T(2, 2), T(3, 3), T(4, 4), T(5, 5), T(6, 6)]);
+ result[] = c * arr[];
+ assert(result[] == [T(1, 1), T(2, 2), T(3, 3), T(4, 4), T(5, 5), T(6, 6)]);
+
+ result[] = c * 3.0f * arr[];
+ assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+ result[] = 3.0f * c * arr[];
+ assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+
+ result[] = arr[] * 3.0f * c;
+ assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+ // result[] = arr[] * c * 3.0f; //not ok
+ // assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+
+ result[] = 3.0f * arr[] * c;
+ assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+ // result[] = c * arr[] * 3.0f; //not ok
+ // assert(result[] == [T(3, 1), T(6, 2), T(9, 3), T(12, 4), T(15, 5), T(18, 6)]);
+
+ result[] = c * arr[] * c;
+ assert(result[] == [T(1, 1), T(2, 2), T(3, 3), T(4, 4), T(5, 5), T(6, 6)]);
+}
@@ -1,5 +1,5 @@
/*
-REQUIRED_ARGS: -mcpu=native -preview=intpromote
+REQUIRED_ARGS: -mcpu=native
PERMUTE_ARGS: -O -inline -release
*/
new file mode 100644
@@ -0,0 +1,39 @@
+// https://issues.dlang.org/show_bug.cgi?id=15862
+
+/*
+PERMUTE_ARGS:
+REQUIRED_ARGS: -O -release
+*/
+
+
+int* p() pure nothrow {return new int;}
+int[] a() pure nothrow {return [0];}
+Object o() pure nothrow {return new Object;}
+
+auto pa() pure nothrow {return new int;}
+
+void main()
+{
+ {
+ int* p1 = p();
+ int* p2 = p();
+
+ if (p1 is p2) assert(0);
+
+ int[] a1 = a();
+ int[] a2 = a();
+
+ if (a1 is a2) assert(0);
+
+ Object o1 = o();
+ Object o2 = o();
+
+ if (o1 is o2) assert(0);
+ }
+ {
+ auto p1 = pa();
+ auto p2 = pa();
+
+ if (p1 is p2) assert(0);
+ }
+}
new file mode 100644
@@ -0,0 +1,47 @@
+// https://issues.dlang.org/show_bug.cgi?id=21367
+
+string result = "";
+
+struct RCArray(T)
+{
+ T* data;
+ this(this)
+ {
+ result ~= "A";
+ }
+ ~this()
+ {
+ result ~= "B";
+ }
+}
+
+struct Variant(T...)
+{
+ union
+ {
+ T payload;
+ }
+ this(this)
+ {
+ result ~= "C";
+ }
+
+ ~this()
+ {
+ result ~= "D";
+ }
+}
+
+alias Ft = Variant!(RCArray!double, RCArray!int);
+
+void fun(Ft a) {}
+void main()
+{
+ Ft a;
+ Ft b = a;
+}
+
+static ~this()
+{
+ assert(result == "CDD");
+}
new file mode 100644
@@ -0,0 +1,16 @@
+// REQUIRED_ARGS: -debug -O -release
+// https://issues.dlang.org/show_bug.cgi?id=22277
+
+bool secret = false;
+
+void free(immutable void* x) pure nothrow
+{
+ debug secret = true;
+}
+
+void main()
+{
+ free(null);
+ if (!secret)
+ assert(0);
+}
@@ -1,4 +1,4 @@
-/* PERMUTE_ARGS:
+/* PERMUTE_ARGS: -preview=dip1000
*/
// https://issues.dlang.org/show_bug.cgi?id=15624
@@ -140,3 +140,32 @@ void testInverseAttributes()
}
safe();
}
+
+// https://issues.dlang.org/show_bug.cgi?id=20907
+Lockstep!() lockstep()
+{
+ return Lockstep!()();
+}
+
+struct Lockstep()
+{
+ int opApply(int delegate(int) callback) @system
+ {
+ return 0;
+ }
+
+ int opApply(int delegate(int) pure nothrow @nogc @safe callback) pure nothrow @nogc @safe
+ {
+ return 0;
+ }
+}
+
+void foo0()
+{
+ foreach (x; lockstep()) {}
+}
+
+void foo1()
+{
+ foreach (x; lockstep()) {}
+}
@@ -1,5 +1,5 @@
/*
-REQUIRED_ARGS: -mcpu=native -preview=intpromote
+REQUIRED_ARGS: -mcpu=native
PERMUTE_ARGS: -O -inline -release
*/
@@ -2860,9 +2860,11 @@ static assert(is(S7038b == shared));
immutable struct S7038c{ int x; }
static assert(is(S7038c == immutable));
-static assert(!is(C7038 == const));
+// https://issues.dlang.org/show_bug.cgi?id=22515
+// Classes fixed for consistency with structs
+static assert(is(C7038 == const));
const class C7038{ int x; }
-static assert(!is(C7038 == const));
+static assert(is(C7038 == const));
void test7038()
{
@@ -2871,7 +2873,7 @@ void test7038()
static assert(is(typeof(s.x) == const int));
C7038 c;
- static assert(!is(typeof(c) == const));
+ static assert(is(typeof(c) == const));
static assert(is(typeof(c.x) == const int));
}
new file mode 100644
@@ -0,0 +1,119 @@
+struct Zero
+{
+ int x;
+}
+
+void testZero()
+{
+ auto zeroInit = __traits(initSymbol, Zero);
+ static assert(is(typeof(zeroInit) == const(void[])));
+
+ assert(zeroInit.ptr is null);
+ assert(zeroInit.length == Zero.sizeof);
+}
+
+struct NonZero
+{
+ long x = 1;
+}
+
+void testNonZero()
+{
+ auto nonZeroInit = __traits(initSymbol, NonZero);
+ static assert(is(typeof(nonZeroInit) == const(void[])));
+
+ assert(nonZeroInit.ptr);
+ assert(nonZeroInit.length == NonZero.sizeof);
+ assert(cast(const(long[])) nonZeroInit == [1L]);
+}
+
+class C
+{
+ short x = 123;
+}
+
+void testClass()
+{
+ auto cInit = __traits(initSymbol, C);
+ static assert(is(typeof(cInit) == const(void[])));
+
+ assert(cInit.ptr);
+ assert(cInit.length == __traits(classInstanceSize, C));
+
+ scope c = new C;
+ assert((cast(void*) c)[0 .. cInit.length] == cInit);
+}
+
+struct AlignedStruct
+{
+ short s = 5;
+ // 2 byte padding
+ align(4) char c = 'c';
+ // 3 byte padding
+ int i = 4;
+ // reduced alignment
+ align(1) long l = 0xDEADBEEF;
+}
+
+void testAlignedStruct()
+{
+ auto init = __traits(initSymbol, AlignedStruct);
+
+ assert(init.ptr);
+ assert(init.length == AlignedStruct.sizeof);
+
+ version (GNU)
+ AlignedStruct exp = AlignedStruct();
+ else
+ AlignedStruct exp;
+ assert(init == (cast(void*) &exp)[0 .. AlignedStruct.sizeof]);
+
+}
+
+class AlignedClass : C
+{
+ short s = 5;
+ // 2 byte padding
+ align(4) char c = 'c';
+ // 3 byte padding
+ int i = 4;
+ // reduced alignment
+ align(1) long l = 0xDEADBEEF;
+}
+
+void testAlignedClass()
+{
+ auto init = __traits(initSymbol, AlignedClass);
+
+ assert(init.ptr);
+ assert(init.length == __traits(classInstanceSize, AlignedClass));
+
+ scope ac = new AlignedClass();
+ assert(init == (cast(void*) ac)[0 .. init.length]);
+}
+
+extern (C++) class ExternCppClass
+{
+ int i = 4;
+}
+
+void testExternCppClass()
+{
+ auto init = __traits(initSymbol, ExternCppClass);
+
+ assert(init.ptr);
+ assert(init.length == __traits(classInstanceSize, ExternCppClass));
+
+ scope ac = new ExternCppClass();
+ assert(init == (cast(void*) ac)[0 .. init.length]);
+}
+
+void main()
+{
+ testZero();
+ testNonZero();
+ testClass();
+ testAlignedStruct();
+ testAlignedClass();
+ testExternCppClass();
+}
@@ -4903,7 +4903,7 @@ static assert(is(typeof(S5933d.x) == FuncType5933));
class C5933a { auto x() { return 0; } }
-static assert(is(typeof(&(new C5933b()).x) == int delegate()));
+static assert(is(typeof(&(new C5933b()).x) == int delegate() pure nothrow @nogc @safe));
class C5933b { auto x() { return 0; } }
//static assert(is(typeof((new C5933b()).x) == FuncType5933));
@@ -7923,8 +7923,9 @@ void test17349()
{
static struct S
{
- int bar(void delegate(ref int*)) { return 1; }
- int bar(void delegate(ref const int*)) const { return 2; }
+ // Specify attribute inferred for dg1/dg2
+ int bar(void delegate(ref int*) pure nothrow @nogc @safe) { return 1; }
+ int bar(void delegate(ref const int*) pure nothrow @nogc @safe) const { return 2; }
}
void dg1(ref int*) { }
new file mode 100644
@@ -0,0 +1,103 @@
+#include <stdarg.h>
+#include <assert.h>
+
+class C1
+{
+public:
+ virtual ~C1();
+
+ int i;
+
+ int f0();
+ int f1(int a);
+ int f2(int a, int b);
+ virtual int f3(int a, int b);
+ int f4(int a, ...);
+};
+
+C1::~C1()
+{
+}
+
+int C1::f0()
+{
+ return i;
+}
+
+int C1::f1(int a)
+{
+ return i + a;
+}
+
+int C1::f2(int a, int b)
+{
+ return i + a + b;
+}
+
+int C1::f3(int a, int b)
+{
+ return i + a + b;
+}
+
+int C1::f4(int a, ...)
+{
+ int r = i + a;
+ int last = a;
+
+ va_list argp;
+ va_start(argp, a);
+ while (last)
+ {
+ last = va_arg(argp, int);
+ r += last;
+ }
+ va_end(argp);
+ return r;
+}
+
+C1 *createC1()
+{
+ return new C1();
+}
+
+class C2
+{
+public:
+ virtual ~C2();
+
+ int i;
+
+ int f0();
+ int f1(int a);
+ int f2(int a, int b);
+ virtual int f3(int a, int b);
+ int f4(int a, ...);
+};
+
+C2 *createC2();
+
+void runCPPTests()
+{
+ C2 *c2 = createC2();
+ c2->i = 100;
+ assert(c2->f0() == 100);
+ assert(c2->f1(1) == 101);
+ assert(c2->f2(20, 3) == 123);
+ assert(c2->f3(20, 3) == 123);
+ assert(c2->f4(20, 3, 0) == 123);
+
+ int (C2::*fp0)() = &C2::f0;
+ int (C2::*fp1)(int) = &C2::f1;
+ int (C2::*fp2)(int, int) = &C2::f2;
+ int (C2::*fp3)(int, int) = &C2::f3;
+#ifndef __DMC__
+ int (C2::*fp4)(int, ...) = &C2::f4;
+#endif
+ assert((c2->*(fp0))() == 100);
+ assert((c2->*(fp1))(1) == 101);
+ assert((c2->*(fp2))(20, 3) == 123);
+ assert((c2->*(fp3))(20, 3) == 123);
+#ifndef __DMC__
+ assert((c2->*(fp4))(20, 3, 0) == 123);
+#endif
+}
new file mode 100644
@@ -0,0 +1,151 @@
+// EXTRA_CPP_SOURCES: cpp7925.cpp
+
+/*
+Exclude -O due to a codegen bug on OSX:
+https://issues.dlang.org/show_bug.cgi?id=22556
+
+PERMUTE_ARGS(osx): -inline -release -g
+*/
+
+import core.vararg;
+
+extern(C++) class C1
+{
+public:
+ ~this();
+
+ int i;
+
+ final int f0();
+ final int f1(int a);
+ final int f2(int a, int b);
+ int f3(int a, int b);
+ final int f4(int a, ...);
+};
+
+extern(C++) C1 createC1();
+
+extern(C++) class C2
+{
+public:
+ ~this()
+ {
+ }
+
+ int i;
+
+ final int f0()
+ {
+ return i;
+ }
+
+ final int f1(int a)
+ {
+ return i + a;
+ }
+
+ final int f2(int a, int b)
+ {
+ return i + a + b;
+ }
+
+ int f3(int a, int b)
+ {
+ return i + a + b;
+ }
+
+ final int f4(int a, ...)
+ {
+ int r = i + a;
+ int last = a;
+
+ va_list argp;
+ va_start(argp, a);
+ while (last)
+ {
+ last = va_arg!int(argp);
+ r += last;
+ }
+ va_end(argp);
+ return r;
+ }
+};
+
+extern(C++) C2 createC2()
+{
+ return new C2;
+}
+
+auto callMember(alias F, Params...)(__traits(parent, F) obj, Params params)
+{
+ static if(__traits(getFunctionVariadicStyle, F) == "stdarg")
+ enum varargSuffix = ", ...";
+ else
+ enum varargSuffix = "";
+
+ static if(is(typeof(&F) R == return) && is(typeof(F) P == __parameters))
+ mixin("extern(" ~ __traits(getLinkage, F) ~ ") R delegate(P" ~ varargSuffix ~ ") dg;");
+ dg.funcptr = &F;
+ dg.ptr = cast(void*)obj;
+ return dg(params);
+}
+
+extern(C++) void runCPPTests();
+
+void main()
+{
+ C1 c1 = createC1();
+ c1.i = 100;
+ assert(c1.f0() == 100);
+ assert(c1.f1(1) == 101);
+ assert(c1.f2(20, 3) == 123);
+ assert(c1.f3(20, 3) == 123);
+ assert(c1.f4(20, 3, 0) == 123);
+
+ auto dg0 = &c1.f0;
+ auto dg1 = &c1.f1;
+ auto dg2 = &c1.f2;
+ auto dg3 = &c1.f3;
+ auto dg4 = &c1.f4;
+ assert(dg0() == 100);
+ assert(dg1(1) == 101);
+ assert(dg2(20, 3) == 123);
+ assert(dg3(20, 3) == 123);
+ assert(dg4(20, 3, 0) == 123);
+
+ assert(callMember!(C1.f0)(c1) == 100);
+ assert(callMember!(C1.f1)(c1, 1) == 101);
+ assert(callMember!(C1.f2)(c1, 20, 3) == 123);
+ assert(callMember!(C1.f3)(c1, 20, 3) == 123);
+ assert(callMember!(C1.f4)(c1, 20, 3, 0) == 123);
+
+ int i;
+ extern(C++) void delegate() lamdba1 = () {
+ i = 5;
+ };
+ lamdba1();
+ assert(i == 5);
+
+ extern(C++) int function(int, int) lamdba2 = (int a, int b) {
+ return a + b;
+ };
+ assert(lamdba2(3, 4) == 7);
+
+ extern(C++) void delegate(int, ...) lamdba3 = (int a, ...) {
+ i = a;
+ int last = a;
+
+ va_list argp;
+ va_start(argp, a);
+ while (last)
+ {
+ last = va_arg!int(argp);
+ i += last;
+ }
+ va_end(argp);
+ };
+ lamdba3(1000, 200, 30, 4, 0);
+ assert(i == 1234);
+
+ runCPPTests();
+}
@@ -1,4 +1,4 @@
-178c44ff362902af589603767055cfac89215652
+bc58b1e9ea68051af9094651a26313371297b79f
The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository.
@@ -280,9 +280,8 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \
core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \
core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \
- core/sys/linux/syscalls.d core/sys/linux/termios.d \
- core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \
- core/sys/linux/unistd.d
+ core/sys/linux/termios.d core/sys/linux/time.d \
+ core/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d
DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \
@@ -367,9 +367,9 @@ am__objects_18 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
core/sys/linux/sys/procfs.lo core/sys/linux/sys/signalfd.lo \
core/sys/linux/sys/socket.lo core/sys/linux/sys/sysinfo.lo \
core/sys/linux/sys/time.lo core/sys/linux/sys/xattr.lo \
- core/sys/linux/syscalls.lo core/sys/linux/termios.lo \
- core/sys/linux/time.lo core/sys/linux/timerfd.lo \
- core/sys/linux/tipc.lo core/sys/linux/unistd.lo
+ core/sys/linux/termios.lo core/sys/linux/time.lo \
+ core/sys/linux/timerfd.lo core/sys/linux/tipc.lo \
+ core/sys/linux/unistd.lo
@DRUNTIME_OS_LINUX_TRUE@am__objects_19 = $(am__objects_18)
am__objects_20 = core/sys/windows/accctrl.lo \
core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \
@@ -944,9 +944,8 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/sys/procfs.d core/sys/linux/sys/signalfd.d \
core/sys/linux/sys/socket.d core/sys/linux/sys/sysinfo.d \
core/sys/linux/sys/time.d core/sys/linux/sys/xattr.d \
- core/sys/linux/syscalls.d core/sys/linux/termios.d \
- core/sys/linux/time.d core/sys/linux/timerfd.d core/sys/linux/tipc.d \
- core/sys/linux/unistd.d
+ core/sys/linux/termios.d core/sys/linux/time.d \
+ core/sys/linux/timerfd.d core/sys/linux/tipc.d core/sys/linux/unistd.d
DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \
@@ -1675,7 +1674,6 @@ core/sys/linux/sys/socket.lo: core/sys/linux/sys/$(am__dirstamp)
core/sys/linux/sys/sysinfo.lo: core/sys/linux/sys/$(am__dirstamp)
core/sys/linux/sys/time.lo: core/sys/linux/sys/$(am__dirstamp)
core/sys/linux/sys/xattr.lo: core/sys/linux/sys/$(am__dirstamp)
-core/sys/linux/syscalls.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/termios.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/time.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/timerfd.lo: core/sys/linux/$(am__dirstamp)
@@ -54,13 +54,13 @@ pure @safe:
enum AddType { no, yes }
- this( return const(char)[] buf_, return char[] dst_ = null )
+ this( return scope const(char)[] buf_, return scope char[] dst_ = null )
{
this( buf_, AddType.yes, dst_ );
}
- this( return const(char)[] buf_, AddType addType_, return char[] dst_ = null )
+ this( return scope const(char)[] buf_, AddType addType_, return scope char[] dst_ = null )
{
buf = buf_;
addType = addType_;
@@ -105,7 +105,7 @@ pure @safe:
//throw new ParseException( msg );
debug(info) printf( "error: %.*s\n", cast(int) msg.length, msg.ptr );
throw __ctfe ? new ParseException(msg)
- : cast(ParseException) cast(void*) typeid(ParseException).initializer;
+ : cast(ParseException) __traits(initSymbol, ParseException).ptr;
}
@@ -116,7 +116,7 @@ pure @safe:
//throw new OverflowException( msg );
debug(info) printf( "overflow: %.*s\n", cast(int) msg.length, msg.ptr );
- throw cast(OverflowException) cast(void*) typeid(OverflowException).initializer;
+ throw cast(OverflowException) __traits(initSymbol, OverflowException).ptr;
}
@@ -14,16 +14,27 @@ import core.internal.traits : Unqual;
/**
* Does array initialization (not assignment) from another array of the same element type.
* Params:
+ * to = what array to initialize
* from = what data the array should be initialized with
+ * makeWeaklyPure = unused; its purpose is to prevent the function from becoming
+ * strongly pure and risk being optimised out
* Returns:
* The created and initialized array `to`
* Bugs:
* This function template was ported from a much older runtime hook that bypassed safety,
* purity, and throwabilty checks. To prevent breaking existing code, this function template
* is temporarily declared `@trusted` until the implementation can be brought up to modern D expectations.
+ *
+ * The third parameter is never used, but is necessary in order for the
+ * function be treated as weakly pure, instead of strongly pure.
+ * This is needed because constructions such as the one below can be ignored by
+ * the compiler if `_d_arrayctor` is believed to be pure, because purity would
+ * mean the call to `_d_arrayctor` has no effects (no side effects and the
+ * return value is ignored), despite it actually modifying the contents of `a`.
+ * const S[2] b;
+ * const S[2] a = b; // this would get lowered to _d_arrayctor(a, b)
*/
-Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @trusted
- if (is(Unqual!T1 == Unqual!T2))
+Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from, char* makeWeaklyPure = null) @trusted
{
pragma(inline, false);
import core.internal.traits : hasElaborateCopyConstructor;
@@ -32,14 +43,12 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
import core.stdc.stdint : uintptr_t;
debug(PRINTF) import core.stdc.stdio : printf;
- debug(PRINTF) printf("_d_arrayctor(to = %p,%d, from = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, T1.tsize);
+ debug(PRINTF) printf("_d_arrayctor(from = %p,%d) size = %d\n", from.ptr, from.length, T.sizeof);
- Tarr1 to = void;
+ void[] vFrom = (cast(void*) from.ptr)[0..from.length];
+ void[] vTo = (cast(void*) to.ptr)[0..to.length];
- void[] vFrom = (cast(void*)from.ptr)[0..from.length];
- void[] vTo = (cast(void*)to.ptr)[0..to.length];
-
- // Force `enforceRawArraysConformable` to be `pure`
+ // Force `enforceRawArraysConformable` to remain weakly `pure`
void enforceRawArraysConformable(const char[] action, const size_t elementSize,
const void[] a1, const void[] a2) @trusted
{
@@ -50,9 +59,9 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
(cast(Type)&enforceRawArraysConformableNogc)(action, elementSize, a1, a2, false);
}
- enforceRawArraysConformable("initialization", T1.sizeof, vFrom, vTo);
+ enforceRawArraysConformable("initialization", T.sizeof, vFrom, vTo);
- static if (hasElaborateCopyConstructor!T1)
+ static if (hasElaborateCopyConstructor!T)
{
size_t i;
try
@@ -66,7 +75,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
*/
while (i--)
{
- auto elem = cast(Unqual!T1*)&to[i];
+ auto elem = cast(Unqual!T*) &to[i];
destroy(*elem);
}
@@ -76,7 +85,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
else
{
// blit all elements at once
- memcpy(cast(void*) to.ptr, from.ptr, to.length * T1.sizeof);
+ memcpy(cast(void*) to.ptr, from.ptr, to.length * T.sizeof);
}
return to;
@@ -94,7 +103,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
S[4] arr1;
S[4] arr2 = [S(0), S(1), S(2), S(3)];
- arr1 = _d_arrayctor!(typeof(arr1))(arr2[]);
+ _d_arrayctor(arr1[], arr2[]);
assert(counter == 4);
assert(arr1 == arr2);
@@ -117,7 +126,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
S[4] arr1;
S[4] arr2 = [S(0), S(1), S(2), S(3)];
- arr1 = _d_arrayctor!(typeof(arr1))(arr2[]);
+ _d_arrayctor(arr1[], arr2[]);
assert(counter == 4);
assert(arr1 == arr2);
@@ -143,7 +152,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
{
Throw[4] a;
Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)];
- a = _d_arrayctor!(typeof(a))(b[]);
+ _d_arrayctor(a[], b[]);
}
catch (Exception)
{
@@ -168,7 +177,7 @@ Tarr1 _d_arrayctor(Tarr1 : T1[], Tarr2 : T2[], T1, T2)(scope Tarr2 from) @truste
{
NoThrow[4] a;
NoThrow[4] b = [NoThrow(1), NoThrow(2), NoThrow(3), NoThrow(4)];
- a = _d_arrayctor!(typeof(a))(b[]);
+ _d_arrayctor(a[], b[]);
}
catch (Exception)
{
@@ -274,7 +283,7 @@ void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted
{
Throw[4] a;
Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)];
- a = _d_arrayctor!(typeof(a))(b[]);
+ _d_arrayctor(a[], b[]);
}
catch (Exception)
{
@@ -801,7 +801,7 @@ const(ubyte)[] toUbyte(T)(const ref T val) if (is(T == delegate) || is(T : V*, V
}
@trusted pure nothrow @nogc
-const(ubyte)[] toUbyte(T)(const ref return scope T val) if (is(T == struct) || is(T == union))
+const(ubyte)[] toUbyte(T)(const return ref scope T val) if (is(T == struct) || is(T == union))
{
if (__ctfe)
{
@@ -826,7 +826,11 @@ const(ubyte)[] toUbyte(T)(const ref return scope T val) if (is(T == struct) || i
}
else
{
- return (cast(const(ubyte)*)&val)[0 .. T.sizeof];
+ // We're escaping a reference to `val` here because we cannot express
+ // ref return + scope, it's currently seen as ref + return scope
+ // https://issues.dlang.org/show_bug.cgi?id=22541
+ // Once fixed, the @system lambda should be removed
+ return (() @system => (cast(const(ubyte)*)&val)[0 .. T.sizeof])();
}
}
@@ -89,44 +89,35 @@ Emplaces T.init.
In contrast to `emplaceRef(chunk)`, there are no checks for disabled default
constructors etc.
+/
-template emplaceInitializer(T)
+void emplaceInitializer(T)(scope ref T chunk) nothrow pure @trusted
if (!is(T == const) && !is(T == immutable) && !is(T == inout))
{
- import core.internal.traits : hasElaborateAssign, Unqual;
+ import core.internal.traits : hasElaborateAssign;
- // Avoid stack allocation by hacking to get to the struct/union init symbol.
- static if (is(T == struct) || is(T == union))
+ static if (__traits(isZeroInit, T))
{
- pragma(mangle, "_D" ~ Unqual!T.mangleof[1..$] ~ "6__initZ")
- __gshared extern immutable T initializer;
+ import core.stdc.string : memset;
+ memset(cast(void*) &chunk, 0, T.sizeof);
}
-
- void emplaceInitializer(scope ref T chunk) nothrow pure @trusted
+ else static if (__traits(isScalar, T) ||
+ T.sizeof <= 16 && !hasElaborateAssign!T && __traits(compiles, (){ T chunk; chunk = T.init; }))
{
- static if (__traits(isZeroInit, T))
- {
- import core.stdc.string : memset;
- memset(cast(void*) &chunk, 0, T.sizeof);
- }
- else static if (__traits(isScalar, T) ||
- T.sizeof <= 16 && !hasElaborateAssign!T && __traits(compiles, (){ T chunk; chunk = T.init; }))
- {
- chunk = T.init;
- }
- else static if (__traits(isStaticArray, T))
- {
- // For static arrays there is no initializer symbol created. Instead, we emplace elements one-by-one.
- foreach (i; 0 .. T.length)
- {
- emplaceInitializer(chunk[i]);
- }
- }
- else
+ chunk = T.init;
+ }
+ else static if (__traits(isStaticArray, T))
+ {
+ // For static arrays there is no initializer symbol created. Instead, we emplace elements one-by-one.
+ foreach (i; 0 .. T.length)
{
- import core.stdc.string : memcpy;
- memcpy(cast(void*)&chunk, &initializer, T.sizeof);
+ emplaceInitializer(chunk[i]);
}
}
+ else
+ {
+ import core.stdc.string : memcpy;
+ const initializer = __traits(initSymbol, T);
+ memcpy(cast(void*)&chunk, initializer.ptr, initializer.length);
+ }
}
@safe unittest
@@ -119,7 +119,7 @@ char[] signedToTempString(uint radix = 10)(long value, return scope char[] buf)
if (neg)
{
// about to do a slice without a bounds check
- auto trustedSlice(return char[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; }
+ auto trustedSlice(return scope char[] r) @trusted { assert(r.ptr > buf.ptr); return (r.ptr-1)[0..r.length+1]; }
r = trustedSlice(r);
r[0] = '-';
}
@@ -583,7 +583,7 @@ void validate(S)(const scope S s)
/* =================== Conversion to UTF8 ======================= */
@safe pure nothrow @nogc
-char[] toUTF8(return char[] buf, dchar c)
+char[] toUTF8(return scope char[] buf, dchar c)
in
{
assert(isValidDchar(c));
@@ -623,7 +623,7 @@ char[] toUTF8(return char[] buf, dchar c)
* Encodes string s into UTF-8 and returns the encoded string.
*/
@safe pure nothrow
-string toUTF8(return string s)
+string toUTF8(return scope string s)
in
{
validate(s);
@@ -692,7 +692,7 @@ string toUTF8(const scope dchar[] s)
/* =================== Conversion to UTF16 ======================= */
@safe pure nothrow @nogc
-wchar[] toUTF16(return wchar[] buf, dchar c)
+wchar[] toUTF16(return scope wchar[] buf, dchar c)
in
{
assert(isValidDchar(c));
@@ -784,7 +784,7 @@ wptr toUTF16z(const scope char[] s)
/** ditto */
@safe pure nothrow
-wstring toUTF16(return wstring s)
+wstring toUTF16(return scope wstring s)
in
{
validate(s);
@@ -864,7 +864,7 @@ dstring toUTF32(const scope wchar[] s)
/** ditto */
@safe pure nothrow
-dstring toUTF32(return dstring s)
+dstring toUTF32(return scope dstring s)
in
{
validate(s);
@@ -103,8 +103,8 @@ T emplace(T, Args...)(T chunk, auto ref Args args)
" is abstract and it can't be emplaced");
// Initialize the object in its pre-ctor state
- enum classSize = __traits(classInstanceSize, T);
- (() @trusted => (cast(void*) chunk)[0 .. classSize] = typeid(T).initializer[])();
+ const initializer = __traits(initSymbol, T);
+ (() @trusted { (cast(void*) chunk)[0 .. initializer.length] = initializer[]; })();
static if (isInnerClass!T)
{
@@ -224,6 +224,31 @@ T emplace(T, Args...)(void[] chunk, auto ref Args args)
assert(c.i == 5);
}
+///
+@betterC
+@nogc pure nothrow @system unittest
+{
+ // works with -betterC too:
+
+ static extern (C++) class C
+ {
+ @nogc pure nothrow @safe:
+ int i = 3;
+ this(int i)
+ {
+ assert(this.i == 3);
+ this.i = i;
+ }
+ int virtualGetI() { return i; }
+ }
+
+ import core.internal.traits : classInstanceAlignment;
+
+ align(classInstanceAlignment!C) byte[__traits(classInstanceSize, C)] buffer;
+ C c = emplace!C(buffer[], 42);
+ assert(c.virtualGetI() == 42);
+}
+
@system unittest
{
class Outer
@@ -1921,7 +1946,7 @@ private void moveImpl(T)(scope ref T target, return scope ref T source)
static if (is(T == struct))
{
- // Unsafe when compiling without -dip1000
+ // Unsafe when compiling without -preview=dip1000
if ((() @trusted => &source == &target)()) return;
// Destroy target before overwriting it
static if (hasElaborateDestructor!T) target.__xdtor();
@@ -2099,7 +2124,7 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
static if (is(T == struct))
{
- // Unsafe when compiling without -dip1000
+ // Unsafe when compiling without -preview=dip1000
assert((() @trusted => &source !is &target)(), "source and target must not be identical");
static if (hasElaborateAssign!T || !isAssignable!T)
@@ -2123,12 +2148,7 @@ private void moveEmplaceImpl(T)(scope ref T target, return scope ref T source)
static if (__traits(isZeroInit, T))
() @trusted { memset(&source, 0, sz); }();
else
- {
- import core.internal.lifetime : emplaceInitializer;
- ubyte[T.sizeof] init = void;
- emplaceInitializer(*(() @trusted { return cast(T*)init.ptr; }()));
- () @trusted { memcpy(&source, init.ptr, sz); }();
- }
+ () @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }();
}
}
else static if (__traits(isStaticArray, T))
@@ -2201,3 +2221,74 @@ pure nothrow @nogc @system unittest
static assert(!__traits(compiles, f(ncarray)));
f(move(ncarray));
}
+
+/**
+ * This is called for a delete statement where the value
+ * being deleted is a pointer to a struct with a destructor
+ * but doesn't have an overloaded delete operator.
+ *
+ * Params:
+ * p = pointer to the value to be deleted
+ */
+void _d_delstruct(T)(ref T *p)
+{
+ if (p)
+ {
+ debug(PRINTF) printf("_d_delstruct(%p)\n", p);
+
+ import core.memory : GC;
+
+ destroy(*p);
+ GC.free(p);
+ p = null;
+ }
+}
+
+@system unittest
+{
+ int dtors = 0;
+ struct S { ~this() { ++dtors; } }
+
+ S *s = new S();
+ _d_delstruct(s);
+
+ assert(s == null);
+ assert(dtors == 1);
+}
+
+@system unittest
+{
+ int innerDtors = 0;
+ int outerDtors = 0;
+
+ struct Inner { ~this() { ++innerDtors; } }
+ struct Outer
+ {
+ Inner *i1;
+ Inner *i2;
+
+ this(int x)
+ {
+ i1 = new Inner();
+ i2 = new Inner();
+ }
+
+ ~this()
+ {
+ ++outerDtors;
+
+ _d_delstruct(i1);
+ assert(i1 == null);
+
+ _d_delstruct(i2);
+ assert(i2 == null);
+ }
+ }
+
+ Outer *o = new Outer(0);
+ _d_delstruct(o);
+
+ assert(o == null);
+ assert(innerDtors == 2);
+ assert(outerDtors == 1);
+}
@@ -270,7 +270,7 @@ extern(C):
* reentrant, and must be called once for every call to disable before
* automatic collections are enabled.
*/
- pragma(mangle, "gc_enable") static void enable() nothrow; /* FIXME pure */
+ pragma(mangle, "gc_enable") static void enable() nothrow pure;
/**
@@ -280,7 +280,7 @@ extern(C):
* such as during an out of memory condition. This function is reentrant,
* but enable must be called once for each call to disable.
*/
- pragma(mangle, "gc_disable") static void disable() nothrow; /* FIXME pure */
+ pragma(mangle, "gc_disable") static void disable() nothrow pure;
/**
@@ -290,14 +290,14 @@ extern(C):
* and then to reclaim free space. This action may need to suspend all
* running threads for at least part of the collection process.
*/
- pragma(mangle, "gc_collect") static void collect() nothrow; /* FIXME pure */
+ pragma(mangle, "gc_collect") static void collect() nothrow pure;
/**
* Indicates that the managed memory space be minimized by returning free
* physical memory to the operating system. The amount of free memory
* returned depends on the allocator design and on program behavior.
*/
- pragma(mangle, "gc_minimize") static void minimize() nothrow; /* FIXME pure */
+ pragma(mangle, "gc_minimize") static void minimize() nothrow pure;
extern(D):
@@ -551,7 +551,7 @@ extern(C):
* Throws:
* `OutOfMemoryError` on allocation failure.
*/
- pragma(mangle, "gc_realloc") static void* realloc(return void* p, size_t sz, uint ba = 0, const TypeInfo ti = null) pure nothrow;
+ pragma(mangle, "gc_realloc") static void* realloc(return scope void* p, size_t sz, uint ba = 0, const TypeInfo ti = null) pure nothrow;
// https://issues.dlang.org/show_bug.cgi?id=13111
///
@@ -635,7 +635,7 @@ extern(C):
* Returns:
* The actual number of bytes reserved or zero on error.
*/
- pragma(mangle, "gc_reserve") static size_t reserve(size_t sz) nothrow; /* FIXME pure */
+ pragma(mangle, "gc_reserve") static size_t reserve(size_t sz) nothrow pure;
/**
@@ -807,7 +807,7 @@ extern(C):
* }
* ---
*/
- pragma(mangle, "gc_addRoot") static void addRoot(const void* p) nothrow @nogc; /* FIXME pure */
+ pragma(mangle, "gc_addRoot") static void addRoot(const void* p) nothrow @nogc pure;
/**
@@ -818,7 +818,7 @@ extern(C):
* Params:
* p = A pointer into a GC-managed memory block or null.
*/
- pragma(mangle, "gc_removeRoot") static void removeRoot(const void* p) nothrow @nogc; /* FIXME pure */
+ pragma(mangle, "gc_removeRoot") static void removeRoot(const void* p) nothrow @nogc pure;
/**
@@ -849,7 +849,8 @@ extern(C):
* // rawMemory will be recognized on collection.
* ---
*/
- pragma(mangle, "gc_addRange") static void addRange(const void* p, size_t sz, const TypeInfo ti = null) @nogc nothrow; /* FIXME pure */
+ pragma(mangle, "gc_addRange")
+ static void addRange(const void* p, size_t sz, const TypeInfo ti = null) @nogc nothrow pure;
/**
@@ -861,7 +862,7 @@ extern(C):
* Params:
* p = A pointer to a valid memory address or to null.
*/
- pragma(mangle, "gc_removeRange") static void removeRange(const void* p) nothrow @nogc; /* FIXME pure */
+ pragma(mangle, "gc_removeRange") static void removeRange(const void* p) nothrow @nogc pure;
/**
@@ -26,6 +26,10 @@ else version (TVOS)
else version (WatchOS)
version = Darwin;
+version (CRuntime_Glibc)
+ version = AlignedAllocSupported;
+else {}
+
extern (C):
@system:
@@ -166,6 +170,12 @@ void* realloc(void* ptr, size_t size);
///
void free(void* ptr);
+/// since C11
+version (AlignedAllocSupported)
+{
+ void* aligned_alloc(size_t alignment, size_t size);
+}
+
///
noreturn abort() @safe;
///
@@ -35,31 +35,31 @@ nothrow:
@nogc:
///
-inout(void)* memchr(return inout void* s, int c, size_t n) pure;
+inout(void)* memchr(return scope inout void* s, int c, size_t n) pure;
///
int memcmp(scope const void* s1, scope const void* s2, size_t n) pure;
///
-void* memcpy(return void* s1, scope const void* s2, size_t n) pure;
+void* memcpy(return scope void* s1, scope const void* s2, size_t n) pure;
version (Windows)
{
///
int memicmp(scope const char* s1, scope const char* s2, size_t n);
}
///
-void* memmove(return void* s1, scope const void* s2, size_t n) pure;
+void* memmove(return scope void* s1, scope const void* s2, size_t n) pure;
///
-void* memset(return void* s, int c, size_t n) pure;
+void* memset(return scope void* s, int c, size_t n) pure;
///
-char* strcat(return char* s1, scope const char* s2) pure;
+char* strcat(return scope char* s1, scope const char* s2) pure;
///
-inout(char)* strchr(return inout(char)* s, int c) pure;
+inout(char)* strchr(return scope inout(char)* s, int c) pure;
///
int strcmp(scope const char* s1, scope const char* s2) pure;
///
int strcoll(scope const char* s1, scope const char* s2);
///
-char* strcpy(return char* s1, scope const char* s2) pure;
+char* strcpy(return scope char* s1, scope const char* s2) pure;
///
size_t strcspn(scope const char* s1, scope const char* s2) pure;
///
@@ -70,7 +70,7 @@ char* strerror(int errnum);
version (ReturnStrerrorR)
{
///
- const(char)* strerror_r(int errnum, return char* buf, size_t buflen);
+ const(char)* strerror_r(int errnum, return scope char* buf, size_t buflen);
}
// This one is
else
@@ -80,20 +80,20 @@ else
///
size_t strlen(scope const char* s) pure;
///
-char* strncat(return char* s1, scope const char* s2, size_t n) pure;
+char* strncat(return scope char* s1, scope const char* s2, size_t n) pure;
///
int strncmp(scope const char* s1, scope const char* s2, size_t n) pure;
///
-char* strncpy(return char* s1, scope const char* s2, size_t n) pure;
+char* strncpy(return scope char* s1, scope const char* s2, size_t n) pure;
///
-inout(char)* strpbrk(return inout(char)* s1, scope const char* s2) pure;
+inout(char)* strpbrk(return scope inout(char)* s1, scope const char* s2) pure;
///
-inout(char)* strrchr(return inout(char)* s, int c) pure;
+inout(char)* strrchr(return scope inout(char)* s, int c) pure;
///
size_t strspn(scope const char* s1, scope const char* s2) pure;
///
-inout(char)* strstr(return inout(char)* s1, scope const char* s2) pure;
+inout(char)* strstr(return scope inout(char)* s1, scope const char* s2) pure;
///
-char* strtok(return char* s1, scope const char* s2);
+char* strtok(return scope char* s1, scope const char* s2);
///
size_t strxfrm(scope char* s1, scope const char* s2, size_t n);
@@ -213,13 +213,13 @@ c_ulong wcstoul(const scope wchar_t* nptr, wchar_t** endptr, int base);
ulong wcstoull(const scope wchar_t* nptr, wchar_t** endptr, int base);
///
-pure wchar_t* wcscpy(return wchar_t* s1, scope const wchar_t* s2);
+pure wchar_t* wcscpy(return scope wchar_t* s1, scope const wchar_t* s2);
///
-pure wchar_t* wcsncpy(return wchar_t* s1, scope const wchar_t* s2, size_t n);
+pure wchar_t* wcsncpy(return scope wchar_t* s1, scope const wchar_t* s2, size_t n);
///
-pure wchar_t* wcscat(return wchar_t* s1, scope const wchar_t* s2);
+pure wchar_t* wcscat(return scope wchar_t* s1, scope const wchar_t* s2);
///
-pure wchar_t* wcsncat(return wchar_t* s1, scope const wchar_t* s2, size_t n);
+pure wchar_t* wcsncat(return scope wchar_t* s1, scope const wchar_t* s2, size_t n);
///
pure int wcscmp(scope const wchar_t* s1, scope const wchar_t* s2);
///
@@ -229,32 +229,32 @@ pure int wcsncmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n);
///
size_t wcsxfrm(scope wchar_t* s1, scope const wchar_t* s2, size_t n);
///
-pure inout(wchar_t)* wcschr(return inout(wchar_t)* s, wchar_t c);
+pure inout(wchar_t)* wcschr(return scope inout(wchar_t)* s, wchar_t c);
///
pure size_t wcscspn(scope const wchar_t* s1, scope const wchar_t* s2);
///
-pure inout(wchar_t)* wcspbrk(return inout(wchar_t)* s1, scope const wchar_t* s2);
+pure inout(wchar_t)* wcspbrk(return scope inout(wchar_t)* s1, scope const wchar_t* s2);
///
-pure inout(wchar_t)* wcsrchr(return inout(wchar_t)* s, wchar_t c);
+pure inout(wchar_t)* wcsrchr(return scope inout(wchar_t)* s, wchar_t c);
///
pure size_t wcsspn(scope const wchar_t* s1, scope const wchar_t* s2);
///
-pure inout(wchar_t)* wcsstr(return inout(wchar_t)* s1, scope const wchar_t* s2);
+pure inout(wchar_t)* wcsstr(return scope inout(wchar_t)* s1, scope const wchar_t* s2);
///
-wchar_t* wcstok(return wchar_t* s1, scope const wchar_t* s2, wchar_t** ptr);
+wchar_t* wcstok(return scope wchar_t* s1, scope const wchar_t* s2, wchar_t** ptr);
///
pure size_t wcslen(scope const wchar_t* s);
///
-pure inout(wchar_t)* wmemchr(return inout wchar_t* s, wchar_t c, size_t n);
+pure inout(wchar_t)* wmemchr(return scope inout wchar_t* s, wchar_t c, size_t n);
///
pure int wmemcmp(scope const wchar_t* s1, scope const wchar_t* s2, size_t n);
///
-pure wchar_t* wmemcpy(return wchar_t* s1, scope const wchar_t* s2, size_t n);
+pure wchar_t* wmemcpy(return scope wchar_t* s1, scope const wchar_t* s2, size_t n);
///
-pure wchar_t* wmemmove(return wchar_t* s1, scope const wchar_t* s2, size_t n);
+pure wchar_t* wmemmove(return scope wchar_t* s1, scope const wchar_t* s2, size_t n);
///
-pure wchar_t* wmemset(return wchar_t* s, wchar_t c, size_t n);
+pure wchar_t* wmemset(return scope wchar_t* s, wchar_t c, size_t n);
///
size_t wcsftime(wchar_t* s, size_t maxsize, const scope wchar_t* format, const scope tm* timeptr);
@@ -19,6 +19,8 @@ version (CppRuntime_Gcc)
version = GenericBaseException;
version (CppRuntime_Clang)
version = GenericBaseException;
+version (CppRuntime_Sun)
+ version = GenericBaseException;
extern (C++, "std"):
@nogc:
@@ -189,7 +189,7 @@ class Mutex :
if (pthread_mutex_lock(&m_hndl) == 0)
return;
- SyncError syncErr = cast(SyncError) cast(void*) typeid(SyncError).initializer;
+ SyncError syncErr = cast(SyncError) __traits(initSymbol, SyncError).ptr;
syncErr.msg = "Unable to lock mutex.";
throw syncErr;
}
@@ -227,7 +227,7 @@ class Mutex :
if (pthread_mutex_unlock(&m_hndl) == 0)
return;
- SyncError syncErr = cast(SyncError) cast(void*) typeid(SyncError).initializer;
+ SyncError syncErr = cast(SyncError) __traits(initSymbol, SyncError).ptr;
syncErr.msg = "Unable to unlock mutex.";
throw syncErr;
}
@@ -14,4 +14,4 @@ extern (C):
nothrow:
@nogc:
-pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
@@ -222,7 +222,7 @@ enum
*/
ubyte GET_LIBRARY_ORDINAL(uint n_desc) @safe { return ((n_desc) >> 8) & 0xff; }
/// Ditto
-ref ushort SET_LIBRARY_ORDINAL(return scope ref ushort n_desc, uint ordinal) @safe
+ref ushort SET_LIBRARY_ORDINAL(return ref ushort n_desc, uint ordinal) @safe
{
return n_desc = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8));
}
@@ -27,5 +27,5 @@ nothrow:
static if (__DARWIN_C_LEVEL >= __DARWIN_C_FULL)
{
// ^ __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
- pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+ pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
}
@@ -17,6 +17,6 @@ nothrow:
static if (__BSD_VISIBLE)
{
- pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+ pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
}
@@ -17,5 +17,5 @@ nothrow:
static if (__BSD_VISIBLE)
{
- pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+ pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
}
@@ -18,5 +18,5 @@ nothrow:
static if (__USE_GNU)
{
- pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+ pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
}
deleted file mode 100644
@@ -1,745 +0,0 @@
-module core.sys.linux.syscalls;
-
-version (linux):
-extern (C):
-@system:
-nothrow:
-@nogc:
-
-import core.stdc.config : c_long;
-
-version (CoreDdoc)
-{
- /// Linux system call number from Linux's asm/unistd.h
- enum SystemCall : c_long;
-}
-else version (X86_64)
-{
- // https://github.com/torvalds/linux/blob/v4.14/arch/sh/include/uapi/asm/unistd_64.h
- // https://github.com/torvalds/linux/blob/v4.14/arch/x86/entry/syscalls/syscall_64.tbl
- enum SystemCall : c_long
- {
- read = 0,
- write = 1,
- open = 2,
- close = 3,
- stat = 4,
- fstat = 5,
- lstat = 6,
- poll = 7,
- lseek = 8,
- mmap = 9,
- mprotect = 10,
- munmap = 11,
- brk = 12,
- rt_sigaction = 13,
- rt_sigprocmask = 14,
- rt_sigreturn = 15,
- ioctl = 16,
- pread64 = 17,
- pwrite64 = 18,
- readv = 19,
- writev = 20,
- access = 21,
- pipe = 22,
- select = 23,
- sched_yield = 24,
- mremap = 25,
- msync = 26,
- mincore = 27,
- madvise = 28,
- shmget = 29,
- shmat = 30,
- shmctl = 31,
- dup = 32,
- dup2 = 33,
- pause = 34,
- nanosleep = 35,
- getitimer = 36,
- alarm = 37,
- setitimer = 38,
- getpid = 39,
- sendfile = 40,
- socket = 41,
- connect = 42,
- accept = 43,
- sendto = 44,
- recvfrom = 45,
- sendmsg = 46,
- recvmsg = 47,
- shutdown = 48,
- bind = 49,
- listen = 50,
- getsockname = 51,
- getpeername = 52,
- socketpair = 53,
- setsockopt = 54,
- getsockopt = 55,
- clone = 56,
- fork = 57,
- vfork = 58,
- execve = 59,
- exit = 60,
- wait4 = 61,
- kill = 62,
- uname = 63,
- semget = 64,
- semop = 65,
- semctl = 66,
- shmdt = 67,
- msgget = 68,
- msgsnd = 69,
- msgrcv = 70,
- msgctl = 71,
- fcntl = 72,
- flock = 73,
- fsync = 74,
- fdatasync = 75,
- truncate = 76,
- ftruncate = 77,
- getdents = 78,
- getcwd = 79,
- chdir = 80,
- fchdir = 81,
- rename = 82,
- mkdir = 83,
- rmdir = 84,
- creat = 85,
- link = 86,
- unlink = 87,
- symlink = 88,
- readlink = 89,
- chmod = 90,
- fchmod = 91,
- chown = 92,
- fchown = 93,
- lchown = 94,
- umask = 95,
- gettimeofday = 96,
- getrlimit = 97,
- getrusage = 98,
- sysinfo = 99,
- times = 100,
- ptrace = 101,
- getuid = 102,
- syslog = 103,
- getgid = 104,
- setuid = 105,
- setgid = 106,
- geteuid = 107,
- getegid = 108,
- setpgid = 109,
- getppid = 110,
- getpgrp = 111,
- setsid = 112,
- setreuid = 113,
- setregid = 114,
- getgroups = 115,
- setgroups = 116,
- setresuid = 117,
- getresuid = 118,
- setresgid = 119,
- getresgid = 120,
- getpgid = 121,
- setfsuid = 122,
- setfsgid = 123,
- getsid = 124,
- capget = 125,
- capset = 126,
- rt_sigpending = 127,
- rt_sigtimedwait = 128,
- rt_sigqueueinfo = 129,
- rt_sigsuspend = 130,
- sigaltstack = 131,
- utime = 132,
- mknod = 133,
- uselib = 134,
- personality = 135,
- ustat = 136,
- statfs = 137,
- fstatfs = 138,
- sysfs = 139,
- getpriority = 140,
- setpriority = 141,
- sched_setparam = 142,
- sched_getparam = 143,
- sched_setscheduler = 144,
- sched_getscheduler = 145,
- sched_get_priority_max = 146,
- sched_get_priority_min = 147,
- sched_rr_get_interval = 148,
- mlock = 149,
- munlock = 150,
- mlockall = 151,
- munlockall = 152,
- vhangup = 153,
- modify_ldt = 154,
- pivot_root = 155,
- _sysctl = 156,
- prctl = 157,
- arch_prctl = 158,
- adjtimex = 159,
- setrlimit = 160,
- chroot = 161,
- sync = 162,
- acct = 163,
- settimeofday = 164,
- mount = 165,
- umount2 = 166,
- swapon = 167,
- swapoff = 168,
- reboot = 169,
- sethostname = 170,
- setdomainname = 171,
- iopl = 172,
- ioperm = 173,
- create_module = 174,
- init_module = 175,
- delete_module = 176,
- get_kernel_syms = 177,
- query_module = 178,
- quotactl = 179,
- nfsservctl = 180,
- getpmsg = 181,
- putpmsg = 182,
- afs_syscall = 183,
- tuxcall = 184,
- security = 185,
- gettid = 186,
- readahead = 187,
- setxattr = 188,
- lsetxattr = 189,
- fsetxattr = 190,
- getxattr = 191,
- lgetxattr = 192,
- fgetxattr = 193,
- listxattr = 194,
- llistxattr = 195,
- flistxattr = 196,
- removexattr = 197,
- lremovexattr = 198,
- fremovexattr = 199,
- tkill = 200,
- time = 201,
- futex = 202,
- sched_setaffinity = 203,
- sched_getaffinity = 204,
- set_thread_area = 205,
- io_setup = 206,
- io_destroy = 207,
- io_getevents = 208,
- io_submit = 209,
- io_cancel = 210,
- get_thread_area = 211,
- lookup_dcookie = 212,
- epoll_create = 213,
- epoll_ctl_old = 214,
- epoll_wait_old = 215,
- remap_file_pages = 216,
- getdents64 = 217,
- set_tid_address = 218,
- restart_syscall = 219,
- semtimedop = 220,
- fadvise64 = 221,
- timer_create = 222,
- timer_settime = 223,
- timer_gettime = 224,
- timer_getoverrun = 225,
- timer_delete = 226,
- clock_settime = 227,
- clock_gettime = 228,
- clock_getres = 229,
- clock_nanosleep = 230,
- exit_group = 231,
- epoll_wait = 232,
- epoll_ctl = 233,
- tgkill = 234,
- utimes = 235,
- vserver = 236,
- mbind = 237,
- set_mempolicy = 238,
- get_mempolicy = 239,
- mq_open = 240,
- mq_unlink = 241,
- mq_timedsend = 242,
- mq_timedreceive = 243,
- mq_notify = 244,
- mq_getsetattr = 245,
- kexec_load = 246,
- waitid = 247,
- add_key = 248,
- request_key = 249,
- keyctl = 250,
- ioprio_set = 251,
- ioprio_get = 252,
- inotify_init = 253,
- inotify_add_watch = 254,
- inotify_rm_watch = 255,
- migrate_pages = 256,
- openat = 257,
- mkdirat = 258,
- mknodat = 259,
- fchownat = 260,
- futimesat = 261,
- newfstatat = 262,
- unlinkat = 263,
- renameat = 264,
- linkat = 265,
- symlinkat = 266,
- readlinkat = 267,
- fchmodat = 268,
- faccessat = 269,
- pselect6 = 270,
- ppoll = 271,
- unshare = 272,
- set_robust_list = 273,
- get_robust_list = 274,
- splice = 275,
- tee = 276,
- sync_file_range = 277,
- vmsplice = 278,
- move_pages = 279,
- utimensat = 280,
- epoll_pwait = 281,
- signalfd = 282,
- timerfd_create = 283,
- eventfd = 284,
- fallocate = 285,
- timerfd_settime = 286,
- timerfd_gettime = 287,
- accept4 = 288,
- signalfd4 = 289,
- eventfd2 = 290,
- epoll_create1 = 291,
- dup3 = 292,
- pipe2 = 293,
- inotify_init1 = 294,
- preadv = 295,
- pwritev = 296,
- rt_tgsigqueueinfo = 297,
- perf_event_open = 298,
- recvmmsg = 299,
- fanotify_init = 300,
- fanotify_mark = 301,
- prlimit64 = 302,
- name_to_handle_at = 303,
- open_by_handle_at = 304,
- clock_adjtime = 305,
- syncfs = 306,
- sendmmsg = 307,
- setns = 308,
- getcpu = 309,
- process_vm_readv = 310,
- process_vm_writev = 311,
- kcmp = 312,
- finit_module = 313,
- sched_setattr = 314,
- sched_getattr = 315,
- renameat2 = 316,
- seccomp = 317,
- getrandom = 318,
- memfd_create = 319,
- kexec_file_load = 320,
- bpf = 321,
- execveat = 322,
- userfaultfd = 323,
- membarrier = 324,
- mlock2 = 325,
- copy_file_range = 326,
- preadv2 = 327,
- pwritev2 = 328,
- pkey_mprotect = 329,
- pkey_alloc = 330,
- pkey_free = 331,
- statx = 332,
- }
-}
-else version (X86)
-{
- // https://github.com/torvalds/linux/blob/master/arch/x86/entry/syscalls/syscall_32.tbl
- // https://github.com/torvalds/linux/blob/v4.14/arch/sh/include/uapi/asm/unistd_32.h
- enum SystemCall : c_long
- {
- restart_syscall = 0,
- exit = 1,
- fork = 2,
- read = 3,
- write = 4,
- open = 5,
- close = 6,
- waitpid = 7,
- creat = 8,
- link = 9,
- unlink = 10,
- execve = 11,
- chdir = 12,
- time = 13,
- mknod = 14,
- chmod = 15,
- lchown = 16,
- break_ = 17,
- oldstat = 18,
- lseek = 19,
- getpid = 20,
- mount = 21,
- umount = 22,
- setuid = 23,
- getuid = 24,
- stime = 25,
- ptrace = 26,
- alarm = 27,
- oldfstat = 28,
- pause = 29,
- utime = 30,
- stty = 31,
- gtty = 32,
- access = 33,
- nice = 34,
- ftime = 35,
- sync = 36,
- kill = 37,
- rename = 38,
- mkdir = 39,
- rmdir = 40,
- dup = 41,
- pipe = 42,
- times = 43,
- prof = 44,
- brk = 45,
- setgid = 46,
- getgid = 47,
- signal = 48,
- geteuid = 49,
- getegid = 50,
- acct = 51,
- umount2 = 52,
- lock = 53,
- ioctl = 54,
- fcntl = 55,
- mpx = 56,
- setpgid = 57,
- ulimit = 58,
- oldolduname = 59,
- umask = 60,
- chroot = 61,
- ustat = 62,
- dup2 = 63,
- getppid = 64,
- getpgrp = 65,
- setsid = 66,
- sigaction = 67,
- sgetmask = 68,
- ssetmask = 69,
- setreuid = 70,
- setregid = 71,
- sigsuspend = 72,
- sigpending = 73,
- sethostname = 74,
- setrlimit = 75,
- getrlimit = 76,
- getrusage = 77,
- gettimeofday = 78,
- settimeofday = 79,
- getgroups = 80,
- setgroups = 81,
- select = 82,
- symlink = 83,
- oldlstat = 84,
- readlink = 85,
- uselib = 86,
- swapon = 87,
- reboot = 88,
- readdir = 89,
- mmap = 90,
- munmap = 91,
- truncate = 92,
- ftruncate = 93,
- fchmod = 94,
- fchown = 95,
- getpriority = 96,
- setpriority = 97,
- profil = 98,
- statfs = 99,
- fstatfs = 100,
- ioperm = 101,
- socketcall = 102,
- syslog = 103,
- setitimer = 104,
- getitimer = 105,
- stat = 106,
- lstat = 107,
- fstat = 108,
- olduname = 109,
- iopl = 110,
- vhangup = 111,
- idle = 112,
- vm86old = 113,
- wait4 = 114,
- swapoff = 115,
- sysinfo = 116,
- ipc = 117,
- fsync = 118,
- sigreturn = 119,
- clone = 120,
- setdomainname = 121,
- uname = 122,
- modify_ldt = 123,
- adjtimex = 124,
- mprotect = 125,
- sigprocmask = 126,
- create_module = 127,
- init_module = 128,
- delete_module = 129,
- get_kernel_syms = 130,
- quotactl = 131,
- getpgid = 132,
- fchdir = 133,
- bdflush = 134,
- sysfs = 135,
- personality = 136,
- afs_syscall = 137,
- setfsuid = 138,
- setfsgid = 139,
- _llseek = 140,
- getdents = 141,
- _newselect = 142,
- flock = 143,
- msync = 144,
- readv = 145,
- writev = 146,
- getsid = 147,
- fdatasync = 148,
- _sysctl = 149,
- mlock = 150,
- munlock = 151,
- mlockall = 152,
- munlockall = 153,
- sched_setparam = 154,
- sched_getparam = 155,
- sched_setscheduler = 156,
- sched_getscheduler = 157,
- sched_yield = 158,
- sched_get_priority_max = 159,
- sched_get_priority_min = 160,
- sched_rr_get_interval = 161,
- nanosleep = 162,
- mremap = 163,
- setresuid = 164,
- getresuid = 165,
- vm86 = 166,
- query_module = 167,
- poll = 168,
- nfsservctl = 169,
- setresgid = 170,
- getresgid = 171,
- prctl = 172,
- rt_sigreturn = 173,
- rt_sigaction = 174,
- rt_sigprocmask = 175,
- rt_sigpending = 176,
- rt_sigtimedwait = 177,
- rt_sigqueueinfo = 178,
- rt_sigsuspend = 179,
- pread64 = 180,
- pwrite64 = 181,
- chown = 182,
- getcwd = 183,
- capget = 184,
- capset = 185,
- sigaltstack = 186,
- sendfile = 187,
- getpmsg = 188,
- putpmsg = 189,
- vfork = 190,
- ugetrlimit = 191,
- mmap2 = 192,
- truncate64 = 193,
- ftruncate64 = 194,
- stat64 = 195,
- lstat64 = 196,
- fstat64 = 197,
- lchown32 = 198,
- getuid32 = 199,
- getgid32 = 200,
- geteuid32 = 201,
- getegid32 = 202,
- setreuid32 = 203,
- setregid32 = 204,
- getgroups32 = 205,
- setgroups32 = 206,
- fchown32 = 207,
- setresuid32 = 208,
- getresuid32 = 209,
- setresgid32 = 210,
- getresgid32 = 211,
- chown32 = 212,
- setuid32 = 213,
- setgid32 = 214,
- setfsuid32 = 215,
- setfsgid32 = 216,
- pivot_root = 217,
- mincore = 218,
- madvise = 219,
- getdents64 = 220,
- fcntl64 = 221,
- gettid = 224,
- readahead = 225,
- setxattr = 226,
- lsetxattr = 227,
- fsetxattr = 228,
- getxattr = 229,
- lgetxattr = 230,
- fgetxattr = 231,
- listxattr = 232,
- llistxattr = 233,
- flistxattr = 234,
- removexattr = 235,
- lremovexattr = 236,
- fremovexattr = 237,
- tkill = 238,
- sendfile64 = 239,
- futex = 240,
- sched_setaffinity = 241,
- sched_getaffinity = 242,
- set_thread_area = 243,
- get_thread_area = 244,
- io_setup = 245,
- io_destroy = 246,
- io_getevents = 247,
- io_submit = 248,
- io_cancel = 249,
- fadvise64 = 250,
- exit_group = 252,
- lookup_dcookie = 253,
- epoll_create = 254,
- epoll_ctl = 255,
- epoll_wait = 256,
- remap_file_pages = 257,
- set_tid_address = 258,
- timer_create = 259,
- timer_settime = 260,
- timer_gettime = 261,
- timer_getoverrun = 262,
- timer_delete = 263,
- clock_settime = 264,
- clock_gettime = 265,
- clock_getres = 266,
- clock_nanosleep = 267,
- statfs64 = 268,
- fstatfs64 = 269,
- tgkill = 270,
- utimes = 271,
- fadvise64_64 = 272,
- vserver = 273,
- mbind = 274,
- get_mempolicy = 275,
- set_mempolicy = 276,
- mq_open = 277,
- mq_unlink = 278,
- mq_timedsend = 279,
- mq_timedreceive = 280,
- mq_notify = 281,
- mq_getsetattr = 282,
- kexec_load = 283,
- waitid = 284,
- add_key = 286,
- request_key = 287,
- keyctl = 288,
- ioprio_set = 289,
- ioprio_get = 290,
- inotify_init = 291,
- inotify_add_watch = 292,
- inotify_rm_watch = 293,
- migrate_pages = 294,
- openat = 295,
- mkdirat = 296,
- mknodat = 297,
- fchownat = 298,
- futimesat = 299,
- fstatat64 = 300,
- unlinkat = 301,
- renameat = 302,
- linkat = 303,
- symlinkat = 304,
- readlinkat = 305,
- fchmodat = 306,
- faccessat = 307,
- pselect6 = 308,
- ppoll = 309,
- unshare = 310,
- set_robust_list = 311,
- get_robust_list = 312,
- splice = 313,
- sync_file_range = 314,
- tee = 315,
- vmsplice = 316,
- move_pages = 317,
- getcpu = 318,
- epoll_pwait = 319,
- utimensat = 320,
- signalfd = 321,
- timerfd_create = 322,
- eventfd = 323,
- fallocate = 324,
- timerfd_settime = 325,
- timerfd_gettime = 326,
- signalfd4 = 327,
- eventfd2 = 328,
- epoll_create1 = 329,
- dup3 = 330,
- pipe2 = 331,
- inotify_init1 = 332,
- preadv = 333,
- pwritev = 334,
- rt_tgsigqueueinfo = 335,
- perf_event_open = 336,
- recvmmsg = 337,
- fanotify_init = 338,
- fanotify_mark = 339,
- prlimit64 = 340,
- name_to_handle_at = 341,
- open_by_handle_at = 342,
- clock_adjtime = 343,
- syncfs = 344,
- sendmmsg = 345,
- setns = 346,
- process_vm_readv = 347,
- process_vm_writev = 348,
- kcmp = 349,
- finit_module = 350,
- sched_setattr = 351,
- sched_getattr = 352,
- renameat2 = 353,
- seccomp = 354,
- getrandom = 355,
- memfd_create = 356,
- bpf = 357,
- execveat = 358,
- socket = 359,
- socketpair = 360,
- bind = 361,
- connect = 362,
- listen = 363,
- accept4 = 364,
- getsockopt = 365,
- setsockopt = 366,
- getsockname = 367,
- getpeername = 368,
- sendto = 369,
- sendmsg = 370,
- recvfrom = 371,
- recvmsg = 372,
- shutdown = 373,
- userfaultfd = 374,
- membarrier = 375,
- mlock2 = 376,
- copy_file_range = 377,
- preadv2 = 378,
- pwritev2 = 379,
- pkey_mprotect = 380,
- pkey_alloc = 381,
- pkey_free = 382,
- statx = 383,
- arch_prctl = 384,
- }
-}
@@ -1,20 +1,16 @@
module core.sys.linux.unistd;
+public import core.sys.posix.unistd;
+
version (linux):
-extern (C):
+extern(C):
nothrow:
@system:
-@nogc:
-
-public import core.sys.posix.unistd;
-public import core.sys.linux.syscalls : SystemCall;
-import core.stdc.config : c_long;
// Additional seek constants for sparse file handling
// from Linux's unistd.h, stdio.h, and linux/fs.h
// (see http://man7.org/linux/man-pages/man2/lseek.2.html)
-enum
-{
+enum {
/// Offset is relative to the next location containing data
SEEK_DATA = 3,
/// Offset is relative to the next hole (or EOF if file is not sparse)
@@ -26,17 +22,3 @@ char* getpass(const(char)* prompt);
// Exit all threads in a process
void exit_group(int status);
-
-/**
-Invoke system call specified by number, passing it the remaining arguments.
-This is completely system-dependent, and not often useful.
-
-In Unix, `syscall' sets `errno' for all errors and most calls return -1
-for errors; in many systems you cannot pass arguments or get return
-values for all system calls (`pipe', `fork', and `getppid' typically
-among them).
-
-In Mach, all system calls take normal arguments and always return an
-error code (zero for success).
-*/
-c_long syscall(SystemCall number, ...) @nogc nothrow;
@@ -17,5 +17,5 @@ nothrow:
static if (_NETBSD_SOURCE)
{
- pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+ pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
}
@@ -18,7 +18,7 @@ nothrow:
static if (__BSD_VISIBLE)
{
void explicit_bzero(void*, size_t);
- pure void* memmem(return const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
+ pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
void* memrchr(scope const void*, int, size_t);
size_t strlcat(char*, scope const char*, size_t);
size_t strlcpy(char*, scope const char*, size_t);
@@ -513,15 +513,21 @@ else version (DragonFlyBSD)
}
else version (Solaris)
{
+ //SIGABRT (defined in core.stdc.signal)
enum SIGALRM = 14;
enum SIGBUS = 10;
enum SIGCHLD = 18;
enum SIGCONT = 25;
+ //SIGFPE (defined in core.stdc.signal)
enum SIGHUP = 1;
+ //SIGILL (defined in core.stdc.signal)
+ //SIGINT (defined in core.stdc.signal)
enum SIGKILL = 9;
enum SIGPIPE = 13;
enum SIGQUIT = 3;
+ //SIGSEGV (defined in core.stdc.signal)
enum SIGSTOP = 23;
+ //SIGTERM (defined in core.stdc.signal)
enum SIGTSTP = 24;
enum SIGTTIN = 26;
enum SIGTTOU = 27;
@@ -1339,6 +1345,10 @@ else version (Solaris)
uint[4] __bits;
}
+ enum SIG_BLOCK = 1;
+ enum SIG_UNBLOCK = 2;
+ enum SIG_SETMASK = 3;
+
struct siginfo_t
{
int si_signo;
@@ -1427,6 +1437,18 @@ else version (Solaris)
___data __data;
}
+ enum SI_NOINFO = 32767;
+ enum SI_DTRACE = 2050;
+ enum SI_RCTL = 2049;
+ enum SI_USER = 0;
+ enum SI_LWP = -1;
+ enum SI_QUEUE = -2;
+ enum SI_TIMER = -3;
+ enum SI_ASYNCIO = -4;
+ enum SI_MESGQ = -5;
+
+ enum SIGIO = SIGPOLL;
+
int kill(pid_t, int);
int sigaction(int, const scope sigaction_t*, sigaction_t*);
int sigaddset(sigset_t*, int);
@@ -2833,9 +2855,9 @@ else version (Solaris)
enum SIGPROF = 29;
enum SIGSYS = 12;
enum SIGTRAP = 5;
- enum SIGVTALRM = 31;
+ enum SIGVTALRM = 28;
enum SIGXCPU = 30;
- enum SIGXFSZ = 25;
+ enum SIGXFSZ = 31;
enum
{
@@ -31,11 +31,11 @@ public import core.sys.posix.locale : locale_t;
public import core.stdc.string;
/// Copy string until character found
-void* memccpy(return void* dst, scope const void* src, int c, size_t n) pure;
+void* memccpy(return scope void* dst, scope const void* src, int c, size_t n) pure;
/// Copy string (including terminating '\0')
-char* stpcpy(return char* dst, scope const char* src) pure;
+char* stpcpy(return scope char* dst, scope const char* src) pure;
/// Ditto
-char* stpncpy(return char* dst, const char* src, size_t len) pure;
+char* stpncpy(return scope char* dst, const char* src, size_t len) pure;
/// Compare strings according to current collation
int strcoll_l(scope const char* s1, scope const char* s2, locale_t locale);
///
@@ -47,6 +47,6 @@ size_t strnlen(scope const char* str, size_t maxlen) pure;
/// System signal messages
const(char)* strsignal(int);
/// Isolate sequential tokens in a null-terminated string
-char* strtok_r(return char* str, scope const char* sep, char** context) pure;
+char* strtok_r(return scope char* str, scope const char* sep, char** context) pure;
/// Transform a string under locale
size_t strxfrm_l(char* s1, scope const char* s2, size_t n, locale_t locale);
@@ -217,7 +217,7 @@ version (CRuntime_Glibc)
}
else
{
- extern (D) inout(ubyte)* CMSG_DATA( return inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
+ extern (D) inout(ubyte)* CMSG_DATA( return scope inout(cmsghdr)* cmsg ) pure nothrow @nogc { return cast(ubyte*)( cmsg + 1 ); }
}
private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc;
@@ -393,7 +393,7 @@ enum SHF_LINK_ORDER = 0x80;
enum SHF_OS_NONCONFORMING = 0x100;
enum SHF_GROUP = 0x200;
enum SHF_TLS = 0x400;
-
+enum SHF_COMPRESSED = 0x800;
enum SHF_MASKOS = 0x0ff00000;
enum SHF_MASKPROC = 0xf0000000;
@@ -656,3 +656,6 @@ enum NT_ZONENAME = 21;
enum NT_FDINFO = 22;
enum NT_SPYMASTER = 23;
enum NT_NUM = 23;
+
+enum SHF_ORDERED = 0x40000000;
+enum SHF_EXCLUDE = 0x80000000;
@@ -52,9 +52,6 @@ enum R_386_NUM = 39;
enum ELF_386_MAXPGSZ = 0x10000;
-enum SHF_ORDERED = 0x40000000;
-enum SHF_EXCLUDE = 0x80000000;
-
enum SHN_BEFORE = 0xff00;
enum SHN_AFTER = 0xff01;
@@ -118,9 +118,6 @@ enum ELF_SPARCV9_MAXPGSZ = 0x100000;
enum SHT_SPARC_GOTDATA = 0x70000000;
-enum SHF_ORDERED = 0x40000000;
-enum SHF_EXCLUDE = 0x80000000;
-
enum SHN_BEFORE = 0xff00;
enum SHN_AFTER = 0xff01;
@@ -39,7 +39,8 @@ extern(Windows)
alias BOOL function(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, IMAGEHLP_SYMBOLA64 *Symbol) SymGetSymFromAddr64Func;
alias DWORD function(PCSTR DecoratedName, PSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc;
alias DWORD64 function(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) SymLoadModule64Func;
- alias BOOL function(HANDLE HProcess, PTSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc;
+ alias BOOL function(HANDLE hProcess, PSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc;
+ alias BOOL function(HANDLE hProcess, PCSTR SearchPath) SymSetSearchPathFunc;
alias BOOL function(HANDLE hProcess, DWORD64 Address) SymUnloadModule64Func;
alias BOOL function(HANDLE hProcess, ULONG ActionCode, ulong CallbackContext, ulong UserContext) PSYMBOL_REGISTERED_CALLBACK64;
alias BOOL function(HANDLE hProcess, PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, ulong UserContext) SymRegisterCallback64Func;
@@ -61,6 +62,7 @@ struct DbgHelp
UnDecorateSymbolNameFunc UnDecorateSymbolName;
SymLoadModule64Func SymLoadModule64;
SymGetSearchPathFunc SymGetSearchPath;
+ SymSetSearchPathFunc SymSetSearchPath;
SymUnloadModule64Func SymUnloadModule64;
SymRegisterCallback64Func SymRegisterCallback64;
ImagehlpApiVersionFunc ImagehlpApiVersion;
@@ -84,6 +86,7 @@ struct DbgHelp
sm_inst.UnDecorateSymbolName = cast(UnDecorateSymbolNameFunc) GetProcAddress(sm_hndl,"UnDecorateSymbolName");
sm_inst.SymLoadModule64 = cast(SymLoadModule64Func) GetProcAddress(sm_hndl,"SymLoadModule64");
sm_inst.SymGetSearchPath = cast(SymGetSearchPathFunc) GetProcAddress(sm_hndl,"SymGetSearchPath");
+ sm_inst.SymSetSearchPath = cast(SymSetSearchPathFunc) GetProcAddress(sm_hndl,"SymSetSearchPath");
sm_inst.SymUnloadModule64 = cast(SymUnloadModule64Func) GetProcAddress(sm_hndl,"SymUnloadModule64");
sm_inst.SymRegisterCallback64 = cast(SymRegisterCallback64Func) GetProcAddress(sm_hndl, "SymRegisterCallback64");
sm_inst.ImagehlpApiVersion = cast(ImagehlpApiVersionFunc) GetProcAddress(sm_hndl, "ImagehlpApiVersion");
@@ -91,7 +94,8 @@ struct DbgHelp
sm_inst.SymSetOptions && sm_inst.SymFunctionTableAccess64 && sm_inst.SymGetLineFromAddr64 &&
sm_inst.SymGetModuleBase64 && sm_inst.SymGetModuleInfo64 && sm_inst.SymGetSymFromAddr64 &&
sm_inst.UnDecorateSymbolName && sm_inst.SymLoadModule64 && sm_inst.SymGetSearchPath &&
- sm_inst.SymUnloadModule64 && sm_inst.SymRegisterCallback64 && sm_inst.ImagehlpApiVersion);
+ sm_inst.SymSetSearchPath && sm_inst.SymUnloadModule64 && sm_inst.SymRegisterCallback64 &&
+ sm_inst.ImagehlpApiVersion);
return &sm_inst;
}
@@ -719,7 +719,7 @@ class Thread : ThreadBase
// the effective maximum.
// maxupri
- result.PRIORITY_MIN = -clinfo[0];
+ result.PRIORITY_MIN = -cast(int)(clinfo[0]);
// by definition
result.PRIORITY_DEFAULT = 0;
}
@@ -2196,8 +2196,7 @@ extern (C) void thread_init() @nogc
status = sem_init( &suspendCount, 0, 0 );
assert( status == 0 );
}
- if (typeid(Thread).initializer.ptr)
- _mainThreadStore[] = typeid(Thread).initializer[];
+ _mainThreadStore[] = __traits(initSymbol, Thread)[];
Thread.sm_main = attachThread((cast(Thread)_mainThreadStore.ptr).__ctor());
}
@@ -771,10 +771,7 @@ package void thread_term_tpl(ThreadT, MainThreadStore)(ref MainThreadStore _main
// destruct manually as object.destroy is not @nogc
(cast(ThreadT) cast(void*) ThreadBase.sm_main).__dtor();
_d_monitordelete_nogc(ThreadBase.sm_main);
- if (typeid(ThreadT).initializer.ptr)
- _mainThreadStore[] = typeid(ThreadT).initializer[];
- else
- (cast(ubyte[])_mainThreadStore)[] = 0;
+ _mainThreadStore[] = __traits(initSymbol, ThreadT)[];
ThreadBase.sm_main = null;
assert(ThreadBase.sm_tbeg && ThreadBase.sm_tlen == 1);
@@ -3485,7 +3485,7 @@ enum immutable(void)* rtinfoHasPointers = cast(void*)1;
// Helper functions
-private inout(TypeInfo) getElement(return inout TypeInfo value) @trusted pure nothrow
+private inout(TypeInfo) getElement(return scope inout TypeInfo value) @trusted pure nothrow
{
TypeInfo element = cast() value;
for (;;)
@@ -4215,8 +4215,8 @@ void destroy(bool initialize = true, T)(T obj) if (is(T == class))
static if (initialize)
{
- enum classSize = __traits(classInstanceSize, T);
- (cast(void*)obj)[0 .. classSize] = typeid(T).initializer[];
+ const initializer = __traits(initSymbol, T);
+ (cast(void*)obj)[0 .. initializer.length] = initializer[];
}
}
else
@@ -4651,6 +4651,8 @@ public import core.internal.array.construction : _d_arrayctor;
public import core.internal.array.construction : _d_arraysetctor;
public import core.internal.array.capacity: _d_arraysetlengthTImpl;
+public import core.lifetime : _d_delstruct;
+
public import core.internal.dassert: _d_assert_fail;
public import core.internal.destruction: __ArrayDtor;
@@ -287,7 +287,7 @@ TypeInfo_Struct fakeEntryTI(ref Impl aa, const TypeInfo keyti, const TypeInfo va
void* p = GC.malloc(sizeti + (2 + rtisize) * (void*).sizeof);
import core.stdc.string : memcpy;
- memcpy(p, typeid(TypeInfo_Struct).initializer().ptr, sizeti);
+ memcpy(p, __traits(initSymbol, TypeInfo_Struct).ptr, sizeti);
auto ti = cast(TypeInfo_Struct) p;
auto extra = cast(TypeInfo*)(p + sizeti);
@@ -853,7 +853,7 @@ struct Range
extern (C) pure nothrow @nogc @safe
{
- Range _aaRange(return AA aa)
+ Range _aaRange(return scope AA aa)
{
if (!aa)
return Range();
@@ -36,7 +36,7 @@ extern (D) private bool areClassInfosEqual(scope const ClassInfo a, scope const
* If it is null, return null.
* Else, undefined crash
*/
-Object _d_toObject(return void* p)
+Object _d_toObject(return scope void* p)
{
if (!p)
return null;
@@ -101,6 +101,9 @@ string rt_cmdlineOption(string opt, scope rt_configCallBack dg) @nogc nothrow
{
foreach (a; rt_args)
{
+ if (a == "--")
+ break;
+
if (a.length >= opt.length + 7 && a[0..6] == "--DRT-" &&
a[6 .. 6 + opt.length] == opt && a[6 + opt.length] == '=')
{
@@ -181,7 +181,7 @@ extern (C) void _d_delstruct(void** p, TypeInfo_Struct inf) @weak
}
// strip const/immutable/shared/inout from type info
-inout(TypeInfo) unqualify(return inout(TypeInfo) cti) pure nothrow @nogc
+inout(TypeInfo) unqualify(return scope inout(TypeInfo) cti) pure nothrow @nogc
{
TypeInfo ti = cast() cti;
while (ti)
@@ -381,7 +381,7 @@ size_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure nothrow
/**
get the start of the array for the given block
*/
-void *__arrayStart(return BlkInfo info) nothrow pure
+void *__arrayStart(return scope BlkInfo info) nothrow pure
{
return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0);
}
@@ -264,7 +264,7 @@ struct Monitor
private:
-@property ref shared(Monitor*) monitor(return Object h) pure nothrow @nogc
+@property ref shared(Monitor*) monitor(return scope Object h) pure nothrow @nogc
{
return *cast(shared Monitor**)&h.__monitor;
}
@@ -1,4 +1,4 @@
-574bf883b790340fb753d6542ec48a3ba3e6cb82
+12329adb67fb43891d6e4e543e7257bc34db0aa7
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
@@ -3595,7 +3595,6 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR)
assert(res.equal("cba"));
}
-
/// Ditto
auto joiner(RoR)(RoR r)
if (isInputRange!RoR && isInputRange!(ElementType!RoR))
@@ -3621,14 +3620,32 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
_currentBack = typeof(_currentBack).init;
}
+ void replaceCurrent(typeof(_current) current) @trusted
+ {
+ import core.lifetime : move;
+
+ current.move(_current);
+ }
+
+ static if (isBidirectional)
+ {
+ void replaceCurrentBack(typeof(_currentBack) currentBack) @trusted
+ {
+ import core.lifetime : move;
+
+ currentBack.move(_currentBack);
+ }
+ }
+
public:
this(RoR r)
{
_items = r;
+ // field _current must be initialized in constructor, because it is nested struct
+ _current = typeof(_current).init;
static if (isBidirectional && hasNested!Result)
_currentBack = typeof(_currentBack).init;
- // field _current must be initialized in constructor, because it is nested struct
mixin(popFrontEmptyElements);
static if (isBidirectional)
mixin(popBackEmptyElements);
@@ -3673,13 +3690,13 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
// consumed when a .save'd copy of ourselves is iterated over. So
// we need to .save each subrange we traverse.
static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))
- _current = _items.front.save;
+ replaceCurrent(_items.front.save);
else
- _current = _items.front;
+ replaceCurrent(_items.front);
}
else
{
- _current = typeof(_current).init;
+ replaceCurrent(typeof(_current).init);
}
};
@@ -3696,9 +3713,9 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
static if (isBidirectional)
{
static if (is(typeof(null) : typeof(_currentBack)))
- r._currentBack = _currentBack is null ? null : _currentBack.save;
+ r.replaceCurrentBack(_currentBack is null ? null : _currentBack.save);
else
- r._currentBack = _currentBack.save;
+ r.replaceCurrentBack(_currentBack.save);
r.reachedFinalElement = reachedFinalElement;
}
return r;
@@ -3784,22 +3801,22 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
static if (isForwardRange!RoR && isForwardRange!(ElementType!RoR))
{
if (reachedFinalElement)
- _current = _items.back.save;
+ replaceCurrent(_items.back.save);
else
- _currentBack = _items.back.save;
+ replaceCurrentBack(_items.back.save);
}
else
{
if (reachedFinalElement)
- _current = _items.back;
+ replaceCurrent(_items.back);
else
- _currentBack = _items.back;
+ replaceCurrentBack(_items.back);
}
}
else
{
- _current = typeof(_current).init;
- _currentBack = typeof(_currentBack).init;
+ replaceCurrent(typeof(_current).init);
+ replaceCurrentBack(typeof(_currentBack).init);
}
};
@@ -4232,6 +4249,15 @@ if (isInputRange!RoR && isInputRange!(ElementType!RoR))
assert([[0]].joiner.save.back == 0);
}
+// https://issues.dlang.org/show_bug.cgi?id=22561
+@safe pure unittest
+{
+ import std.range : only;
+
+ static immutable struct S { int[] array; }
+ assert([only(S(null))].joiner.front == S(null));
+}
+
/++
Implements the homonym function (also known as `accumulate`, $(D
compress), `inject`, or `foldl`) present in various programming
@@ -886,31 +886,13 @@ if (isInputRange!Range && hasLvalueElements!Range && hasAssignableElements!Range
static if (hasElaborateAssign!T)
{
import std.algorithm.internal : addressOf;
- //Elaborate opAssign. Must go the memcpy road.
- //We avoid calling emplace here, because our goal is to initialize to
- //the static state of T.init,
- //So we want to avoid any un-necassarilly CC'ing of T.init
+ //Elaborate opAssign. Must go the memcpy/memset road.
static if (!__traits(isZeroInit, T))
{
- auto p = typeid(T).initializer();
for ( ; !range.empty ; range.popFront() )
{
- static if (__traits(isStaticArray, T))
- {
- // static array initializer only contains initialization
- // for one element of the static array.
- auto elemp = cast(void *) addressOf(range.front);
- auto endp = elemp + T.sizeof;
- while (elemp < endp)
- {
- memcpy(elemp, p.ptr, p.length);
- elemp += p.length;
- }
- }
- else
- {
- memcpy(addressOf(range.front), p.ptr, T.sizeof);
- }
+ import core.internal.lifetime : emplaceInitializer;
+ emplaceInitializer(range.front);
}
}
else
@@ -1456,10 +1438,7 @@ private void moveEmplaceImpl(T)(ref scope T target, ref return scope T source)
static if (__traits(isZeroInit, T))
() @trusted { memset(&source, 0, sz); }();
else
- {
- auto init = typeid(T).initializer();
- () @trusted { memcpy(&source, init.ptr, sz); }();
- }
+ () @trusted { memcpy(&source, __traits(initSymbol, T).ptr, sz); }();
}
}
else static if (isStaticArray!T)
@@ -3121,14 +3121,14 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R &&
else
static assert(false, "`transform` returns an unsortable qualified type: " ~ TB.stringof);
- static trustedMalloc(size_t len) @trusted
+ static trustedMalloc()(size_t len) @trusted
{
import core.checkedint : mulu;
- import core.stdc.stdlib : malloc;
+ import core.memory : pureMalloc;
bool overflow;
const nbytes = mulu(len, T.sizeof, overflow);
if (overflow) assert(false, "multiplication overflowed");
- T[] result = (cast(T*) malloc(nbytes))[0 .. len];
+ T[] result = (cast(T*) pureMalloc(nbytes))[0 .. len];
static if (hasIndirections!T)
{
import core.memory : GC;
@@ -3145,15 +3145,15 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R &&
{
foreach (i; 0 .. length) collectException(destroy(xform1[i]));
}
- static void trustedFree(T[] p) @trusted
+ static void trustedFree()(T[] p) @trusted
{
- import core.stdc.stdlib : free;
+ import core.memory : pureFree;
static if (hasIndirections!T)
{
import core.memory : GC;
GC.removeRange(p.ptr);
}
- free(p.ptr);
+ pureFree(p.ptr);
}
trustedFree(xform1);
}
@@ -3186,7 +3186,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
}
///
-@safe unittest
+@safe pure unittest
{
import std.algorithm.iteration : map;
import std.numeric : entropy;
@@ -3207,7 +3207,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
assert(isSorted!("a > b")(map!(entropy)(arr)));
}
-@safe unittest
+@safe pure unittest
{
import std.algorithm.iteration : map;
import std.numeric : entropy;
@@ -3228,7 +3228,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
assert(isSorted!("a < b")(map!(entropy)(arr)));
}
-@safe unittest
+@safe pure unittest
{
// binary transform function
string[] strings = [ "one", "two", "three" ];
@@ -3237,7 +3237,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
}
// https://issues.dlang.org/show_bug.cgi?id=4909
-@safe unittest
+@safe pure unittest
{
import std.typecons : Tuple;
Tuple!(char)[] chars;
@@ -3245,7 +3245,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
}
// https://issues.dlang.org/show_bug.cgi?id=5924
-@safe unittest
+@safe pure unittest
{
import std.typecons : Tuple;
Tuple!(char)[] chars;
@@ -3253,7 +3253,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
}
// https://issues.dlang.org/show_bug.cgi?id=13965
-@safe unittest
+@safe pure unittest
{
import std.typecons : Tuple;
Tuple!(char)[] chars;
@@ -3261,7 +3261,7 @@ if (isRandomAccessRange!R && hasLength!R && hasSwappableElements!R)
}
// https://issues.dlang.org/show_bug.cgi?id=13965
-@safe unittest
+@safe pure unittest
{
import std.algorithm.iteration : map;
import std.numeric : entropy;
@@ -2149,14 +2149,16 @@ private
if (msg.convertsTo!(Args))
{
- static if (is(ReturnType!(t) == bool))
+ alias RT = ReturnType!(t);
+ static if (is(RT == bool))
{
return msg.map(op);
}
else
{
msg.map(op);
- return true;
+ static if (!is(immutable RT == immutable noreturn))
+ return true;
}
}
}
@@ -2745,7 +2747,8 @@ auto ref initOnce(alias var)(lazy typeof(var) init, shared Mutex mutex)
if (!atomicLoad!(MemoryOrder.raw)(flag))
{
var = init;
- atomicStore!(MemoryOrder.rel)(flag, true);
+ static if (!is(immutable typeof(var) == immutable noreturn))
+ atomicStore!(MemoryOrder.rel)(flag, true);
}
}
}
@@ -2827,3 +2830,26 @@ auto ref initOnce(alias var)(lazy typeof(var) init, Mutex mutex)
immutable expected = Aggregate(42, [1, 2, 3, 4, 5]);
assert(result1 == expected);
}
+
+// Noreturn support
+@system unittest
+{
+ static noreturn foo(int) { throw new Exception(""); }
+
+ if (false) spawn(&foo, 1);
+ if (false) spawnLinked(&foo, 1);
+
+ if (false) receive(&foo);
+ if (false) receiveTimeout(Duration.init, &foo);
+
+ // Wrapped in __traits(compiles) to skip codegen which crashes dmd's backend
+ static assert(__traits(compiles, receiveOnly!noreturn() ));
+ static assert(__traits(compiles, send(Tid.init, noreturn.init) ));
+ static assert(__traits(compiles, prioritySend(Tid.init, noreturn.init) ));
+ static assert(__traits(compiles, yield(noreturn.init) ));
+
+ static assert(__traits(compiles, {
+ __gshared noreturn n;
+ initOnce!n(noreturn.init);
+ }));
+}
@@ -196,6 +196,12 @@ struct DList(T)
T _payload = T.init;
+ this (BaseNode _base, T _payload)
+ {
+ this._base = _base;
+ this._payload = _payload;
+ }
+
inout(BaseNode)* asBaseNode() inout @trusted
{
return &_base;
@@ -887,7 +887,7 @@ if (is(typeof(binaryFun!less(T.init, T.init))))
* Returns:
* true if node was added
*/
- private bool _add(return Elem n)
+ private bool _add(return scope Elem n)
{
Node result;
static if (!allowDuplicates)
@@ -8349,7 +8349,7 @@ private:
}
{
- SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; }
+ SysTime stFunc(scope const SysTime st) { return SysTime.init; }
auto interval = Interval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)),
SysTime(DateTime(2012, 1, 7, 14, 0, 0)));
auto ir = IntervalRange!(SysTime, Direction.fwd)(interval, &stFunc);
@@ -8794,7 +8794,7 @@ private:
}
{
- SysTime stFunc(scope const SysTime st) { return cast(SysTime) st; }
+ SysTime stFunc(scope const SysTime st) { return SysTime.init; }
auto posInfInterval = PosInfInterval!SysTime(SysTime(DateTime(2010, 7, 4, 12, 1, 7)));
auto ir = PosInfIntervalRange!SysTime(posInfInterval, &stFunc);
}
@@ -9076,7 +9076,7 @@ private:
}
{
- SysTime stFunc(scope const SysTime st) { return cast(SysTime)(st); }
+ SysTime stFunc(scope const SysTime st) { return SysTime.init; }
auto negInfInterval = NegInfInterval!SysTime(SysTime(DateTime(2012, 1, 7, 14, 0, 0)));
auto ir = NegInfIntervalRange!(SysTime)(negInfInterval, &stFunc);
}
@@ -503,7 +503,7 @@ public:
given $(REF DateTime,std,datetime,date) is assumed to
be in the given time zone.
+/
- this(DateTime dateTime, immutable TimeZone tz = null) @safe nothrow
+ this(DateTime dateTime, return scope immutable TimeZone tz = null) return scope @safe nothrow
{
try
this(dateTime, Duration.zero, tz);
@@ -554,7 +554,7 @@ public:
$(REF DateTimeException,std,datetime,date) if `fracSecs` is negative or if it's
greater than or equal to one second.
+/
- this(DateTime dateTime, Duration fracSecs, immutable TimeZone tz = null) @safe
+ this(DateTime dateTime, Duration fracSecs, return scope immutable TimeZone tz = null) return scope @safe
{
enforce(fracSecs >= Duration.zero, new DateTimeException("A SysTime cannot have negative fractional seconds."));
enforce(fracSecs < seconds(1), new DateTimeException("Fractional seconds must be less than one second."));
@@ -611,7 +611,7 @@ public:
given $(REF Date,std,datetime,date) is assumed to be in the
given time zone.
+/
- this(Date date, immutable TimeZone tz = null) @safe nothrow
+ this(Date date, return scope immutable TimeZone tz = null) return scope @safe nothrow
{
_timezone = tz is null ? LocalTime() : tz;
@@ -664,7 +664,7 @@ public:
$(LREF SysTime). If null,
$(REF LocalTime,std,datetime,timezone) will be used.
+/
- this(long stdTime, immutable TimeZone tz = null) @safe pure nothrow
+ this(long stdTime, return scope immutable TimeZone tz = null) return scope @safe pure nothrow
{
_stdTime = stdTime;
_timezone = tz is null ? LocalTime() : tz;
@@ -693,7 +693,7 @@ public:
Returns: The `this` of this `SysTime`.
+/
- ref SysTime opAssign()(auto ref const(SysTime) rhs) return @safe pure nothrow scope
+ ref SysTime opAssign()(auto ref const(SysTime) rhs) return scope @safe pure nothrow
{
_stdTime = rhs._stdTime;
_timezone = rhs._timezone;
@@ -710,6 +710,7 @@ public:
st = other;
assert(st == other);
+ version (none) // https://issues.dlang.org/show_bug.cgi?id=21175
static void testScope(scope ref SysTime left, const scope SysTime right) @safe
{
left = right;
@@ -2184,7 +2185,7 @@ public:
hours - adjust the time to this $(LREF SysTime)'s time zone before
returning.
+/
- @property immutable(TimeZone) timezone() @safe const pure nothrow scope
+ @property immutable(TimeZone) timezone() @safe const pure nothrow return scope
{
return _timezone;
}
@@ -2238,7 +2239,7 @@ public:
/++
Returns whether DST is in effect for this $(LREF SysTime).
+/
- @property bool dstInEffect() @safe const nothrow scope
+ @property bool dstInEffect() @safe const nothrow return scope
{
return _timezone.dstInEffect(_stdTime);
}
@@ -2261,7 +2262,7 @@ public:
Returns what the offset from UTC is for this $(LREF SysTime).
It includes the DST offset in effect at that time (if any).
+/
- @property Duration utcOffset() @safe const nothrow scope
+ @property Duration utcOffset() @safe const nothrow return scope
{
return _timezone.utcOffsetAt(_stdTime);
}
@@ -9586,13 +9587,13 @@ private:
@property override bool hasDST() @safe const nothrow @nogc { return false; }
- override bool dstInEffect(long stdTime) @safe const nothrow @nogc { return false; }
+ override bool dstInEffect(long stdTime) @safe const scope nothrow @nogc { return false; }
- override long utcToTZ(long stdTime) @safe const nothrow @nogc { return 0; }
+ override long utcToTZ(long stdTime) @safe const scope nothrow @nogc { return 0; }
- override long tzToUTC(long adjTime) @safe const nothrow @nogc { return 0; }
+ override long tzToUTC(long adjTime) @safe const scope nothrow @nogc { return 0; }
- override Duration utcOffsetAt(long stdTime) @safe const nothrow @nogc { return Duration.zero; }
+ override Duration utcOffsetAt(long stdTime) @safe const scope nothrow @nogc { return Duration.zero; }
private:
@@ -9628,7 +9629,7 @@ private:
return _timezoneStorage is null ? InitTimeZone() : _timezoneStorage;
}
- pragma(inline, true) @property void _timezone(immutable TimeZone tz) @safe pure nothrow @nogc scope
+ pragma(inline, true) @property void _timezone(return scope immutable TimeZone tz) @safe pure nothrow @nogc scope
{
_timezoneStorage = tz;
}
@@ -100,7 +100,7 @@ public:
However, on Windows, it may be the unabbreviated name (e.g. Pacific
Standard Time). Regardless, it is not the same as name.
+/
- @property string stdName() @safe const nothrow
+ @property string stdName() @safe const scope nothrow
{
return _stdName;
}
@@ -113,7 +113,7 @@ public:
However, on Windows, it may be the unabbreviated name (e.g. Pacific
Daylight Time). Regardless, it is not the same as name.
+/
- @property string dstName() @safe const nothrow
+ @property string dstName() @safe const scope nothrow
{
return _dstName;
}
@@ -137,7 +137,7 @@ public:
stdTime = The UTC time that needs to be checked for DST in this time
zone.
+/
- abstract bool dstInEffect(long stdTime) @safe const nothrow;
+ abstract bool dstInEffect(long stdTime) @safe const scope nothrow;
/++
@@ -148,7 +148,7 @@ public:
stdTime = The UTC time that needs to be adjusted to this time zone's
time.
+/
- abstract long utcToTZ(long stdTime) @safe const nothrow;
+ abstract long utcToTZ(long stdTime) @safe const scope nothrow;
/++
@@ -159,7 +159,7 @@ public:
adjTime = The time in this time zone that needs to be adjusted to
UTC time.
+/
- abstract long tzToUTC(long adjTime) @safe const nothrow;
+ abstract long tzToUTC(long adjTime) @safe const scope nothrow;
/++
@@ -170,7 +170,7 @@ public:
stdTime = The UTC time for which to get the offset from UTC for this
time zone.
+/
- Duration utcOffsetAt(long stdTime) @safe const nothrow
+ Duration utcOffsetAt(long stdTime) @safe const scope nothrow
{
return dur!"hnsecs"(utcToTZ(stdTime) - stdTime);
}
@@ -580,7 +580,7 @@ public:
dynamically rather than it being fixed like it would be with most time
zones.
+/
- @property override string stdName() @trusted const nothrow
+ @property override string stdName() @trusted const scope nothrow
{
version (Posix)
{
@@ -665,7 +665,7 @@ public:
dynamically rather than it being fixed like it would be with most time
zones.
+/
- @property override string dstName() @trusted const nothrow
+ @property override string dstName() @trusted const scope nothrow
{
version (Posix)
{
@@ -809,7 +809,7 @@ public:
stdTime = The UTC time that needs to be checked for DST in this time
zone.
+/
- override bool dstInEffect(long stdTime) @trusted const nothrow
+ override bool dstInEffect(long stdTime) @trusted const scope nothrow
{
import core.stdc.time : tm;
@@ -863,7 +863,7 @@ public:
See_Also:
`TimeZone.utcToTZ`
+/
- override long utcToTZ(long stdTime) @trusted const nothrow
+ override long utcToTZ(long stdTime) @trusted const scope nothrow
{
version (Solaris)
return stdTime + convert!("seconds", "hnsecs")(tm_gmtoff(stdTime));
@@ -904,7 +904,7 @@ public:
adjTime = The time in this time zone that needs to be adjusted to
UTC time.
+/
- override long tzToUTC(long adjTime) @trusted const nothrow
+ override long tzToUTC(long adjTime) @trusted const scope nothrow
{
version (Posix)
{
@@ -1159,7 +1159,7 @@ public:
/++
Always returns false.
+/
- override bool dstInEffect(long stdTime) @safe const nothrow
+ override bool dstInEffect(long stdTime) @safe const scope nothrow
{
return false;
}
@@ -1175,7 +1175,7 @@ public:
See_Also:
`TimeZone.utcToTZ`
+/
- override long utcToTZ(long stdTime) @safe const nothrow
+ override long utcToTZ(long stdTime) @safe const scope nothrow
{
return stdTime;
}
@@ -1208,7 +1208,7 @@ public:
adjTime = The time in this time zone that needs to be adjusted to
UTC time.
+/
- override long tzToUTC(long adjTime) @safe const nothrow
+ override long tzToUTC(long adjTime) @safe const scope nothrow
{
return adjTime;
}
@@ -1238,7 +1238,7 @@ public:
stdTime = The UTC time for which to get the offset from UTC for this
time zone.
+/
- override Duration utcOffsetAt(long stdTime) @safe const nothrow
+ override Duration utcOffsetAt(long stdTime) @safe const scope nothrow
{
return dur!"hnsecs"(0);
}
@@ -1285,7 +1285,7 @@ public:
/++
Always returns false.
+/
- override bool dstInEffect(long stdTime) @safe const nothrow
+ override bool dstInEffect(long stdTime) @safe const scope nothrow
{
return false;
}
@@ -1299,7 +1299,7 @@ public:
stdTime = The UTC time that needs to be adjusted to this time zone's
time.
+/
- override long utcToTZ(long stdTime) @safe const nothrow
+ override long utcToTZ(long stdTime) @safe const scope nothrow
{
return stdTime + _utcOffset.total!"hnsecs";
}
@@ -1326,7 +1326,7 @@ public:
adjTime = The time in this time zone that needs to be adjusted to
UTC time.
+/
- override long tzToUTC(long adjTime) @safe const nothrow
+ override long tzToUTC(long adjTime) @safe const scope nothrow
{
return adjTime - _utcOffset.total!"hnsecs";
}
@@ -1352,7 +1352,7 @@ public:
stdTime = The UTC time for which to get the offset from UTC for this
time zone.
+/
- override Duration utcOffsetAt(long stdTime) @safe const nothrow
+ override Duration utcOffsetAt(long stdTime) @safe const scope nothrow
{
return _utcOffset;
}
@@ -1919,7 +1919,7 @@ public:
stdTime = The UTC time that needs to be checked for DST in this time
zone.
+/
- override bool dstInEffect(long stdTime) @safe const nothrow
+ override bool dstInEffect(long stdTime) @safe const scope nothrow
{
assert(!_transitions.empty);
@@ -1943,7 +1943,7 @@ public:
stdTime = The UTC time that needs to be adjusted to this time zone's
time.
+/
- override long utcToTZ(long stdTime) @safe const nothrow
+ override long utcToTZ(long stdTime) @safe const scope nothrow
{
assert(!_transitions.empty);
@@ -1968,7 +1968,7 @@ public:
adjTime = The time in this time zone that needs to be adjusted to
UTC time.
+/
- override long tzToUTC(long adjTime) @safe const nothrow
+ override long tzToUTC(long adjTime) @safe const scope nothrow
{
assert(!_transitions.empty, "UTC offset's not available");
@@ -2691,7 +2691,7 @@ private:
}
- int calculateLeapSeconds(long stdTime) @safe const pure nothrow
+ int calculateLeapSeconds(long stdTime) @safe const scope pure nothrow
{
if (_leapSeconds.empty)
return 0;
@@ -2864,7 +2864,7 @@ version (StdDdoc)
current dates but will still return true for `hasDST` because the
time zone did at some point have DST.
+/
- @property override bool hasDST() @safe const nothrow;
+ @property override bool hasDST() @safe const scope nothrow;
/++
@@ -2876,7 +2876,7 @@ version (StdDdoc)
stdTime = The UTC time that needs to be checked for DST in this
time zone.
+/
- override bool dstInEffect(long stdTime) @safe const nothrow;
+ override bool dstInEffect(long stdTime) @safe const scope nothrow;
/++
@@ -2888,7 +2888,7 @@ version (StdDdoc)
stdTime = The UTC time that needs to be adjusted to this time
zone's time.
+/
- override long utcToTZ(long stdTime) @safe const nothrow;
+ override long utcToTZ(long stdTime) @safe const scope nothrow;
/++
@@ -2900,7 +2900,7 @@ version (StdDdoc)
adjTime = The time in this time zone that needs to be adjusted
to UTC time.
+/
- override long tzToUTC(long adjTime) @safe const nothrow;
+ override long tzToUTC(long adjTime) @safe const scope nothrow;
/++
@@ -2945,9 +2945,9 @@ version (StdDdoc)
else
alias TIME_ZONE_INFORMATION = void*;
- static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow;
- static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow;
- static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow;
+ static bool _dstInEffect(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime) nothrow;
+ static long _utcToTZ(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) nothrow;
+ static long _tzToUTC(const scope TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) nothrow;
this() immutable pure
{
@@ -2967,25 +2967,25 @@ else version (Windows)
public:
- @property override bool hasDST() @safe const nothrow
+ @property override bool hasDST() @safe const scope nothrow
{
return _tzInfo.DaylightDate.wMonth != 0;
}
- override bool dstInEffect(long stdTime) @safe const nothrow
+ override bool dstInEffect(long stdTime) @safe const scope nothrow
{
return _dstInEffect(&_tzInfo, stdTime);
}
- override long utcToTZ(long stdTime) @safe const nothrow
+ override long utcToTZ(long stdTime) @safe const scope nothrow
{
return _utcToTZ(&_tzInfo, stdTime, hasDST);
}
- override long tzToUTC(long adjTime) @safe const nothrow
+ override long tzToUTC(long adjTime) @safe const scope nothrow
{
return _tzToUTC(&_tzInfo, adjTime, hasDST);
}
@@ -3071,7 +3071,7 @@ else version (Windows)
private:
- static bool _dstInEffect(const TIME_ZONE_INFORMATION* tzInfo, long stdTime) @trusted nothrow
+ static bool _dstInEffect(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime) @trusted nothrow
{
try
{
@@ -3155,7 +3155,7 @@ else version (Windows)
}
- static long _utcToTZ(const TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) @safe nothrow
+ static long _utcToTZ(const scope TIME_ZONE_INFORMATION* tzInfo, long stdTime, bool hasDST) @safe nothrow
{
if (hasDST && WindowsTimeZone._dstInEffect(tzInfo, stdTime))
return stdTime - convert!("minutes", "hnsecs")(tzInfo.Bias + tzInfo.DaylightBias);
@@ -3164,7 +3164,7 @@ else version (Windows)
}
- static long _tzToUTC(const TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) @trusted nothrow
+ static long _tzToUTC(const scope TIME_ZONE_INFORMATION* tzInfo, long adjTime, bool hasDST) @trusted nothrow
{
if (hasDST)
{
@@ -1124,7 +1124,7 @@ version (Windows) private ulong makeUlong(DWORD dwLow, DWORD dwHigh) @safe pure
}
version (Posix) private extern (C) pragma(mangle, stat.mangleof)
-int trustedStat(const(FSChar)* namez, ref stat_t buf) @nogc nothrow @trusted;
+int trustedStat(scope const(FSChar)* namez, ref stat_t buf) @nogc nothrow @trusted;
/**
Get size of file `name` in bytes.
@@ -1928,7 +1928,7 @@ if (isConvertibleToString!R)
assert(!f.exists);
}
-private bool existsImpl(const(FSChar)* namez) @trusted nothrow @nogc
+private bool existsImpl(scope const(FSChar)* namez) @trusted nothrow @nogc
{
version (Windows)
{
@@ -2010,7 +2010,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
version (Windows)
{
auto namez = name.tempCString!FSChar();
- static auto trustedGetFileAttributesW(const(FSChar)* namez) @trusted
+ static auto trustedGetFileAttributesW(scope const(FSChar)* namez) @trusted
{
return GetFileAttributesW(namez);
}
@@ -2220,7 +2220,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
version (Windows)
{
auto namez = name.tempCString!FSChar();
- static auto trustedSetFileAttributesW(const(FSChar)* namez, uint dwFileAttributes) @trusted
+ static auto trustedSetFileAttributesW(scope const(FSChar)* namez, uint dwFileAttributes) @trusted
{
return SetFileAttributesW(namez, dwFileAttributes);
}
@@ -2233,7 +2233,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
else version (Posix)
{
auto namez = name.tempCString!FSChar();
- static auto trustedChmod(const(FSChar)* namez, mode_t mode) @trusted
+ static auto trustedChmod(scope const(FSChar)* namez, mode_t mode) @trusted
{
return chmod(namez, mode);
}
@@ -2868,14 +2868,14 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
version (Windows)
{
- static auto trustedChdir(const(FSChar)* pathz) @trusted
+ static auto trustedChdir(scope const(FSChar)* pathz) @trusted
{
return SetCurrentDirectoryW(pathz);
}
}
else version (Posix)
{
- static auto trustedChdir(const(FSChar)* pathz) @trusted
+ static auto trustedChdir(scope const(FSChar)* pathz) @trusted
{
return core.sys.posix.unistd.chdir(pathz) == 0;
}
@@ -2939,7 +2939,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
version (Windows)
{
- static auto trustedCreateDirectoryW(const(FSChar)* pathz) @trusted
+ static auto trustedCreateDirectoryW(scope const(FSChar)* pathz) @trusted
{
return CreateDirectoryW(pathz, null);
}
@@ -2953,7 +2953,7 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
{
import std.conv : octal;
- static auto trustedMkdir(const(FSChar)* pathz, mode_t mode) @trusted
+ static auto trustedMkdir(scope const(FSChar)* pathz, mode_t mode) @trusted
{
return core.sys.posix.sys.stat.mkdir(pathz, mode);
}
@@ -3143,14 +3143,14 @@ if (isInputRange!R && !isInfinite!R && isSomeChar!(ElementEncodingType!R) &&
version (Windows)
{
- static auto trustedRmdir(const(FSChar)* pathz) @trusted
+ static auto trustedRmdir(scope const(FSChar)* pathz) @trusted
{
return RemoveDirectoryW(pathz);
}
}
else version (Posix)
{
- static auto trustedRmdir(const(FSChar)* pathz) @trusted
+ static auto trustedRmdir(scope const(FSChar)* pathz) @trusted
{
return core.sys.posix.unistd.rmdir(pathz) == 0;
}
@@ -3859,17 +3859,17 @@ else version (Windows)
return _size;
}
- @property SysTime timeCreated() const pure nothrow scope
+ @property SysTime timeCreated() const pure nothrow return scope
{
return cast(SysTime)_timeCreated;
}
- @property SysTime timeLastAccessed() const pure nothrow scope
+ @property SysTime timeLastAccessed() const pure nothrow return scope
{
return cast(SysTime)_timeLastAccessed;
}
- @property SysTime timeLastModified() const pure nothrow scope
+ @property SysTime timeLastModified() const pure nothrow return scope
{
return cast(SysTime)_timeLastModified;
}
@@ -227,7 +227,7 @@ private struct TempCStringBuffer(To = char)
@disable this(this);
alias ptr this; /// implicitly covert to raw pointer
- @property inout(To)* buffPtr() inout
+ @property inout(To)* buffPtr() return inout
{
return _ptr == useStack ? _buff.ptr : _ptr;
}
@@ -879,7 +879,7 @@ public:
}
// return x / y
- static BigUint divInt(T)(scope return BigUint x, T y_) pure nothrow @safe
+ static BigUint divInt(T)(return scope BigUint x, T y_) pure nothrow @safe
if ( is(immutable T == immutable uint) )
{
uint y = y_;
@@ -942,7 +942,7 @@ public:
}
// return x / y
- static BigUint div(scope return BigUint x, scope BigUint y) pure nothrow @safe
+ static BigUint div(return scope BigUint x, scope BigUint y) pure nothrow @safe
{
if (y.data.length > x.data.length)
return BigUint(ZERO);
@@ -954,7 +954,7 @@ public:
}
// return x % y
- static BigUint mod(scope return BigUint x, scope BigUint y) pure nothrow @safe
+ static BigUint mod(return scope BigUint x, scope BigUint y) pure nothrow @safe
{
if (y.data.length > x.data.length) return x;
if (y.data.length == 1)
@@ -1020,7 +1020,7 @@ public:
* exponentiation is used.
* Memory allocation is minimized: at most one temporary BigUint is used.
*/
- static BigUint pow(scope return BigUint x, ulong y) pure nothrow @safe
+ static BigUint pow(return scope BigUint x, ulong y) pure nothrow @safe
{
// Deal with the degenerate cases first.
if (y == 0) return BigUint(ONE);
@@ -1259,7 +1259,7 @@ public:
}
// Remove leading zeros from x, to restore the BigUint invariant
-inout(BigDigit) [] removeLeadingZeros(scope return inout(BigDigit) [] x) pure nothrow @safe
+inout(BigDigit) [] removeLeadingZeros(return scope inout(BigDigit) [] x) pure nothrow @safe
{
size_t k = x.length;
while (k>1 && x[k - 1]==0) --k;
@@ -1916,7 +1916,7 @@ pure @safe unittest
// every 8 digits.
// buff.length must be data.length*8 if separator is zero,
// or data.length*9 if separator is non-zero. It will be completely filled.
-char [] biguintToHex(scope return char [] buff, const scope BigDigit [] data, char separator=0,
+char [] biguintToHex(return scope char [] buff, const scope BigDigit [] data, char separator=0,
LetterCase letterCase = LetterCase.upper) pure nothrow @safe
{
int x=0;
@@ -159,7 +159,7 @@ struct JSONValue
return store.str;
}
/// ditto
- @property string str(return string v) pure nothrow @nogc @trusted return // TODO make @safe
+ @property string str(return scope string v) pure nothrow @nogc @trusted return // TODO make @safe
{
assign(v);
return v;
@@ -282,7 +282,7 @@ struct JSONValue
return store.object;
}
/// ditto
- @property JSONValue[string] object(return JSONValue[string] v) pure nothrow @nogc @trusted // TODO make @safe
+ @property JSONValue[string] object(return scope JSONValue[string] v) pure nothrow @nogc @trusted // TODO make @safe
{
assign(v);
return v;
@@ -321,14 +321,14 @@ struct JSONValue
(*a)[0] = "world"; // segmentation fault
---
*/
- @property ref inout(JSONValue[]) array() inout pure @system
+ @property ref inout(JSONValue[]) array() return scope inout pure @system
{
enforce!JSONException(type == JSONType.array,
"JSONValue is not an array");
return store.array;
}
/// ditto
- @property JSONValue[] array(return JSONValue[] v) pure nothrow @nogc @trusted scope // TODO make @safe
+ @property JSONValue[] array(return scope JSONValue[] v) pure nothrow @nogc @trusted scope // TODO make @safe
{
assign(v);
return v;
@@ -635,7 +635,7 @@ struct JSONValue
* Hash syntax for json objects.
* Throws: `JSONException` if `type` is not `JSONType.object`.
*/
- ref inout(JSONValue) opIndex(return string k) inout pure @safe
+ ref inout(JSONValue) opIndex(return scope string k) inout pure @safe
{
auto o = this.objectNoRef;
return *enforce!JSONException(k in o,
@@ -1893,7 +1893,7 @@ Note that only the first item of "matchAll" was ever used in practice
so we can return `const(Char)[]` instead of `const(Char)[][]` using a
zero-length string to indicate no match.
+/
-const(Char)[] matchIPSuffix(Char)(return const(Char)[] s) @nogc nothrow pure @safe
+const(Char)[] matchIPSuffix(Char)(return scope const(Char)[] s) @nogc nothrow pure @safe
{
size_t end = s.length;
if (end < 7) return null;
@@ -276,7 +276,7 @@ static:
multi-threaded programs. See e.g.
$(LINK2 https://www.gnu.org/software/libc/manual/html_node/Environment-Access.html#Environment-Access, glibc).
*/
- inout(char)[] opIndexAssign(return inout char[] value, scope const(char)[] name) @trusted
+ inout(char)[] opIndexAssign(return scope inout char[] value, scope const(char)[] name) @trusted
{
version (Posix)
{
@@ -4385,6 +4385,7 @@ else version (Posix)
void browse(scope const(char)[] url) nothrow @nogc @safe
{
+ const buffer = url.tempCString(); // Retain buffer until end of scope
const(char)*[3] args;
// Trusted because it's called with a zero-terminated literal
@@ -4408,7 +4409,6 @@ else version (Posix)
}
}
- const buffer = url.tempCString(); // Retain buffer until end of scope
args[1] = buffer;
args[2] = null;
@@ -166,12 +166,16 @@ version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any;
assert(10.iota.randomSample(3, rnd2).equal([7, 8, 9]));
// Cover all elements in an array in random order
- version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
- assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
+ version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
+ assert(10.iota.randomCover(rnd2).equal([7, 4, 2, 0, 1, 6, 8, 3, 9, 5]));
+ else
+ assert(10.iota.randomCover(rnd2).equal([4, 8, 7, 3, 5, 9, 2, 6, 0, 1]));
// Shuffle an array
- version (X86_64) // https://issues.dlang.org/show_bug.cgi?id=15147
- assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1]));
+ version (D_LP64) // https://issues.dlang.org/show_bug.cgi?id=15147
+ assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([2, 0, 4, 5, 1]));
+ else
+ assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([4, 2, 5, 0, 1]));
}
version (StdUnittest)
@@ -4650,7 +4650,7 @@ if ((isInputRange!R1 && isSomeChar!(ElementEncodingType!R1) || isSomeString!R1)
auto namez = name.tempCString!FSChar();
auto modez = mode.tempCString!FSChar();
- static _fopenImpl(const(FSChar)* namez, const(FSChar)* modez) @trusted nothrow @nogc
+ static _fopenImpl(scope const(FSChar)* namez, scope const(FSChar)* modez) @trusted nothrow @nogc
{
version (Windows)
{
@@ -2239,7 +2239,7 @@ if (is(T == class) || is(T == interface) || isAssociativeArray!T)
U stripped;
}
- void opAssign(T another) pure nothrow @nogc
+ void opAssign(return scope T another) pure nothrow @nogc
{
// If `T` defines `opCast` we must infer the safety
static if (hasMember!(T, "opCast"))
@@ -2271,7 +2271,7 @@ if (is(T == class) || is(T == interface) || isAssociativeArray!T)
opAssign(initializer);
}
- @property inout(T) get() @trusted pure nothrow @nogc inout
+ @property inout(T) get() @trusted pure nothrow @nogc return scope inout
{
return original;
}
@@ -2792,6 +2792,15 @@ struct Nullable(T)
}
}
+ this (ref return scope inout Nullable!T rhs) inout
+ {
+ _isNull = rhs._isNull;
+ if (!_isNull)
+ _value.payload = rhs._value.payload;
+ else
+ _value = DontCallDestructorT.init;
+ }
+
/**
* If they are both null, then they are equal. If one is null and the other
* is not, then they are not equal. If they are both non-null, then they are
@@ -3284,11 +3293,11 @@ auto nullable(T)(T t)
static struct S2 //inspired from 9404
{
Nullable!int ni;
- this(S2 other)
+ this(ref S2 other)
{
ni = other.ni;
}
- void opAssign(S2 other)
+ void opAssign(ref S2 other)
{
ni = other.ni;
}
@@ -9566,3 +9575,21 @@ unittest
assert((a ^ true) == Ternary.no);
assert((a ^ false) == Ternary.yes);
}
+
+// https://issues.dlang.org/show_bug.cgi?id=22511
+@safe unittest
+{
+ static struct S
+ {
+ int b;
+ @disable this(this);
+ this (ref return scope inout S rhs) inout
+ {
+ this.b = rhs.b + 1;
+ }
+ }
+
+ Nullable!S s1 = S(1);
+ Nullable!S s2 = s1;
+ assert(s2.get().b > s1.get().b);
+}
@@ -1987,8 +1987,8 @@ pure:
{
return this[0] == val[0] && this[1] == val[1];
}
- @property ref inout(uint) a() inout { return _tuple[0]; }
- @property ref inout(uint) b() inout { return _tuple[1]; }
+ @property ref inout(uint) a() return inout { return _tuple[0]; }
+ @property ref inout(uint) b() return inout { return _tuple[1]; }
}
/**
@@ -4315,12 +4315,12 @@ if (isSomeChar!C)
{
enum Empty = uint.max; // range is empty or just constructed
- this(return R r)
+ this(return scope R r)
{
this.r = r;
}
- this(return R r, uint buff)
+ this(return scope R r, uint buff)
{
this.r = r;
this.buff = buff;
@@ -4328,7 +4328,7 @@ if (isSomeChar!C)
static if (isBidirectionalRange!R)
{
- this(return R r, uint frontBuff, uint backBuff)
+ this(return scope R r, uint frontBuff, uint backBuff)
{
this.r = r;
this.buff = frontBuff;
@@ -4436,12 +4436,12 @@ if (isSomeChar!C)
{
static struct Result
{
- this(return R r)
+ this(return scope R r)
{
this.r = r;
}
- this(return R r, ushort pos, ushort fill, C[4 / C.sizeof] buf)
+ this(return scope R r, ushort pos, ushort fill, C[4 / C.sizeof] buf)
{
this.r = r;
this.pos = pos;
@@ -4451,7 +4451,7 @@ if (isSomeChar!C)
static if (isBidirectionalRange!R)
{
- this(return R r, ushort frontPos, ushort frontFill,
+ this(return scope R r, ushort frontPos, ushort frontFill,
ushort backPos, ushort backFill, C[4 / C.sizeof] buf)
{
this.r = r;
@@ -22,6 +22,7 @@ set dg-output-text [list]
set config_test_list [list \
{ test19433 "--DRT-dont-eat-me" 0 } \
{ test20459 "foo bar -- --DRT-gcopts=profile:1" 0 } \
+ { test22523 "-- --DRT-testmode=run-main" 0 } \
]
# Initialize dg.
new file mode 100644
@@ -0,0 +1,11 @@
+// https://issues.dlang.org/show_bug.cgi?id=22523
+
+import core.stdc.stdio;
+
+int main()
+{
+ puts("Executed main although it should be skipped!");
+ return 1;
+}
+
+unittest {}