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