From b6df113247b9f3f7c3db0e65c481dad5bcfddfb4 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Tue, 26 Jul 2022 17:42:23 +0200 Subject: d: Merge upstream dmd d7772a2369, phobos 5748ca43f. In upstream dmd, the compiler front-end and run-time have been merged together into one repository. Both dmd and libdruntime now track that. D front-end changes: - Deprecated `scope(failure)' blocks that contain `return' statements. - Deprecated using integers for `version' or `debug' conditions. - Deprecated returning a discarded void value from a function. - `new' can now allocate an associative array. D runtime changes: - Added avx512f detection to core.cpuid module. Phobos changes: - Changed std.experimental.logger.core.sharedLog to return shared(Logger). gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd d7772a2369. * dmd/VERSION: Bump version to v2.100.1. * d-codegen.cc (get_frameinfo): Check whether decision to generate closure changed since semantic finished. * d-lang.cc (d_handle_option): Remove handling of -fdebug=level and -fversion=level. * decl.cc (DeclVisitor::visit (VarDeclaration *)): Generate evaluation of noreturn variable initializers before throw. * expr.cc (ExprVisitor::visit (AssignExp *)): Don't generate assignment for noreturn types, only evaluate for side effects. * lang.opt (fdebug=): Undocument -fdebug=level. (fversion=): Undocument -fversion=level. libphobos/ChangeLog: * configure: Regenerate. * configure.ac (libtool_VERSION): Update to 4:0:0. * libdruntime/MERGE: Merge upstream druntime d7772a2369. * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add core/internal/array/duplication.d. * libdruntime/Makefile.in: Regenerate. * src/MERGE: Merge upstream phobos 5748ca43f. * testsuite/libphobos.gc/nocollect.d: --- libphobos/libdruntime/MERGE | 4 +- libphobos/libdruntime/Makefile.am | 16 +- libphobos/libdruntime/Makefile.in | 19 +- libphobos/libdruntime/core/cpuid.d | 16 + libphobos/libdruntime/core/int128.d | 2 - .../libdruntime/core/internal/array/appending.d | 28 +- .../libdruntime/core/internal/array/duplication.d | 346 +++++++++++++++++++++ libphobos/libdruntime/core/internal/dassert.d | 2 +- libphobos/libdruntime/core/runtime.d | 2 +- libphobos/libdruntime/core/stdc/errno.d | 2 +- libphobos/libdruntime/core/stdc/stdio.d | 53 +++- libphobos/libdruntime/core/stdc/wchar_.d | 90 ++++-- .../libdruntime/core/sys/darwin/mach/getsect.d | 1 - .../libdruntime/core/sys/dragonflybsd/string.d | 1 - libphobos/libdruntime/core/sys/linux/sys/time.d | 1 - libphobos/libdruntime/core/sys/linux/sys/xattr.d | 1 - libphobos/libdruntime/core/sys/linux/tipc.d | 1 - libphobos/libdruntime/core/sys/posix/signal.d | 79 +---- libphobos/libdruntime/core/sys/posix/spawn.d | 2 +- libphobos/libdruntime/core/sys/posix/stdio.d | 2 +- libphobos/libdruntime/core/sys/posix/sys/select.d | 1 - libphobos/libdruntime/core/sys/posix/time.d | 66 +++- libphobos/libdruntime/core/sys/posix/ucontext.d | 1 - .../libdruntime/core/sys/solaris/sys/priocntl.d | 1 - .../libdruntime/core/sys/solaris/sys/procset.d | 1 - libphobos/libdruntime/core/sys/windows/cguid.d | 1 - libphobos/libdruntime/core/sys/windows/ntsecpkg.d | 1 - libphobos/libdruntime/core/sys/windows/olectlid.d | 1 - libphobos/libdruntime/core/sys/windows/shlguid.d | 1 - libphobos/libdruntime/core/sys/windows/sspi.d | 1 - libphobos/libdruntime/object.d | 340 +------------------- libphobos/libdruntime/rt/dylib_fixes.c | 1 - 32 files changed, 581 insertions(+), 503 deletions(-) create mode 100644 libphobos/libdruntime/core/internal/array/duplication.d (limited to 'libphobos/libdruntime') diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 6e25a9d..c358b69 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -651389b52243dcadb338dd0c14dd27e7850cda8d +d7772a236983ec37b92d21b28bad3cd2de57b945 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..2e1e91d 100644 --- a/libphobos/libdruntime/Makefile.am +++ b/libphobos/libdruntime/Makefile.am @@ -174,14 +174,14 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.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/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 \ - core/internal/container/common.d core/internal/container/hashtab.d \ - core/internal/container/treap.d core/internal/convert.d \ - core/internal/dassert.d core/internal/destruction.d \ - core/internal/entrypoint.d core/internal/gc/bits.d \ - core/internal/gc/impl/conservative/gc.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 core/internal/container/common.d \ + core/internal/container/hashtab.d core/internal/container/treap.d \ + core/internal/convert.d core/internal/dassert.d \ + core/internal/destruction.d core/internal/entrypoint.d \ + core/internal/gc/bits.d core/internal/gc/impl/conservative/gc.d \ core/internal/gc/impl/manual/gc.d core/internal/gc/impl/proto/gc.d \ core/internal/gc/os.d core/internal/gc/pooltable.d \ core/internal/gc/proxy.d core/internal/hash.d core/internal/lifetime.d \ diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in index 24865fb..de6656c 100644 --- a/libphobos/libdruntime/Makefile.in +++ b/libphobos/libdruntime/Makefile.in @@ -196,6 +196,7 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.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 \ @@ -841,14 +842,14 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.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/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 \ - core/internal/container/common.d core/internal/container/hashtab.d \ - core/internal/container/treap.d core/internal/convert.d \ - core/internal/dassert.d core/internal/destruction.d \ - core/internal/entrypoint.d core/internal/gc/bits.d \ - core/internal/gc/impl/conservative/gc.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 core/internal/container/common.d \ + core/internal/container/hashtab.d core/internal/container/treap.d \ + core/internal/convert.d core/internal/dassert.d \ + core/internal/destruction.d core/internal/entrypoint.d \ + core/internal/gc/bits.d core/internal/gc/impl/conservative/gc.d \ core/internal/gc/impl/manual/gc.d core/internal/gc/impl/proto/gc.d \ core/internal/gc/os.d core/internal/gc/pooltable.d \ core/internal/gc/proxy.d core/internal/hash.d core/internal/lifetime.d \ @@ -1208,6 +1209,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/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/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/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 2f8d3f37..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/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..8ef65489 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -3765,6 +3765,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 +3787,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 +3795,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 +3816,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 +4003,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 +4019,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 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(); } - -- cgit v1.1