aboutsummaryrefslogtreecommitdiff
path: root/libphobos/libdruntime
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-09-22 06:29:20 -0700
committerIan Lance Taylor <iant@golang.org>2022-09-22 06:29:20 -0700
commit795cffe109e28b248a54b8ee583cbae48368c2a7 (patch)
tree0c12b075c51c0d5097f26953835ae540d9f2f501 /libphobos/libdruntime
parent9f62ed218fa656607740b386c0caa03e65dcd283 (diff)
parentf35be1268c996d993ab0b4ff329734d467474445 (diff)
downloadgcc-795cffe109e28b248a54b8ee583cbae48368c2a7.zip
gcc-795cffe109e28b248a54b8ee583cbae48368c2a7.tar.gz
gcc-795cffe109e28b248a54b8ee583cbae48368c2a7.tar.bz2
Merge from trunk revision f35be1268c996d993ab0b4ff329734d467474445.
Diffstat (limited to 'libphobos/libdruntime')
-rw-r--r--libphobos/libdruntime/MERGE4
-rw-r--r--libphobos/libdruntime/Makefile.am7
-rw-r--r--libphobos/libdruntime/Makefile.in13
-rw-r--r--libphobos/libdruntime/core/cpuid.d16
-rw-r--r--libphobos/libdruntime/core/demangle.d2
-rw-r--r--libphobos/libdruntime/core/exception.d10
-rw-r--r--libphobos/libdruntime/core/int128.d2
-rw-r--r--libphobos/libdruntime/core/internal/array/appending.d28
-rw-r--r--libphobos/libdruntime/core/internal/array/arrayassign.d304
-rw-r--r--libphobos/libdruntime/core/internal/array/duplication.d346
-rw-r--r--libphobos/libdruntime/core/internal/array/equality.d27
-rw-r--r--libphobos/libdruntime/core/internal/dassert.d2
-rw-r--r--libphobos/libdruntime/core/runtime.d2
-rw-r--r--libphobos/libdruntime/core/stdc/errno.d2
-rw-r--r--libphobos/libdruntime/core/stdc/stdio.d53
-rw-r--r--libphobos/libdruntime/core/stdc/wchar_.d90
-rw-r--r--libphobos/libdruntime/core/sys/darwin/mach/getsect.d1
-rw-r--r--libphobos/libdruntime/core/sys/dragonflybsd/string.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/time.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/sys/xattr.d1
-rw-r--r--libphobos/libdruntime/core/sys/linux/tipc.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/signal.d79
-rw-r--r--libphobos/libdruntime/core/sys/posix/spawn.d2
-rw-r--r--libphobos/libdruntime/core/sys/posix/stdio.d2
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/select.d1
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/socket.d36
-rw-r--r--libphobos/libdruntime/core/sys/posix/time.d66
-rw-r--r--libphobos/libdruntime/core/sys/posix/ucontext.d1
-rw-r--r--libphobos/libdruntime/core/sys/solaris/sys/priocntl.d1
-rw-r--r--libphobos/libdruntime/core/sys/solaris/sys/procset.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/cguid.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/ntsecpkg.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/olectlid.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/shlguid.d1
-rw-r--r--libphobos/libdruntime/core/sys/windows/sspi.d1
-rw-r--r--libphobos/libdruntime/object.d431
-rw-r--r--libphobos/libdruntime/rt/arrayassign.d165
-rw-r--r--libphobos/libdruntime/rt/dylib_fixes.c1
38 files changed, 1012 insertions, 692 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 6e25a9d..85fc49d 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-651389b52243dcadb338dd0c14dd27e7850cda8d
+817610b16d0f0f469b9fbb28c000956fb910c43f
The first line of this file holds the git revision number of the last
-merge done from the dlang/druntime repository.
+merge done from the dlang/dmd repository.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index 56b332d..d828749 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -171,9 +171,10 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/builtins.d core/checkedint.d core/cpuid.d core/demangle.d \
core/exception.d core/gc/config.d core/gc/gcinterface.d \
core/gc/registry.d core/int128.d core/internal/abort.d \
- core/internal/array/appending.d core/internal/array/capacity.d \
- core/internal/array/casting.d core/internal/array/comparison.d \
- core/internal/array/concatenation.d core/internal/array/construction.d \
+ core/internal/array/appending.d core/internal/array/arrayassign.d \
+ core/internal/array/capacity.d core/internal/array/casting.d \
+ core/internal/array/comparison.d core/internal/array/concatenation.d \
+ core/internal/array/construction.d core/internal/array/duplication.d \
core/internal/array/equality.d core/internal/array/operations.d \
core/internal/array/utils.d core/internal/atomic.d \
core/internal/attributes.d core/internal/container/array.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 24865fb..57660ee 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -192,10 +192,12 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
core/demangle.lo core/exception.lo core/gc/config.lo \
core/gc/gcinterface.lo core/gc/registry.lo core/int128.lo \
core/internal/abort.lo core/internal/array/appending.lo \
+ core/internal/array/arrayassign.lo \
core/internal/array/capacity.lo core/internal/array/casting.lo \
core/internal/array/comparison.lo \
core/internal/array/concatenation.lo \
core/internal/array/construction.lo \
+ core/internal/array/duplication.lo \
core/internal/array/equality.lo \
core/internal/array/operations.lo core/internal/array/utils.lo \
core/internal/atomic.lo core/internal/attributes.lo \
@@ -838,9 +840,10 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/builtins.d core/checkedint.d core/cpuid.d core/demangle.d \
core/exception.d core/gc/config.d core/gc/gcinterface.d \
core/gc/registry.d core/int128.d core/internal/abort.d \
- core/internal/array/appending.d core/internal/array/capacity.d \
- core/internal/array/casting.d core/internal/array/comparison.d \
- core/internal/array/concatenation.d core/internal/array/construction.d \
+ core/internal/array/appending.d core/internal/array/arrayassign.d \
+ core/internal/array/capacity.d core/internal/array/casting.d \
+ core/internal/array/comparison.d core/internal/array/concatenation.d \
+ core/internal/array/construction.d core/internal/array/duplication.d \
core/internal/array/equality.d core/internal/array/operations.d \
core/internal/array/utils.d core/internal/atomic.d \
core/internal/attributes.d core/internal/container/array.d \
@@ -1200,6 +1203,8 @@ core/internal/array/$(am__dirstamp):
@$(MKDIR_P) core/internal/array
@: > core/internal/array/$(am__dirstamp)
core/internal/array/appending.lo: core/internal/array/$(am__dirstamp)
+core/internal/array/arrayassign.lo: \
+ core/internal/array/$(am__dirstamp)
core/internal/array/capacity.lo: core/internal/array/$(am__dirstamp)
core/internal/array/casting.lo: core/internal/array/$(am__dirstamp)
core/internal/array/comparison.lo: \
@@ -1208,6 +1213,8 @@ core/internal/array/concatenation.lo: \
core/internal/array/$(am__dirstamp)
core/internal/array/construction.lo: \
core/internal/array/$(am__dirstamp)
+core/internal/array/duplication.lo: \
+ core/internal/array/$(am__dirstamp)
core/internal/array/equality.lo: core/internal/array/$(am__dirstamp)
core/internal/array/operations.lo: \
core/internal/array/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/cpuid.d b/libphobos/libdruntime/core/cpuid.d
index e31f776..1c2ac06 100644
--- a/libphobos/libdruntime/core/cpuid.d
+++ b/libphobos/libdruntime/core/cpuid.d
@@ -170,6 +170,8 @@ public:
bool hle() {return _hle;}
/// Is RTM (restricted transactional memory) supported
bool rtm() {return _rtm;}
+ /// Is AVX512F supported
+ bool avx512f() {return _avx512f;}
/// Is rdseed supported
bool hasRdseed() {return _hasRdseed;}
/// Is SHA supported
@@ -279,6 +281,7 @@ private immutable
bool _avx2;
bool _hle;
bool _rtm;
+ bool _avx512f;
bool _hasRdseed;
bool _hasSha;
bool _amd3dnow;
@@ -389,6 +392,7 @@ CpuFeatures* getCpuFeatures() @nogc nothrow
enum : uint
{
FSGSBASE_BIT = 1 << 0,
+ SGX_BIT = 1 << 2,
BMI1_BIT = 1 << 3,
HLE_BIT = 1 << 4,
AVX2_BIT = 1 << 5,
@@ -397,8 +401,19 @@ CpuFeatures* getCpuFeatures() @nogc nothrow
ERMS_BIT = 1 << 9,
INVPCID_BIT = 1 << 10,
RTM_BIT = 1 << 11,
+ AVX512F_BIT = 1 << 16,
+ AVX512DQ_BIT = 1 << 17,
RDSEED_BIT = 1 << 18,
+ ADX_BIT = 1 << 19,
+ AVX512IFMA_BIT = 1 << 21,
+ CLFLUSHOPT_BIT = 1 << 23,
+ CLWB_BIT = 1 << 24,
+ AVX512PF_BIT = 1 << 26,
+ AVX512ER_BIT = 1 << 27,
+ AVX512CD_BIT = 1 << 28,
SHA_BIT = 1 << 29,
+ AVX512BW_BIT = 1 << 30,
+ AVX512VL_BIT = 1 << 31,
}
// feature flags XFEATURES_ENABLED_MASK
enum : ulong
@@ -1122,6 +1137,7 @@ shared static this()
_avx2 = avx && (cf.extfeatures & AVX2_BIT) != 0;
_hle = (cf.extfeatures & HLE_BIT) != 0;
_rtm = (cf.extfeatures & RTM_BIT) != 0;
+ _avx512f = (cf.extfeatures & AVX512F_BIT) != 0;
_hasRdseed = (cf.extfeatures&RDSEED_BIT)!=0;
_hasSha = (cf.extfeatures&SHA_BIT)!=0;
_amd3dnow = (cf.amdfeatures&AMD_3DNOW_BIT)!=0;
diff --git a/libphobos/libdruntime/core/demangle.d b/libphobos/libdruntime/core/demangle.d
index cb8d433..ca87f90 100644
--- a/libphobos/libdruntime/core/demangle.d
+++ b/libphobos/libdruntime/core/demangle.d
@@ -2328,7 +2328,7 @@ char[] mangle(T)(return scope const(char)[] fqn, return scope char[] dst = null)
@property bool empty() const { return !s.length; }
- @property const(char)[] front() const return
+ @property const(char)[] front() const return scope
{
immutable i = indexOfDot();
return i == -1 ? s[0 .. $] : s[0 .. i];
diff --git a/libphobos/libdruntime/core/exception.d b/libphobos/libdruntime/core/exception.d
index 81aa43b..a05a24c 100644
--- a/libphobos/libdruntime/core/exception.d
+++ b/libphobos/libdruntime/core/exception.d
@@ -14,7 +14,7 @@ void __switch_errorT()(string file = __FILE__, size_t line = __LINE__) @trusted
{
// Consider making this a compile time check.
version (D_Exceptions)
- throw staticError!SwitchError(file, line, null);
+ throw staticError!SwitchError("No appropriate switch clause found", file, line, null);
else
assert(0, "No appropriate switch clause found");
}
@@ -446,16 +446,16 @@ class ForkError : Error
*/
class SwitchError : Error
{
- @safe pure nothrow @nogc this( string file = __FILE__, size_t line = __LINE__, Throwable next = null )
+ @safe pure nothrow @nogc this( string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null )
{
- super( "No appropriate switch clause found", file, line, next );
+ super( msg, file, line, next );
}
}
unittest
{
{
- auto se = new SwitchError();
+ auto se = new SwitchError("No appropriate switch clause found");
assert(se.file == __FILE__);
assert(se.line == __LINE__ - 2);
assert(se.next is null);
@@ -463,7 +463,7 @@ unittest
}
{
- auto se = new SwitchError("hello", 42, new Exception("It's an Exception!"));
+ auto se = new SwitchError("No appropriate switch clause found", "hello", 42, new Exception("It's an Exception!"));
assert(se.file == "hello");
assert(se.line == 42);
assert(se.next !is null);
diff --git a/libphobos/libdruntime/core/int128.d b/libphobos/libdruntime/core/int128.d
index e4326fd..46eb9b2 100644
--- a/libphobos/libdruntime/core/int128.d
+++ b/libphobos/libdruntime/core/int128.d
@@ -943,5 +943,3 @@ unittest
assert(rol(C7_9, 1) == rol1(C7_9));
assert(ror(C7_9, 1) == ror1(C7_9));
}
-
-
diff --git a/libphobos/libdruntime/core/internal/array/appending.d b/libphobos/libdruntime/core/internal/array/appending.d
index d416efe..616d27c 100644
--- a/libphobos/libdruntime/core/internal/array/appending.d
+++ b/libphobos/libdruntime/core/internal/array/appending.d
@@ -30,26 +30,14 @@ template _d_arrayappendcTXImpl(Tarr : T[], T)
* Returns:
* The new value of `px`
* 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 pure` until the implementation can be brought up to modern D expectations.
+ * 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 pure` until the implementation can be brought up to modern D expectations.
*/
- static if (isCopyingNothrow!T) // `nothrow` deduction doesn't work, so this is needed
- ref Tarr _d_arrayappendcTX(return ref scope Tarr px, size_t n) @trusted pure nothrow
- {
- pragma(inline, false);
-
- mixin(_d_arrayappendcTXBody);
- }
- else
- ref Tarr _d_arrayappendcTX(return ref scope Tarr px, size_t n) @trusted pure nothrow
- {
- pragma(inline, false);
-
- mixin(_d_arrayappendcTXBody);
- }
-
- private enum _d_arrayappendcTXBody = q{
+ ref Tarr _d_arrayappendcTX(return ref scope Tarr px, size_t n) @trusted pure nothrow
+ {
+ // needed for CTFE: https://github.com/dlang/druntime/pull/3870#issuecomment-1178800718
+ pragma(inline, false);
version (D_TypeInfo)
{
auto ti = typeid(Tarr);
@@ -64,7 +52,7 @@ template _d_arrayappendcTXImpl(Tarr : T[], T)
}
else
assert(0, "Cannot append arrays if compiling without support for runtime type information!");
- };
+ }
/**
* TraceGC wrapper around $(REF _d_arrayappendcTX, rt,array,appending,_d_arrayappendcTXImpl).
diff --git a/libphobos/libdruntime/core/internal/array/arrayassign.d b/libphobos/libdruntime/core/internal/array/arrayassign.d
new file mode 100644
index 0000000..6132e68
--- /dev/null
+++ b/libphobos/libdruntime/core/internal/array/arrayassign.d
@@ -0,0 +1,304 @@
+module core.internal.array.arrayassign;
+
+// Force `enforceRawArraysConformable` to remain `pure` `@nogc`
+private void enforceRawArraysConformable(const char[] action, const size_t elementSize,
+ const void[] a1, const void[] a2, const bool allowOverlap) @trusted @nogc pure nothrow
+{
+ import core.internal.util.array : enforceRawArraysConformable;
+
+ alias Type = void function(const char[] action, const size_t elementSize,
+ const void[] a1, const void[] a2, in bool allowOverlap = false) @nogc pure nothrow;
+ (cast(Type)&enforceRawArraysConformable)(action, elementSize, a1, a2, allowOverlap);
+}
+
+private template CopyElem(string CopyAction)
+{
+ const char[] CopyElem = "{\n" ~ q{
+ memcpy(&tmp, cast(void*) &dst, elemSize);
+ } ~ CopyAction ~ q{
+ auto elem = cast(Unqual!T*) &tmp;
+ destroy(*elem);
+ } ~ "}\n";
+}
+
+private template CopyArray(bool CanOverlap, string CopyAction)
+{
+ const char[] CopyArray = CanOverlap ? q{
+ if (vFrom.ptr < vTo.ptr && vTo.ptr < vFrom.ptr + elemSize * vFrom.length)
+ foreach_reverse (i, ref dst; to)
+ } ~ CopyElem!(CopyAction) ~ q{
+ else
+ foreach (i, ref dst; to)
+ } ~ CopyElem!(CopyAction)
+ : q{
+ foreach (i, ref dst; to)
+ } ~ CopyElem!(CopyAction);
+}
+
+private template ArrayAssign(string CopyLogic, string AllowOverLap)
+{
+ const char[] ArrayAssign = q{
+ import core.internal.traits : hasElaborateCopyConstructor, Unqual;
+ import core.lifetime : copyEmplace;
+ import core.stdc.string : memcpy;
+
+ void[] vFrom = (cast(void*) from.ptr)[0 .. from.length];
+ void[] vTo = (cast(void*) to.ptr)[0 .. to.length];
+ enum elemSize = T.sizeof;
+
+ enforceRawArraysConformable("copy", elemSize, vFrom, vTo, } ~ AllowOverLap ~ q{);
+
+ void[elemSize] tmp = void;
+
+ } ~ CopyLogic ~ q{
+
+ return to;
+ };
+}
+
+/**
+ * Does array assignment (not construction) from another array of the same
+ * element type. Handles overlapping copies. Assumes the right hand side is an
+ * lvalue,
+ *
+ * Used for static array assignment with non-POD element types:
+ * ---
+ * struct S
+ * {
+ * ~this() {} // destructor, so not Plain Old Data
+ * }
+ *
+ * void main()
+ * {
+ * S[3] arr;
+ * S[3] lvalue;
+ *
+ * arr = lvalue;
+ * // Generates:
+ * // _d_arrayassign_l(arr[], lvalue[]), arr;
+ * }
+ * ---
+ *
+ * Params:
+ * to = destination array
+ * from = source array
+ * Returns:
+ * `to`
+ */
+Tarr _d_arrayassign_l(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted
+{
+ mixin(ArrayAssign!(q{
+ static if (hasElaborateCopyConstructor!T)
+ } ~ CopyArray!(true, "copyEmplace(from[i], dst);") ~ q{
+ else
+ } ~ CopyArray!(true, "memcpy(cast(void*) &dst, cast(void*) &from[i], elemSize);"),
+ "true"));
+}
+
+@safe unittest
+{
+ int counter;
+ struct S
+ {
+ int val;
+ this(int val) { this.val = val; }
+ this(const scope ref S rhs)
+ {
+ val = rhs.val;
+ counter++;
+ }
+ }
+
+ S[4] arr1;
+ S[4] arr2 = [S(0), S(1), S(2), S(3)];
+ _d_arrayassign_l(arr1[], arr2[]);
+
+ assert(counter == 4);
+ assert(arr1 == arr2);
+}
+
+// copy constructor
+@safe unittest
+{
+ int counter;
+ struct S
+ {
+ int val;
+ this(int val) { this.val = val; }
+ this(const scope ref S rhs)
+ {
+ val = rhs.val;
+ counter++;
+ }
+ }
+
+ S[4] arr1;
+ S[4] arr2 = [S(0), S(1), S(2), S(3)];
+ _d_arrayassign_l(arr1[], arr2[]);
+
+ assert(counter == 4);
+ assert(arr1 == arr2);
+}
+
+@safe nothrow unittest
+{
+ // Test that throwing works
+ int counter;
+ bool didThrow;
+
+ struct Throw
+ {
+ int val;
+ this(this)
+ {
+ counter++;
+ if (counter == 2)
+ throw new Exception("");
+ }
+ }
+ try
+ {
+ Throw[4] a;
+ Throw[4] b = [Throw(1), Throw(2), Throw(3), Throw(4)];
+ _d_arrayassign_l(a[], b[]);
+ }
+ catch (Exception)
+ {
+ didThrow = true;
+ }
+ assert(didThrow);
+ assert(counter == 2);
+
+
+ // Test that `nothrow` works
+ didThrow = false;
+ counter = 0;
+ struct NoThrow
+ {
+ int val;
+ this(this)
+ {
+ counter++;
+ }
+ }
+ try
+ {
+ NoThrow[4] a;
+ NoThrow[4] b = [NoThrow(1), NoThrow(2), NoThrow(3), NoThrow(4)];
+ _d_arrayassign_l(a[], b[]);
+ }
+ catch (Exception)
+ {
+ didThrow = false;
+ }
+ assert(!didThrow);
+ assert(counter == 4);
+}
+
+/**
+ * Does array assignment (not construction) from another array of the same
+ * element type. Does not support overlapping copies. Assumes the right hand
+ * side is an rvalue,
+ *
+ * Used for static array assignment with non-POD element types:
+ * ---
+ * struct S
+ * {
+ * ~this() {} // destructor, so not Plain Old Data
+ * }
+ *
+ * void main()
+ * {
+ * S[3] arr;
+ * S[3] getRvalue() {return lvalue;}
+ *
+ * arr = getRvalue();
+ * // Generates:
+ * // (__appendtmp = getRvalue), _d_arrayassign_l(arr[], __appendtmp), arr;
+ * }
+ * ---
+ *
+ * Params:
+ * to = destination array
+ * from = source array
+ * Returns:
+ * `to`
+ */
+Tarr _d_arrayassign_r(Tarr : T[], T)(return scope Tarr to, scope Tarr from) @trusted
+{
+ mixin(ArrayAssign!(
+ CopyArray!(false, "memcpy(cast(void*) &dst, cast(void*) &from[i], elemSize);"),
+ "false"));
+}
+
+@safe unittest
+{
+ int counter;
+ struct S
+ {
+ int val;
+ this(int val) { this.val = val; }
+ this(const scope ref S rhs)
+ {
+ val = rhs.val;
+ counter++;
+ }
+ }
+
+ S[4] arr1;
+ S[4] arr2 = [S(0), S(1), S(2), S(3)];
+ _d_arrayassign_r(arr1[], arr2[]);
+
+ assert(counter == 0);
+ assert(arr1 == arr2);
+}
+
+// copy constructor
+@safe unittest
+{
+ int counter;
+ struct S
+ {
+ int val;
+ this(int val) { this.val = val; }
+ this(const scope ref S rhs)
+ {
+ val = rhs.val;
+ counter++;
+ }
+ }
+
+ S[4] arr1;
+ S[4] arr2 = [S(0), S(1), S(2), S(3)];
+ _d_arrayassign_r(arr1[], arr2[]);
+
+ assert(counter == 0);
+ assert(arr1 == arr2);
+}
+
+@safe nothrow unittest
+{
+ // Test that `nothrow` works
+ bool didThrow = false;
+ int counter = 0;
+ struct NoThrow
+ {
+ int val;
+ this(this)
+ {
+ counter++;
+ }
+ }
+ try
+ {
+ NoThrow[4] a;
+ NoThrow[4] b = [NoThrow(1), NoThrow(2), NoThrow(3), NoThrow(4)];
+ _d_arrayassign_r(a[], b[]);
+ }
+ catch (Exception)
+ {
+ didThrow = false;
+ }
+ assert(!didThrow);
+ assert(counter == 0);
+}
diff --git a/libphobos/libdruntime/core/internal/array/duplication.d b/libphobos/libdruntime/core/internal/array/duplication.d
new file mode 100644
index 0000000..41dfab6
--- /dev/null
+++ b/libphobos/libdruntime/core/internal/array/duplication.d
@@ -0,0 +1,346 @@
+/**
+The `.dup` and `.idup` properties for Associative Arrays and Dynamic Arrays
+
+Copyright: Copyright Digital Mars 2000 - 2022.
+License: Distributed under the $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ (See accompanying file LICENSE)
+Source: $(DRUNTIMESRC core/internal/_array/_duplication.d)
+*/
+module core.internal.array.duplication;
+
+private extern (C) void[] _d_newarrayU(const scope TypeInfo ti, size_t length) pure nothrow;
+
+U[] _dup(T, U)(scope T[] a) pure nothrow @trusted if (__traits(isPOD, T))
+{
+ if (__ctfe)
+ return _dupCtfe!(T, U)(a);
+
+ import core.stdc.string : memcpy;
+ auto arr = _d_newarrayU(typeid(T[]), a.length);
+ memcpy(arr.ptr, cast(const(void)*) a.ptr, T.sizeof * a.length);
+ return *cast(U[]*) &arr;
+}
+
+U[] _dupCtfe(T, U)(scope T[] a)
+{
+ static if (is(T : void))
+ assert(0, "Cannot dup a void[] array at compile time.");
+ else
+ {
+ U[] res;
+ foreach (ref e; a)
+ res ~= e;
+ return res;
+ }
+}
+
+U[] _dup(T, U)(T[] a) if (!__traits(isPOD, T))
+{
+ // note: copyEmplace is `@system` inside a `@trusted` block, so the __ctfe branch
+ // has the extra duty to infer _dup `@system` when the copy-constructor is `@system`.
+ if (__ctfe)
+ return _dupCtfe!(T, U)(a);
+
+ import core.lifetime: copyEmplace;
+ U[] res = () @trusted {
+ auto arr = cast(U*) _d_newarrayU(typeid(T[]), a.length);
+ size_t i;
+ scope (failure)
+ {
+ import core.internal.lifetime: emplaceInitializer;
+ // Initialize all remaining elements to not destruct garbage
+ foreach (j; i .. a.length)
+ emplaceInitializer(cast() arr[j]);
+ }
+ for (; i < a.length; i++)
+ {
+ copyEmplace(a.ptr[i], arr[i]);
+ }
+ return cast(U[])(arr[0..a.length]);
+ } ();
+
+ return res;
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=22107
+@safe unittest
+{
+ static int i;
+ @safe struct S
+ {
+ this(this) { i++; }
+ }
+
+ void fun(scope S[] values...) @safe
+ {
+ values.dup;
+ }
+}
+
+@safe unittest
+{
+ static struct S1 { int* p; }
+ static struct S2 { @disable this(); }
+ static struct S3 { @disable this(this); }
+
+ int dg1() pure nothrow @safe
+ {
+ {
+ char[] m;
+ string i;
+ m = m.dup;
+ i = i.idup;
+ m = i.dup;
+ i = m.idup;
+ }
+ {
+ S1[] m;
+ immutable(S1)[] i;
+ m = m.dup;
+ i = i.idup;
+ static assert(!is(typeof(m.idup)));
+ static assert(!is(typeof(i.dup)));
+ }
+ {
+ S3[] m;
+ immutable(S3)[] i;
+ static assert(!is(typeof(m.dup)));
+ static assert(!is(typeof(i.idup)));
+ }
+ {
+ shared(S1)[] m;
+ m = m.dup;
+ static assert(!is(typeof(m.idup)));
+ }
+ {
+ int[] a = (inout(int)) { inout(const(int))[] a; return a.dup; }(0);
+ }
+ return 1;
+ }
+
+ int dg2() pure nothrow @safe
+ {
+ {
+ S2[] m = [S2.init, S2.init];
+ immutable(S2)[] i = [S2.init, S2.init];
+ m = m.dup;
+ m = i.dup;
+ i = m.idup;
+ i = i.idup;
+ }
+ return 2;
+ }
+
+ enum a = dg1();
+ enum b = dg2();
+ assert(dg1() == a);
+ assert(dg2() == b);
+}
+
+@system unittest
+{
+ static struct Sunpure { this(this) @safe nothrow {} }
+ static struct Sthrow { this(this) @safe pure {} }
+ static struct Sunsafe { this(this) @system pure nothrow {} }
+ static struct Snocopy { @disable this(this); }
+
+ [].dup!Sunpure;
+ [].dup!Sthrow;
+ cast(void) [].dup!Sunsafe;
+ static assert(!__traits(compiles, () pure { [].dup!Sunpure; }));
+ static assert(!__traits(compiles, () nothrow { [].dup!Sthrow; }));
+ static assert(!__traits(compiles, () @safe { [].dup!Sunsafe; }));
+ static assert(!__traits(compiles, () { [].dup!Snocopy; }));
+
+ [].idup!Sunpure;
+ [].idup!Sthrow;
+ [].idup!Sunsafe;
+ static assert(!__traits(compiles, () pure { [].idup!Sunpure; }));
+ static assert(!__traits(compiles, () nothrow { [].idup!Sthrow; }));
+ static assert(!__traits(compiles, () @safe { [].idup!Sunsafe; }));
+ static assert(!__traits(compiles, () { [].idup!Snocopy; }));
+}
+
+@safe unittest
+{
+ // test that the copy-constructor is called with .dup
+ static struct ArrElem
+ {
+ int a;
+ this(int a)
+ {
+ this.a = a;
+ }
+ this(ref const ArrElem)
+ {
+ a = 2;
+ }
+ this(ref ArrElem) immutable
+ {
+ a = 3;
+ }
+ }
+
+ auto arr = [ArrElem(1), ArrElem(1)];
+
+ ArrElem[] b = arr.dup;
+ assert(b[0].a == 2 && b[1].a == 2);
+
+ immutable ArrElem[] c = arr.idup;
+ assert(c[0].a == 3 && c[1].a == 3);
+}
+
+@system unittest
+{
+ static struct Sunpure { this(ref const typeof(this)) @safe nothrow {} }
+ static struct Sthrow { this(ref const typeof(this)) @safe pure {} }
+ static struct Sunsafe { this(ref const typeof(this)) @system pure nothrow {} }
+ [].dup!Sunpure;
+ [].dup!Sthrow;
+ cast(void) [].dup!Sunsafe;
+ static assert(!__traits(compiles, () pure { [].dup!Sunpure; }));
+ static assert(!__traits(compiles, () nothrow { [].dup!Sthrow; }));
+ static assert(!__traits(compiles, () @safe { [].dup!Sunsafe; }));
+
+ // for idup to work on structs that have copy constructors, it is necessary
+ // that the struct defines a copy constructor that creates immutable objects
+ static struct ISunpure { this(ref const typeof(this)) immutable @safe nothrow {} }
+ static struct ISthrow { this(ref const typeof(this)) immutable @safe pure {} }
+ static struct ISunsafe { this(ref const typeof(this)) immutable @system pure nothrow {} }
+ [].idup!ISunpure;
+ [].idup!ISthrow;
+ [].idup!ISunsafe;
+ static assert(!__traits(compiles, () pure { [].idup!ISunpure; }));
+ static assert(!__traits(compiles, () nothrow { [].idup!ISthrow; }));
+ static assert(!__traits(compiles, () @safe { [].idup!ISunsafe; }));
+}
+
+@safe unittest
+{
+ static int*[] pureFoo() pure { return null; }
+ { char[] s; immutable x = s.dup; }
+ { immutable x = (cast(int*[])null).dup; }
+ { immutable x = pureFoo(); }
+ { immutable x = pureFoo().dup; }
+}
+
+@safe unittest
+{
+ auto a = [1, 2, 3];
+ auto b = a.dup;
+ debug(SENTINEL) {} else
+ assert(b.capacity >= 3);
+}
+
+@system unittest
+{
+ // Bugzilla 12580
+ void[] m = [0];
+ shared(void)[] s = [cast(shared)1];
+ immutable(void)[] i = [cast(immutable)2];
+
+ s = s.dup;
+ static assert(is(typeof(s.dup) == shared(void)[]));
+
+ m = i.dup;
+ i = m.dup;
+ i = i.idup;
+ i = m.idup;
+ i = s.idup;
+ i = s.dup;
+ static assert(!__traits(compiles, m = s.dup));
+}
+
+@safe unittest
+{
+ // Bugzilla 13809
+ static struct S
+ {
+ this(this) {}
+ ~this() {}
+ }
+
+ S[] arr;
+ auto a = arr.dup;
+}
+
+@system unittest
+{
+ // Bugzilla 16504
+ static struct S
+ {
+ __gshared int* gp;
+ int* p;
+ // postblit and hence .dup could escape
+ this(this) { gp = p; }
+ }
+
+ int p;
+ scope S[1] arr = [S(&p)];
+ auto a = arr.dup; // dup does escape
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=21983
+// dup/idup destroys partially constructed arrays on failure
+@safe unittest
+{
+ static struct SImpl(bool postblit)
+ {
+ int num;
+ long l = 0xDEADBEEF;
+
+ static if (postblit)
+ {
+ this(this)
+ {
+ if (this.num == 3)
+ throw new Exception("");
+ }
+ }
+ else
+ {
+ this(scope ref const SImpl other)
+ {
+ if (other.num == 3)
+ throw new Exception("");
+
+ this.num = other.num;
+ this.l = other.l;
+ }
+ }
+
+ ~this() @trusted
+ {
+ if (l != 0xDEADBEEF)
+ {
+ import core.stdc.stdio;
+ printf("Unexpected value: %lld\n", l);
+ fflush(stdout);
+ assert(false);
+ }
+ }
+ }
+
+ alias Postblit = SImpl!true;
+ alias Copy = SImpl!false;
+
+ static int test(S)()
+ {
+ S[4] arr = [ S(1), S(2), S(3), S(4) ];
+ try
+ {
+ arr.dup();
+ assert(false);
+ }
+ catch (Exception)
+ {
+ return 1;
+ }
+ }
+
+ static assert(test!Postblit());
+ assert(test!Postblit());
+
+ static assert(test!Copy());
+ assert(test!Copy());
+}
diff --git a/libphobos/libdruntime/core/internal/array/equality.d b/libphobos/libdruntime/core/internal/array/equality.d
index d3fdd65..c110d64 100644
--- a/libphobos/libdruntime/core/internal/array/equality.d
+++ b/libphobos/libdruntime/core/internal/array/equality.d
@@ -236,6 +236,33 @@ unittest
static assert(!useMemcmp!(int[], int[]));
}
+// https://issues.dlang.org/show_bug.cgi?id=21094
+unittest
+{
+ static class C
+ {
+ int a;
+ }
+ static struct S
+ {
+ bool isValid;
+ C fib;
+
+ inout(C) get() pure @safe @nogc nothrow inout
+ {
+ return isValid ? fib : C.init;
+ }
+ T opCast(T : C)() const { return null; }
+
+ alias get this;
+ }
+
+ auto foo(S[] lhs, S[] rhs)
+ {
+ return lhs == rhs;
+ }
+}
+
// Returns a reference to an array element, eliding bounds check and
// casting void to ubyte.
pragma(inline, true)
diff --git a/libphobos/libdruntime/core/internal/dassert.d b/libphobos/libdruntime/core/internal/dassert.d
index 2c51b86..07486c2 100644
--- a/libphobos/libdruntime/core/internal/dassert.d
+++ b/libphobos/libdruntime/core/internal/dassert.d
@@ -14,7 +14,7 @@
*
* Copyright: D Language Foundation 2018 - 2020
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
- * Source: $(LINK2 https://github.com/dlang/druntime/blob/master/src/core/internal/dassert.d, _dassert.d)
+ * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/druntime/src/core/internal/dassert.d, _dassert.d)
* Documentation: https://dlang.org/phobos/core_internal_dassert.html
*/
module core.internal.dassert;
diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d
index d1378af..75e671c 100644
--- a/libphobos/libdruntime/core/runtime.d
+++ b/libphobos/libdruntime/core/runtime.d
@@ -4,7 +4,7 @@
* Copyright: Copyright Sean Kelly 2005 - 2009.
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Authors: Sean Kelly
- * Source: $(LINK2 https://github.com/dlang/druntime/blob/master/src/core/runtime.d, _runtime.d)
+ * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/druntime/src/core/runtime.d, _runtime.d)
* Documentation: https://dlang.org/phobos/core_runtime.html
*/
diff --git a/libphobos/libdruntime/core/stdc/errno.d b/libphobos/libdruntime/core/stdc/errno.d
index 24b4138..c992a5f 100644
--- a/libphobos/libdruntime/core/stdc/errno.d
+++ b/libphobos/libdruntime/core/stdc/errno.d
@@ -8,7 +8,7 @@
* $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
* (See accompanying file LICENSE)
* Authors: Sean Kelly, Alex Rønne Petersen
- * Source: https://github.com/dlang/druntime/blob/master/src/core/stdc/errno.d
+ * Source: https://github.com/dlang/dmd/blob/master/druntime/src/core/stdc/errno.d
* Standards: ISO/IEC 9899:1999 (E)
*/
diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d
index 2e83811..fc98350 100644
--- a/libphobos/libdruntime/core/stdc/stdio.d
+++ b/libphobos/libdruntime/core/stdc/stdio.d
@@ -9,7 +9,7 @@
* (See accompanying file LICENSE)
* Authors: Sean Kelly,
* Alex Rønne Petersen
- * Source: https://github.com/dlang/druntime/blob/master/src/core/stdc/stdio.d
+ * Source: https://github.com/dlang/dmd/blob/master/druntime/src/core/stdc/stdio.d
* Standards: ISO/IEC 9899:1999 (E)
*/
@@ -1286,6 +1286,57 @@ version (MinGW)
///
alias __mingw_scanf scanf;
}
+else version (CRuntime_Glibc)
+{
+ ///
+ pragma(printf)
+ int fprintf(FILE* stream, scope const char* format, scope const ...);
+ ///
+ pragma(scanf)
+ int __isoc99_fscanf(FILE* stream, scope const char* format, scope ...);
+ ///
+ alias fscanf = __isoc99_fscanf;
+ ///
+ pragma(printf)
+ int sprintf(scope char* s, scope const char* format, scope const ...);
+ ///
+ pragma(scanf)
+ int __isoc99_sscanf(scope const char* s, scope const char* format, scope ...);
+ ///
+ alias sscanf = __isoc99_sscanf;
+ ///
+ pragma(printf)
+ int vfprintf(FILE* stream, scope const char* format, va_list arg);
+ ///
+ pragma(scanf)
+ int __isoc99_vfscanf(FILE* stream, scope const char* format, va_list arg);
+ ///
+ alias vfscanf = __isoc99_vfscanf;
+ ///
+ pragma(printf)
+ int vsprintf(scope char* s, scope const char* format, va_list arg);
+ ///
+ pragma(scanf)
+ int __isoc99_vsscanf(scope const char* s, scope const char* format, va_list arg);
+ ///
+ alias vsscanf = __isoc99_vsscanf;
+ ///
+ pragma(printf)
+ int vprintf(scope const char* format, va_list arg);
+ ///
+ pragma(scanf)
+ int __isoc99_vscanf(scope const char* format, va_list arg);
+ ///
+ alias vscanf = __isoc99_vscanf;
+ ///
+ pragma(printf)
+ int printf(scope const char* format, scope const ...);
+ ///
+ pragma(scanf)
+ int __isoc99_scanf(scope const char* format, scope ...);
+ ///
+ alias scanf = __isoc99_scanf;
+}
else
{
///
diff --git a/libphobos/libdruntime/core/stdc/wchar_.d b/libphobos/libdruntime/core/stdc/wchar_.d
index e8fb94b..d087029 100644
--- a/libphobos/libdruntime/core/stdc/wchar_.d
+++ b/libphobos/libdruntime/core/stdc/wchar_.d
@@ -127,30 +127,72 @@ alias wchar_t wint_t;
///
enum wchar_t WEOF = 0xFFFF;
-///
-int fwprintf(FILE* stream, const scope wchar_t* format, scope const ...);
-///
-int fwscanf(FILE* stream, const scope wchar_t* format, scope ...);
-///
-int swprintf(wchar_t* s, size_t n, const scope wchar_t* format, scope const ...);
-///
-int swscanf(const scope wchar_t* s, const scope wchar_t* format, scope ...);
-///
-int vfwprintf(FILE* stream, const scope wchar_t* format, va_list arg);
-///
-int vfwscanf(FILE* stream, const scope wchar_t* format, va_list arg);
-///
-int vswprintf(wchar_t* s, size_t n, const scope wchar_t* format, va_list arg);
-///
-int vswscanf(const scope wchar_t* s, const scope wchar_t* format, va_list arg);
-///
-int vwprintf(const scope wchar_t* format, va_list arg);
-///
-int vwscanf(const scope wchar_t* format, va_list arg);
-///
-int wprintf(const scope wchar_t* format, scope const ...);
-///
-int wscanf(const scope wchar_t* format, scope ...);
+version (CRuntime_Glibc)
+{
+ ///
+ int fwprintf(FILE* stream, const scope wchar_t* format, scope const ...);
+ ///
+ int __isoc99_fwscanf(FILE* stream, const scope wchar_t* format, scope ...);
+ ///
+ alias fwscanf = __isoc99_fwscanf;
+ ///
+ int swprintf(wchar_t* s, size_t n, const scope wchar_t* format, scope const ...);
+ ///
+ int __isoc99_swscanf(const scope wchar_t* s, const scope wchar_t* format, scope ...);
+ ///
+ alias swscanf = __isoc99_swscanf;
+ ///
+ int vfwprintf(FILE* stream, const scope wchar_t* format, va_list arg);
+ ///
+ int __isoc99_vfwscanf(FILE* stream, const scope wchar_t* format, va_list arg);
+ ///
+ alias vfwscanf = __isoc99_vfwscanf;
+ ///
+ int vswprintf(wchar_t* s, size_t n, const scope wchar_t* format, va_list arg);
+ ///
+ int __isoc99_vswscanf(const scope wchar_t* s, const scope wchar_t* format, va_list arg);
+ ///
+ alias vswscanf = __isoc99_vswscanf;
+ ///
+ int vwprintf(const scope wchar_t* format, va_list arg);
+ ///
+ int __isoc99_vwscanf(const scope wchar_t* format, va_list arg);
+ ///
+ alias vwscanf = __isoc99_vwscanf;
+ ///
+ int wprintf(const scope wchar_t* format, scope const ...);
+ ///
+ int __isoc99_wscanf(const scope wchar_t* format, scope ...);
+ ///
+ alias wscanf = __isoc99_wscanf;
+}
+else
+{
+ ///
+ int fwprintf(FILE* stream, const scope wchar_t* format, scope const ...);
+ ///
+ int fwscanf(FILE* stream, const scope wchar_t* format, scope ...);
+ ///
+ int swprintf(wchar_t* s, size_t n, const scope wchar_t* format, scope const ...);
+ ///
+ int swscanf(const scope wchar_t* s, const scope wchar_t* format, scope ...);
+ ///
+ int vfwprintf(FILE* stream, const scope wchar_t* format, va_list arg);
+ ///
+ int vfwscanf(FILE* stream, const scope wchar_t* format, va_list arg);
+ ///
+ int vswprintf(wchar_t* s, size_t n, const scope wchar_t* format, va_list arg);
+ ///
+ int vswscanf(const scope wchar_t* s, const scope wchar_t* format, va_list arg);
+ ///
+ int vwprintf(const scope wchar_t* format, va_list arg);
+ ///
+ int vwscanf(const scope wchar_t* format, va_list arg);
+ ///
+ int wprintf(const scope wchar_t* format, scope const ...);
+ ///
+ int wscanf(const scope wchar_t* format, scope ...);
+}
// No unsafe pointer manipulation.
@trusted
diff --git a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d
index fd1a8e4..dc42a2d 100644
--- a/libphobos/libdruntime/core/sys/darwin/mach/getsect.d
+++ b/libphobos/libdruntime/core/sys/darwin/mach/getsect.d
@@ -468,4 +468,3 @@ const(section)* getsectbynamefromheaderwithswap_64(
const scope char* section,
int fSwap
);
-
diff --git a/libphobos/libdruntime/core/sys/dragonflybsd/string.d b/libphobos/libdruntime/core/sys/dragonflybsd/string.d
index 4b84227..1a85ba6 100644
--- a/libphobos/libdruntime/core/sys/dragonflybsd/string.d
+++ b/libphobos/libdruntime/core/sys/dragonflybsd/string.d
@@ -19,4 +19,3 @@ static if (__BSD_VISIBLE)
{
pure void* memmem(return scope const void* haystack, size_t haystacklen, scope const void* needle, size_t needlelen);
}
-
diff --git a/libphobos/libdruntime/core/sys/linux/sys/time.d b/libphobos/libdruntime/core/sys/linux/sys/time.d
index 6ea626e..4b56229 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/time.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/time.d
@@ -65,4 +65,3 @@ extern (D) pure @safe @nogc nothrow {
}
}
-
diff --git a/libphobos/libdruntime/core/sys/linux/sys/xattr.d b/libphobos/libdruntime/core/sys/linux/sys/xattr.d
index 2f8d3f3..6446ff8 100644
--- a/libphobos/libdruntime/core/sys/linux/sys/xattr.d
+++ b/libphobos/libdruntime/core/sys/linux/sys/xattr.d
@@ -66,4 +66,3 @@ ssize_t flistxattr (int __fd, char *list, size_t size);
int removexattr (const scope char *path, const scope char *name);
int lremovexattr (const scope char *path, const scope char *name);
int fremovexattr (int fd, const scope char *name);
-
diff --git a/libphobos/libdruntime/core/sys/linux/tipc.d b/libphobos/libdruntime/core/sys/linux/tipc.d
index 3246e62..4d5d886 100644
--- a/libphobos/libdruntime/core/sys/linux/tipc.d
+++ b/libphobos/libdruntime/core/sys/linux/tipc.d
@@ -208,4 +208,3 @@ enum: int
TIPC_DEST_DROPPABLE = 129,
TIPC_CONN_TIMEOUT = 130,
}
-
diff --git a/libphobos/libdruntime/core/sys/posix/signal.d b/libphobos/libdruntime/core/sys/posix/signal.d
index 68aee98..542e83a 100644
--- a/libphobos/libdruntime/core/sys/posix/signal.d
+++ b/libphobos/libdruntime/core/sys/posix/signal.d
@@ -14,7 +14,7 @@ module core.sys.posix.signal;
import core.sys.posix.config;
public import core.stdc.signal;
public import core.sys.posix.sys.types; // for pid_t
-//public import core.sys.posix.time; // for timespec, now defined here
+public import core.sys.posix.time; // for timespec
version (OSX)
version = Darwin;
@@ -2805,83 +2805,6 @@ else
}
//
-// Timer (TMR)
-//
-/*
-NOTE: This should actually be defined in core.sys.posix.time.
- It is defined here instead to break a circular import.
-
-struct timespec
-{
- time_t tv_sec;
- int tv_nsec;
-}
-*/
-
-version (linux)
-{
- struct timespec
- {
- time_t tv_sec;
- c_long tv_nsec;
- }
-}
-else version (Darwin)
-{
- struct timespec
- {
- time_t tv_sec;
- c_long tv_nsec;
- }
-}
-else version (FreeBSD)
-{
- struct timespec
- {
- time_t tv_sec;
- c_long tv_nsec;
- }
-}
-else version (NetBSD)
-{
- struct timespec
- {
- time_t tv_sec;
- c_long tv_nsec;
- }
-}
-else version (OpenBSD)
-{
- struct timespec
- {
- time_t tv_sec;
- c_long tv_nsec;
- }
-}
-else version (DragonFlyBSD)
-{
- struct timespec
- {
- time_t tv_sec;
- c_long tv_nsec;
- }
-}
-else version (Solaris)
-{
- struct timespec
- {
- time_t tv_sec;
- c_long tv_nsec;
- }
-
- alias timespec timestruc_t;
-}
-else
-{
- static assert(false, "Unsupported platform");
-}
-
-//
// Realtime Signals (RTS)
//
/*
diff --git a/libphobos/libdruntime/core/sys/posix/spawn.d b/libphobos/libdruntime/core/sys/posix/spawn.d
index cfa3a40..2064962 100644
--- a/libphobos/libdruntime/core/sys/posix/spawn.d
+++ b/libphobos/libdruntime/core/sys/posix/spawn.d
@@ -4,7 +4,7 @@
* Copyright: Copyright (C) 2018 by The D Language Foundation, All Rights Reserved
* Authors: Petar Kirov
* License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
- * Source: $(LINK2 https://github.com/dlang/druntime/blob/master/src/core/sys/posix/spawn.d, _spawn.d)
+ * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/druntime/src/core/sys/posix/spawn.d, _spawn.d)
* Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
*/
module core.sys.posix.spawn;
diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d
index 077838d..d0d3d60 100644
--- a/libphobos/libdruntime/core/sys/posix/stdio.d
+++ b/libphobos/libdruntime/core/sys/posix/stdio.d
@@ -487,7 +487,7 @@ else version (CRuntime_Musl)
version (HaveMemstream)
{
- FILE* fmemopen(const scope void* buf, in size_t size, const scope char* mode);
+ FILE* fmemopen(const scope void* buf, size_t size, const scope char* mode);
FILE* open_memstream(char** ptr, size_t* sizeloc);
version (CRuntime_UClibc) {} else
FILE* open_wmemstream(wchar_t** ptr, size_t* sizeloc);
diff --git a/libphobos/libdruntime/core/sys/posix/sys/select.d b/libphobos/libdruntime/core/sys/posix/sys/select.d
index 2a659c3..925976d 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/select.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/select.d
@@ -608,4 +608,3 @@ pure unittest
assert(!FD_ISSET(i, &fd));
}
}
-
diff --git a/libphobos/libdruntime/core/sys/posix/sys/socket.d b/libphobos/libdruntime/core/sys/posix/sys/socket.d
index 3a7b753..fc5dc5d 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/socket.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/socket.d
@@ -188,10 +188,40 @@ version (linux)
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;
- extern (D) inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc
+ version (CRuntime_Musl)
{
- return __cmsg_nxthdr(msg, cmsg);
+ extern (D)
+ {
+ private size_t __CMSG_LEN(inout(cmsghdr)* cmsg) pure nothrow @nogc
+ {
+ return (cmsg.cmsg_len + size_t.sizeof -1) & cast(size_t)(~(size_t.sizeof - 1));
+ }
+
+ private inout(cmsghdr)* __CMSG_NEXT(inout(cmsghdr)* cmsg) pure nothrow @nogc
+ {
+ return cmsg + __CMSG_LEN(cmsg);
+ }
+
+ private inout(msghdr)* __MHDR_END(inout(msghdr)* mhdr) pure nothrow @nogc
+ {
+ return cast(inout(msghdr)*)(mhdr.msg_control + mhdr.msg_controllen);
+ }
+
+ inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc
+ {
+ return cmsg.cmsg_len < cmsghdr.sizeof ||
+ __CMSG_LEN(cmsg) + cmsghdr.sizeof >= __MHDR_END(msg) - cast(inout(msghdr)*)(cmsg)
+ ? cast(inout(cmsghdr)*) null : cast(inout(cmsghdr)*) __CMSG_NEXT(cmsg);
+ }
+ }
+ }
+ else
+ {
+ private inout(cmsghdr)* __cmsg_nxthdr(inout(msghdr)*, inout(cmsghdr)*) pure nothrow @nogc;
+ extern (D) inout(cmsghdr)* CMSG_NXTHDR(inout(msghdr)* msg, inout(cmsghdr)* cmsg) pure nothrow @nogc
+ {
+ return __cmsg_nxthdr(msg, cmsg);
+ }
}
extern (D) inout(cmsghdr)* CMSG_FIRSTHDR( inout(msghdr)* mhdr ) pure nothrow @nogc
diff --git a/libphobos/libdruntime/core/sys/posix/time.d b/libphobos/libdruntime/core/sys/posix/time.d
index a9be87c8..ff3a3c4 100644
--- a/libphobos/libdruntime/core/sys/posix/time.d
+++ b/libphobos/libdruntime/core/sys/posix/time.d
@@ -167,9 +167,6 @@ else
CLOCK_PROCESS_CPUTIME_ID (TMR|CPT)
CLOCK_THREAD_CPUTIME_ID (TMR|TCT)
-NOTE: timespec must be defined in core.sys.posix.signal to break
- a circular import.
-
struct timespec
{
time_t tv_sec;
@@ -199,6 +196,69 @@ int timer_getoverrun(timer_t);
int timer_settime(timer_t, int, const scope itimerspec*, itimerspec*);
*/
+version (linux)
+{
+ struct timespec
+ {
+ time_t tv_sec;
+ c_long tv_nsec;
+ }
+}
+else version (Darwin)
+{
+ struct timespec
+ {
+ time_t tv_sec;
+ c_long tv_nsec;
+ }
+}
+else version (FreeBSD)
+{
+ struct timespec
+ {
+ time_t tv_sec;
+ c_long tv_nsec;
+ }
+}
+else version (NetBSD)
+{
+ struct timespec
+ {
+ time_t tv_sec;
+ c_long tv_nsec;
+ }
+}
+else version (OpenBSD)
+{
+ struct timespec
+ {
+ time_t tv_sec;
+ c_long tv_nsec;
+ }
+}
+else version (DragonFlyBSD)
+{
+ struct timespec
+ {
+ time_t tv_sec;
+ c_long tv_nsec;
+ }
+}
+else version (Solaris)
+{
+ struct timespec
+ {
+ time_t tv_sec;
+ c_long tv_nsec;
+ }
+
+ alias timespec timestruc_t;
+}
+else
+{
+ static assert(false, "Unsupported platform");
+}
+
version (CRuntime_Glibc)
{
enum CLOCK_PROCESS_CPUTIME_ID = 2;
diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d
index 20297f5..e8c2f87 100644
--- a/libphobos/libdruntime/core/sys/posix/ucontext.d
+++ b/libphobos/libdruntime/core/sys/posix/ucontext.d
@@ -1628,4 +1628,3 @@ version (Solaris)
int addrtosymstr(uintptr_t, char*, int);
int printstack(int);
}
-
diff --git a/libphobos/libdruntime/core/sys/solaris/sys/priocntl.d b/libphobos/libdruntime/core/sys/solaris/sys/priocntl.d
index bfbf3ee..c56be3b 100644
--- a/libphobos/libdruntime/core/sys/solaris/sys/priocntl.d
+++ b/libphobos/libdruntime/core/sys/solaris/sys/priocntl.d
@@ -113,4 +113,3 @@ struct pcadmin_t
id_t pc_cid;
caddr_t pc_cladmin;
}
-
diff --git a/libphobos/libdruntime/core/sys/solaris/sys/procset.d b/libphobos/libdruntime/core/sys/solaris/sys/procset.d
index 43fa997..8bd9115 100644
--- a/libphobos/libdruntime/core/sys/solaris/sys/procset.d
+++ b/libphobos/libdruntime/core/sys/solaris/sys/procset.d
@@ -50,4 +50,3 @@ void setprocset(ref procset_t psp, idop_t op, idtype_t ltype, id_t lid, idtype_t
psp.p_ridtype = rtype;
psp.p_rid = rid;
}
-
diff --git a/libphobos/libdruntime/core/sys/windows/cguid.d b/libphobos/libdruntime/core/sys/windows/cguid.d
index 0afbc42..d0a8fb9 100644
--- a/libphobos/libdruntime/core/sys/windows/cguid.d
+++ b/libphobos/libdruntime/core/sys/windows/cguid.d
@@ -10,4 +10,3 @@ module core.sys.windows.cguid;
version (Windows):
import core.sys.windows.basetyps;
-
diff --git a/libphobos/libdruntime/core/sys/windows/ntsecpkg.d b/libphobos/libdruntime/core/sys/windows/ntsecpkg.d
index d4c93d7..d8c5e95 100644
--- a/libphobos/libdruntime/core/sys/windows/ntsecpkg.d
+++ b/libphobos/libdruntime/core/sys/windows/ntsecpkg.d
@@ -444,4 +444,3 @@ alias NTSTATUS function(ULONG, PULONG,
PSECPKG_FUNCTION_TABLE *, PULONG) SpLsaModeInitializeFn;
alias NTSTATUS function(ULONG, PULONG,
PSECPKG_USER_FUNCTION_TABLE *, PULONG) SpUserModeInitializeFn;
-
diff --git a/libphobos/libdruntime/core/sys/windows/olectlid.d b/libphobos/libdruntime/core/sys/windows/olectlid.d
index 8bbe657..b58c14a 100644
--- a/libphobos/libdruntime/core/sys/windows/olectlid.d
+++ b/libphobos/libdruntime/core/sys/windows/olectlid.d
@@ -10,4 +10,3 @@ module core.sys.windows.olectlid;
version (Windows):
import core.sys.windows.basetyps;
-
diff --git a/libphobos/libdruntime/core/sys/windows/shlguid.d b/libphobos/libdruntime/core/sys/windows/shlguid.d
index 1c0c98f..e0c1af1 100644
--- a/libphobos/libdruntime/core/sys/windows/shlguid.d
+++ b/libphobos/libdruntime/core/sys/windows/shlguid.d
@@ -16,4 +16,3 @@ import core.sys.windows.basetyps, core.sys.windows.w32api;
// I think this is just a helper macro for other win32 headers?
//MACRO #define DEFINE_SHLGUID(n,l,w1,w2) DEFINE_GUID(n,l,w1,w2,0xC0,0,0,0,0,0,0,0x46)
-
diff --git a/libphobos/libdruntime/core/sys/windows/sspi.d b/libphobos/libdruntime/core/sys/windows/sspi.d
index 07a2596..21e982d 100644
--- a/libphobos/libdruntime/core/sys/windows/sspi.d
+++ b/libphobos/libdruntime/core/sys/windows/sspi.d
@@ -380,4 +380,3 @@ version (Unicode) {
alias QUERY_SECURITY_PACKAGE_INFO_FN_A QUERY_SECURITY_PACKAGE_INFO_FN;
alias INIT_SECURITY_INTERFACE_A INIT_SECURITY_INTERFACE;
}
-
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index fe65c09..d842499 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -6,6 +6,7 @@
* $(TR $(TD Arrays) $(TD
* $(MYREF assumeSafeAppend)
* $(MYREF capacity)
+ * $(A #.dup.2, $(TT dup))
* $(MYREF idup)
* $(MYREF reserve)
* ))
@@ -14,6 +15,7 @@
* $(MYREF byKeyValue)
* $(MYREF byValue)
* $(MYREF clear)
+ * $(MYREF dup)
* $(MYREF get)
* $(MYREF keys)
* $(MYREF rehash)
@@ -23,15 +25,15 @@
* ))
* $(TR $(TD General) $(TD
* $(MYREF destroy)
- * $(MYREF dup)
* $(MYREF hashOf)
- * $(MYREF opEquals)
+ * $(MYREF imported)
+ * $(MYREF noreturn)
* ))
- * $(TR $(TD Types) $(TD
+ * $(TR $(TD Classes) $(TD
* $(MYREF Error)
* $(MYREF Exception)
- * $(MYREF noreturn)
* $(MYREF Object)
+ * $(MYREF opEquals)
* $(MYREF Throwable)
* ))
* $(TR $(TD Type info) $(TD
@@ -61,7 +63,11 @@ alias size_t = typeof(int.sizeof);
alias ptrdiff_t = typeof(cast(void*)0 - cast(void*)0);
alias sizediff_t = ptrdiff_t; // For backwards compatibility only.
-alias noreturn = typeof(*null); /// bottom type
+/**
+ * Bottom type.
+ * See $(DDSUBLINK spec/type, noreturn).
+ */
+alias noreturn = typeof(*null);
alias hash_t = size_t; // For backwards compatibility only.
alias equals_t = bool; // For backwards compatibility only.
@@ -266,7 +272,9 @@ class Object
the typeinfo name string compare. This is because of dmd's dll implementation. However,
it can infer to @safe if your class' opEquals is.
+/
-bool opEquals(LHS, RHS)(LHS lhs, RHS rhs) if (is(LHS : const Object) && is(RHS : const Object))
+bool opEquals(LHS, RHS)(LHS lhs, RHS rhs)
+if ((is(LHS : const Object) || is(LHS : const shared Object)) &&
+ (is(RHS : const Object) || is(RHS : const shared Object)))
{
static if (__traits(compiles, lhs.opEquals(rhs)) && __traits(compiles, rhs.opEquals(lhs)))
{
@@ -505,6 +513,16 @@ unittest
assert(obj1 != obj2);
}
+// https://issues.dlang.org/show_bug.cgi?id=23291
+@system unittest
+{
+ static shared class C { bool opEquals(const(shared(C)) rhs) const shared { return true;}}
+ const(C) c = new C();
+ const(C)[] a = [c];
+ const(C)[] b = [c];
+ assert(a[0] == b[0]);
+}
+
private extern(C) void _d_setSameMutex(shared Object ownee, shared Object owner) nothrow;
void setSameMutex(shared Object ownee, shared Object owner)
@@ -3473,13 +3491,18 @@ ref V require(K, V)(ref V[K] aa, K key, lazy V value = V.init)
private enum bool isSafeCopyable(T) = is(typeof(() @safe { union U { T x; } T *x; auto u = U(*x); }));
/***********************************
- * Looks up key; if it exists applies the update callable else evaluates the
- * create callable and adds it to the associative array
+ * Calls `create` if `key` doesn't exist in the associative array,
+ * otherwise calls `update`.
+ * `create` returns a corresponding value for `key`.
+ * `update` accepts a key parameter. If it returns a value, the value is
+ * set for `key`.
* Params:
* aa = The associative array.
* key = The key.
- * create = The callable to apply on create.
- * update = The callable to apply on update.
+ * create = The callable to create a value for `key`.
+ * Must return V.
+ * update = The callable to call if `key` exists.
+ * Takes a K argument, returns a V or void.
*/
void update(K, V, C, U)(ref V[K] aa, K key, scope C create, scope U update)
if (is(typeof(create()) : V) && (is(typeof(update(aa[K.init])) : V) || is(typeof(update(aa[K.init])) == void)))
@@ -3509,23 +3532,39 @@ if (is(typeof(create()) : V) && (is(typeof(update(aa[K.init])) : V) || is(typeof
}
///
-@system unittest
+@safe unittest
{
- auto aa = ["k1": 1];
+ int[string] aa;
- aa.update("k1", {
- return -1; // create (won't be executed)
- }, (ref int v) {
- v += 1; // update
- });
- assert(aa["k1"] == 2);
-
- aa.update("k2", {
- return 0; // create
- }, (ref int v) {
- v = -1; // update (won't be executed)
- });
- assert(aa["k2"] == 0);
+ // create
+ aa.update("key",
+ () => 1,
+ (int) {} // not executed
+ );
+ assert(aa["key"] == 1);
+
+ // update value by ref
+ aa.update("key",
+ () => 0, // not executed
+ (ref int v) {
+ v += 1;
+ });
+ assert(aa["key"] == 2);
+
+ // update from return value
+ aa.update("key",
+ () => 0, // not executed
+ (int v) => v * 2
+ );
+ assert(aa["key"] == 4);
+
+ // 'update' without changing value
+ aa.update("key",
+ () => 0, // not executed
+ (int) {
+ // do something else
+ });
+ assert(aa["key"] == 4);
}
@safe unittest
@@ -3765,6 +3804,7 @@ private size_t getArrayHash(const scope TypeInfo element, const scope void* ptr,
if (!is(const(T) : T))
{
import core.internal.traits : Unconst;
+ import core.internal.array.duplication : _dup;
static assert(is(T : Unconst!T), "Cannot implicitly convert type "~T.stringof~
" to "~Unconst!T.stringof~" in dup.");
@@ -3786,6 +3826,7 @@ private size_t getArrayHash(const scope TypeInfo element, const scope void* ptr,
@property T[] dup(T)(const(T)[] a)
if (is(const(T) : T))
{
+ import core.internal.array.duplication : _dup;
return _dup!(const(T), T)(a);
}
@@ -3793,6 +3834,7 @@ private size_t getArrayHash(const scope TypeInfo element, const scope void* ptr,
/// Provide the .idup array property.
@property immutable(T)[] idup(T)(T[] a)
{
+ import core.internal.array.duplication : _dup;
static assert(is(T : immutable(T)), "Cannot implicitly convert type "~T.stringof~
" to immutable in idup.");
return _dup!(T, immutable(T))(a);
@@ -3813,73 +3855,6 @@ private size_t getArrayHash(const scope TypeInfo element, const scope void* ptr,
assert(s == "abc");
}
-private U[] _dup(T, U)(scope T[] a) pure nothrow @trusted if (__traits(isPOD, T))
-{
- if (__ctfe)
- return _dupCtfe!(T, U)(a);
-
- import core.stdc.string : memcpy;
- auto arr = _d_newarrayU(typeid(T[]), a.length);
- memcpy(arr.ptr, cast(const(void)*) a.ptr, T.sizeof * a.length);
- return *cast(U[]*) &arr;
-}
-
-private U[] _dupCtfe(T, U)(scope T[] a)
-{
- static if (is(T : void))
- assert(0, "Cannot dup a void[] array at compile time.");
- else
- {
- U[] res;
- foreach (ref e; a)
- res ~= e;
- return res;
- }
-}
-
-private U[] _dup(T, U)(T[] a) if (!__traits(isPOD, T))
-{
- // note: copyEmplace is `@system` inside a `@trusted` block, so the __ctfe branch
- // has the extra duty to infer _dup `@system` when the copy-constructor is `@system`.
- if (__ctfe)
- return _dupCtfe!(T, U)(a);
-
- import core.lifetime: copyEmplace;
- U[] res = () @trusted {
- auto arr = cast(U*) _d_newarrayU(typeid(T[]), a.length);
- size_t i;
- scope (failure)
- {
- import core.internal.lifetime: emplaceInitializer;
- // Initialize all remaining elements to not destruct garbage
- foreach (j; i .. a.length)
- emplaceInitializer(cast() arr[j]);
- }
- for (; i < a.length; i++)
- {
- copyEmplace(a.ptr[i], arr[i]);
- }
- return cast(U[])(arr[0..a.length]);
- } ();
-
- return res;
-}
-
-// https://issues.dlang.org/show_bug.cgi?id=22107
-@safe unittest
-{
- static int i;
- @safe struct S
- {
- this(this) { i++; }
- }
-
- void fun(scope S[] values...) @safe
- {
- values.dup;
- }
-}
-
// HACK: This is a lie. `_d_arraysetcapacity` is neither `nothrow` nor `pure`, but this lie is
// necessary for now to prevent breaking code.
private extern (C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* arrptr) pure nothrow;
@@ -4067,8 +4042,6 @@ auto ref inout(T[]) assumeSafeAppend(T)(auto ref inout(T[]) arr) nothrow @system
assert(is(typeof(b3) == immutable(int[])));
}
-private extern (C) void[] _d_newarrayU(const scope TypeInfo ti, size_t length) pure nothrow;
-
private void _doPostblit(T)(T[] arr)
{
// infer static postblit type, run postblit if any
@@ -4085,274 +4058,6 @@ private void _doPostblit(T)(T[] arr)
}
}
-@safe unittest
-{
- static struct S1 { int* p; }
- static struct S2 { @disable this(); }
- static struct S3 { @disable this(this); }
-
- int dg1() pure nothrow @safe
- {
- {
- char[] m;
- string i;
- m = m.dup;
- i = i.idup;
- m = i.dup;
- i = m.idup;
- }
- {
- S1[] m;
- immutable(S1)[] i;
- m = m.dup;
- i = i.idup;
- static assert(!is(typeof(m.idup)));
- static assert(!is(typeof(i.dup)));
- }
- {
- S3[] m;
- immutable(S3)[] i;
- static assert(!is(typeof(m.dup)));
- static assert(!is(typeof(i.idup)));
- }
- {
- shared(S1)[] m;
- m = m.dup;
- static assert(!is(typeof(m.idup)));
- }
- {
- int[] a = (inout(int)) { inout(const(int))[] a; return a.dup; }(0);
- }
- return 1;
- }
-
- int dg2() pure nothrow @safe
- {
- {
- S2[] m = [S2.init, S2.init];
- immutable(S2)[] i = [S2.init, S2.init];
- m = m.dup;
- m = i.dup;
- i = m.idup;
- i = i.idup;
- }
- return 2;
- }
-
- enum a = dg1();
- enum b = dg2();
- assert(dg1() == a);
- assert(dg2() == b);
-}
-
-@system unittest
-{
- static struct Sunpure { this(this) @safe nothrow {} }
- static struct Sthrow { this(this) @safe pure {} }
- static struct Sunsafe { this(this) @system pure nothrow {} }
- static struct Snocopy { @disable this(this); }
-
- [].dup!Sunpure;
- [].dup!Sthrow;
- cast(void) [].dup!Sunsafe;
- static assert(!__traits(compiles, () pure { [].dup!Sunpure; }));
- static assert(!__traits(compiles, () nothrow { [].dup!Sthrow; }));
- static assert(!__traits(compiles, () @safe { [].dup!Sunsafe; }));
- static assert(!__traits(compiles, () { [].dup!Snocopy; }));
-
- [].idup!Sunpure;
- [].idup!Sthrow;
- [].idup!Sunsafe;
- static assert(!__traits(compiles, () pure { [].idup!Sunpure; }));
- static assert(!__traits(compiles, () nothrow { [].idup!Sthrow; }));
- static assert(!__traits(compiles, () @safe { [].idup!Sunsafe; }));
- static assert(!__traits(compiles, () { [].idup!Snocopy; }));
-}
-
-@safe unittest
-{
- // test that the copy-constructor is called with .dup
- static struct ArrElem
- {
- int a;
- this(int a)
- {
- this.a = a;
- }
- this(ref const ArrElem)
- {
- a = 2;
- }
- this(ref ArrElem) immutable
- {
- a = 3;
- }
- }
-
- auto arr = [ArrElem(1), ArrElem(1)];
-
- ArrElem[] b = arr.dup;
- assert(b[0].a == 2 && b[1].a == 2);
-
- immutable ArrElem[] c = arr.idup;
- assert(c[0].a == 3 && c[1].a == 3);
-}
-
-@system unittest
-{
- static struct Sunpure { this(ref const typeof(this)) @safe nothrow {} }
- static struct Sthrow { this(ref const typeof(this)) @safe pure {} }
- static struct Sunsafe { this(ref const typeof(this)) @system pure nothrow {} }
- [].dup!Sunpure;
- [].dup!Sthrow;
- cast(void) [].dup!Sunsafe;
- static assert(!__traits(compiles, () pure { [].dup!Sunpure; }));
- static assert(!__traits(compiles, () nothrow { [].dup!Sthrow; }));
- static assert(!__traits(compiles, () @safe { [].dup!Sunsafe; }));
-
- // for idup to work on structs that have copy constructors, it is necessary
- // that the struct defines a copy constructor that creates immutable objects
- static struct ISunpure { this(ref const typeof(this)) immutable @safe nothrow {} }
- static struct ISthrow { this(ref const typeof(this)) immutable @safe pure {} }
- static struct ISunsafe { this(ref const typeof(this)) immutable @system pure nothrow {} }
- [].idup!ISunpure;
- [].idup!ISthrow;
- [].idup!ISunsafe;
- static assert(!__traits(compiles, () pure { [].idup!ISunpure; }));
- static assert(!__traits(compiles, () nothrow { [].idup!ISthrow; }));
- static assert(!__traits(compiles, () @safe { [].idup!ISunsafe; }));
-}
-
-@safe unittest
-{
- static int*[] pureFoo() pure { return null; }
- { char[] s; immutable x = s.dup; }
- { immutable x = (cast(int*[])null).dup; }
- { immutable x = pureFoo(); }
- { immutable x = pureFoo().dup; }
-}
-
-@safe unittest
-{
- auto a = [1, 2, 3];
- auto b = a.dup;
- debug(SENTINEL) {} else
- assert(b.capacity >= 3);
-}
-
-@system unittest
-{
- // Bugzilla 12580
- void[] m = [0];
- shared(void)[] s = [cast(shared)1];
- immutable(void)[] i = [cast(immutable)2];
-
- s = s.dup;
- static assert(is(typeof(s.dup) == shared(void)[]));
-
- m = i.dup;
- i = m.dup;
- i = i.idup;
- i = m.idup;
- i = s.idup;
- i = s.dup;
- static assert(!__traits(compiles, m = s.dup));
-}
-
-@safe unittest
-{
- // Bugzilla 13809
- static struct S
- {
- this(this) {}
- ~this() {}
- }
-
- S[] arr;
- auto a = arr.dup;
-}
-
-@system unittest
-{
- // Bugzilla 16504
- static struct S
- {
- __gshared int* gp;
- int* p;
- // postblit and hence .dup could escape
- this(this) { gp = p; }
- }
-
- int p;
- scope S[1] arr = [S(&p)];
- auto a = arr.dup; // dup does escape
-}
-
-// https://issues.dlang.org/show_bug.cgi?id=21983
-// dup/idup destroys partially constructed arrays on failure
-@safe unittest
-{
- static struct SImpl(bool postblit)
- {
- int num;
- long l = 0xDEADBEEF;
-
- static if (postblit)
- {
- this(this)
- {
- if (this.num == 3)
- throw new Exception("");
- }
- }
- else
- {
- this(scope ref const SImpl other)
- {
- if (other.num == 3)
- throw new Exception("");
-
- this.num = other.num;
- this.l = other.l;
- }
- }
-
- ~this() @trusted
- {
- if (l != 0xDEADBEEF)
- {
- import core.stdc.stdio;
- printf("Unexpected value: %lld\n", l);
- fflush(stdout);
- assert(false);
- }
- }
- }
-
- alias Postblit = SImpl!true;
- alias Copy = SImpl!false;
-
- static int test(S)()
- {
- S[4] arr = [ S(1), S(2), S(3), S(4) ];
- try
- {
- arr.dup();
- assert(false);
- }
- catch (Exception)
- {
- return 1;
- }
- }
-
- static assert(test!Postblit());
- assert(test!Postblit());
-
- static assert(test!Copy());
- assert(test!Copy());
-}
-
/**
Destroys the given object and optionally resets to initial state. It's used to
_destroy an object, calling its destructor or finalizer so it no longer
@@ -4910,6 +4615,8 @@ public import core.internal.array.casting: __ArrayCast;
public import core.internal.array.concatenation : _d_arraycatnTXImpl;
public import core.internal.array.construction : _d_arrayctor;
public import core.internal.array.construction : _d_arraysetctor;
+public import core.internal.array.arrayassign : _d_arrayassign_l;
+public import core.internal.array.arrayassign : _d_arrayassign_r;
public import core.internal.array.capacity: _d_arraysetlengthTImpl;
public import core.internal.dassert: _d_assert_fail;
diff --git a/libphobos/libdruntime/rt/arrayassign.d b/libphobos/libdruntime/rt/arrayassign.d
index c9db2fc..c9e2b15 100644
--- a/libphobos/libdruntime/rt/arrayassign.d
+++ b/libphobos/libdruntime/rt/arrayassign.d
@@ -19,171 +19,6 @@ private
debug(PRINTF) import core.stdc.stdio;
}
-/*
- * Superseded array assignment hook. Does not take into account destructors:
- * https://issues.dlang.org/show_bug.cgi?id=13661
- * Kept for backward binary compatibility. This function can be removed in the future.
- */
-extern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to)
-{
- debug(PRINTF) printf("_d_arrayassign(from = %p,%d, to = %p,%d) size = %d\n", from.ptr, from.length, to.ptr, to.length, ti.tsize);
-
- immutable elementSize = ti.tsize;
-
- // Need a temporary buffer tmp[] big enough to hold one element
- void[16] buf = void;
- void* ptmp = (elementSize > buf.sizeof) ? malloc(elementSize) : buf.ptr;
- scope (exit)
- {
- if (ptmp != buf.ptr)
- free(ptmp);
- }
- return _d_arrayassign_l(ti, from, to, ptmp);
-}
-
-/**
-Does array assignment (not construction) from another array of the same
-element type.
-
-Handles overlapping copies.
-
-The `_d_arrayassign_l` variant assumes the right hand side is an lvalue,
-while `_d_arrayassign_r` assumes it's an rvalue, which means it doesn't have to call copy constructors.
-
-Used for static array assignment with non-POD element types:
----
-struct S
-{
- ~this() {} // destructor, so not Plain Old Data
-}
-
-void main()
-{
- S[3] arr;
- S[3] lvalue;
-
- arr = lvalue;
- // Generates:
- // S _tmp;
- // _d_arrayassign_l(typeid(S), (cast(void*) lvalue.ptr)[0..lvalue.length], (cast(void*) arr.ptr)[0..arr.length], &_tmp);
-
- S[3] getRvalue() {return lvalue;}
- arr = getRvalue();
- // Similar, but `_d_arrayassign_r`
-}
----
-
-Params:
- ti = `TypeInfo` of the array element type.
- dst = target memory. Its `.length` is equal to the element count, not byte length.
- src = source memory. Its `.length` is equal to the element count, not byte length.
- ptmp = Temporary memory for element swapping, must have capacity of `ti.tsize` bytes.
-Returns: `dst`
-*/
-extern (C) void[] _d_arrayassign_l(TypeInfo ti, void[] src, void[] dst, void* ptmp)
-{
- debug(PRINTF) printf("_d_arrayassign_l(src = %p,%d, dst = %p,%d) size = %d\n", src.ptr, src.length, dst.ptr, dst.length, ti.tsize);
-
- immutable elementSize = ti.tsize;
-
- enforceRawArraysConformable("copy", elementSize, src, dst, true);
-
- if (src.ptr < dst.ptr && dst.ptr < src.ptr + elementSize * src.length)
- {
- // If dst is in the middle of src memory, use reverse order.
- for (auto i = dst.length; i--; )
- {
- void* pdst = dst.ptr + i * elementSize;
- void* psrc = src.ptr + i * elementSize;
- memcpy(ptmp, pdst, elementSize);
- memcpy(pdst, psrc, elementSize);
- ti.postblit(pdst);
- ti.destroy(ptmp);
- }
- }
- else
- {
- // Otherwise, use normal order.
- foreach (i; 0 .. dst.length)
- {
- void* pdst = dst.ptr + i * elementSize;
- void* psrc = src.ptr + i * elementSize;
- memcpy(ptmp, pdst, elementSize);
- memcpy(pdst, psrc, elementSize);
- ti.postblit(pdst);
- ti.destroy(ptmp);
- }
- }
- return dst;
-}
-
-unittest // Bugzilla 14024
-{
- string op;
-
- struct S
- {
- char x = 'x';
- this(this) { op ~= x-0x20; } // upper case
- ~this() { op ~= x; } // lower case
- }
-
- S[4] mem;
- ref S[2] slice(int a, int b) { return mem[a .. b][0 .. 2]; }
-
- op = null;
- mem[0].x = 'a';
- mem[1].x = 'b';
- mem[2].x = 'x';
- mem[3].x = 'y';
- slice(0, 2) = slice(2, 4); // [ab] = [xy]
- assert(op == "XaYb", op);
-
- op = null;
- mem[0].x = 'x';
- mem[1].x = 'y';
- mem[2].x = 'a';
- mem[3].x = 'b';
- slice(2, 4) = slice(0, 2); // [ab] = [xy]
- assert(op == "XaYb", op);
-
- op = null;
- mem[0].x = 'a';
- mem[1].x = 'b';
- mem[2].x = 'c';
- slice(0, 2) = slice(1, 3); // [ab] = [bc]
- assert(op == "BaCb", op);
-
- op = null;
- mem[0].x = 'x';
- mem[1].x = 'y';
- mem[2].x = 'z';
- slice(1, 3) = slice(0, 2); // [yz] = [xy]
- assert(op == "YzXy", op);
-}
-
-/// ditto
-extern (C) void[] _d_arrayassign_r(TypeInfo ti, void[] src, void[] dst, void* ptmp)
-{
- debug(PRINTF) printf("_d_arrayassign_r(src = %p,%d, dst = %p,%d) size = %d\n", src.ptr, src.length, dst.ptr, dst.length, ti.tsize);
-
- immutable elementSize = ti.tsize;
-
- enforceRawArraysConformable("copy", elementSize, src, dst, false);
-
- // Always use normal order, because we can assume that
- // the rvalue src has no overlapping with dst.
- foreach (i; 0 .. dst.length)
- {
- void* pdst = dst.ptr + i * elementSize;
- void* psrc = src.ptr + i * elementSize;
- memcpy(ptmp, pdst, elementSize);
- memcpy(pdst, psrc, elementSize);
- ti.destroy(ptmp);
- }
- return dst;
-}
-
/**
Set all elements of an array to a single value.
diff --git a/libphobos/libdruntime/rt/dylib_fixes.c b/libphobos/libdruntime/rt/dylib_fixes.c
index e484fed..c1391b8 100644
--- a/libphobos/libdruntime/rt/dylib_fixes.c
+++ b/libphobos/libdruntime/rt/dylib_fixes.c
@@ -25,4 +25,3 @@ __attribute__((destructor)) static void finalizer ()
{
rt_term();
}
-