diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-02-28 15:47:52 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2022-02-28 17:49:01 +0100 |
commit | 1027dc459204894f4503f713a3d73826e4bbab15 (patch) | |
tree | 606564b15e0978c77c76d0e618c00c25a78aaf38 /libphobos/src | |
parent | 430c89274d7f82810724126637ffdc5507d442f0 (diff) | |
download | gcc-1027dc459204894f4503f713a3d73826e4bbab15.tar.gz |
d: Merge upstream dmd cf63dd8e5, druntime caf14b0f, phobos 41aaf8c26.
D front-end changes:
- Import dmd v2.099.0-rc.1.
- The `main' can now return type `noreturn' and supports return
inference.
D Runtime changes:
- Import druntime v2.099.0-rc.1.
- C bindings for stat_t on powerpc-linux has been fixed.
Phobos changes:
- Import phobos v2.099.0-rc.1.
gcc/d/ChangeLog:
* d-target.cc (Target::_init): Initialize C type size fields.
* dmd/MERGE: Merge upstream dmd cf63dd8e5.
* dmd/VERSION: Update version to v2.099.0-rc.1.
libphobos/ChangeLog:
* libdruntime/MERGE: Merge upstream druntime caf14b0f.
* src/MERGE: Merge upstream phobos 41aaf8c26.
gcc/testsuite/ChangeLog:
* gdc.dg/torture/simd7413a.d: Update.
* gdc.dg/ubsan/pr88957.d: Update.
* gdc.dg/simd18489.d: New test.
* gdc.dg/torture/simd21727.d: New test.
Diffstat (limited to 'libphobos/src')
-rw-r--r-- | libphobos/src/MERGE | 2 | ||||
-rw-r--r-- | libphobos/src/std/file.d | 4 | ||||
-rw-r--r-- | libphobos/src/std/getopt.d | 8 | ||||
-rw-r--r-- | libphobos/src/std/range/primitives.d | 11 | ||||
-rw-r--r-- | libphobos/src/std/sumtype.d | 108 |
5 files changed, 110 insertions, 23 deletions
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index b5b939f41b3..e15541e181d 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -1a3e80ec25afab6123cdcfe20186f36f006b68bb +41aaf8c2636df0e2e3ad39933b321d2b4cd231fa 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/file.d b/libphobos/src/std/file.d index a99c5170afb..b09b82ab85e 100644 --- a/libphobos/src/std/file.d +++ b/libphobos/src/std/file.d @@ -425,10 +425,10 @@ version (Windows) private void[] readImpl(scope const(char)[] name, scope const( fileSize = makeUlong(sizeLow, sizeHigh); return result; } - static trustedReadFile(HANDLE hFile, void *lpBuffer, ulong nNumberOfBytesToRead) + static trustedReadFile(HANDLE hFile, void *lpBuffer, size_t nNumberOfBytesToRead) { // Read by chunks of size < 4GB (Windows API limit) - ulong totalNumRead = 0; + size_t totalNumRead = 0; while (totalNumRead != nNumberOfBytesToRead) { const uint chunkSize = min(nNumberOfBytesToRead - totalNumRead, 0xffff_0000); diff --git a/libphobos/src/std/getopt.d b/libphobos/src/std/getopt.d index 482aae6306a..c1c5cd2b36e 100644 --- a/libphobos/src/std/getopt.d +++ b/libphobos/src/std/getopt.d @@ -438,7 +438,7 @@ GetoptResult getopt(T...)(ref string[] args, T opts) } /// -@system unittest +@safe unittest { auto args = ["prog", "--foo", "-b"]; @@ -1646,11 +1646,13 @@ Params: text = The text to printed at the beginning of the help output. opt = The `Option` extracted from the `getopt` parameter. */ -void defaultGetoptPrinter(string text, Option[] opt) +void defaultGetoptPrinter(string text, Option[] opt) @safe { import std.stdio : stdout; + // stdout global __gshared is trusted with a locked text writer + auto w = (() @trusted => stdout.lockingTextWriter())(); - defaultGetoptFormatter(stdout.lockingTextWriter(), text, opt); + defaultGetoptFormatter(w, text, opt); } /** This function writes the passed text and `Option` into an output range diff --git a/libphobos/src/std/range/primitives.d b/libphobos/src/std/range/primitives.d index c092a9d0946..31f58fa5fa9 100644 --- a/libphobos/src/std/range/primitives.d +++ b/libphobos/src/std/range/primitives.d @@ -2055,9 +2055,14 @@ if (isBidirectionalRange!Range) } /** - Moves the front of `r` out and returns it. Leaves `r.front` in a - destroyable state that does not allocate any resources (usually equal - to its `.init` value). + Moves the front of `r` out and returns it. + + If `r.front` is a struct with a destructor or copy constructor defined, it + is reset to its `.init` value after its value is moved. Otherwise, it is + left unchanged. + + In either case, `r.front` is left in a destroyable state that does not + allocate any resources. */ ElementType!R moveFront(R)(R r) { diff --git a/libphobos/src/std/sumtype.d b/libphobos/src/std/sumtype.d index 5e35a6b9cd5..0dd636ea67b 100644 --- a/libphobos/src/std/sumtype.d +++ b/libphobos/src/std/sumtype.d @@ -533,15 +533,35 @@ public: /** * Assigns a value to a `SumType`. * - * Assigning to a `SumType` is `@system` if any of the - * `SumType`'s members contain pointers or references, since - * those members may be reachable through external references, - * and overwriting them could therefore lead to memory - * corruption. + * If any of the `SumType`'s members other than the one being assigned + * to contain pointers or references, it is possible for the assignment + * to cause memory corruption (see the + * ["Memory corruption" example](#memory-corruption) below for an + * illustration of how). Therefore, such assignments are considered + * `@system`. * * An individual assignment can be `@trusted` if the caller can - * guarantee that there are no outstanding references to $(I any) - * of the `SumType`'s members when the assignment occurs. + * guarantee that there are no outstanding references to any `SumType` + * members that contain pointers or references at the time the + * assignment occurs. + * + * Examples: + * + * $(DIVID memory-corruption, $(H3 Memory corruption)) + * + * This example shows how assignment to a `SumType` can be used to + * cause memory corruption in `@system` code. In `@safe` code, the + * assignment `s = 123` would not be allowed. + * + * --- + * SumType!(int*, int) s = new int; + * s.tryMatch!( + * (ref int* p) { + * s = 123; // overwrites `p` + * return *p; // undefined behavior + * } + * ); + * --- */ ref SumType opAssign(T rhs); } @@ -553,14 +573,35 @@ public: /** * Assigns a value to a `SumType`. * - * Assigning to a `SumType` is `@system` if any of the `SumType`'s - * $(I other) members contain pointers or references, since those - * members may be reachable through external references, and - * overwriting them could therefore lead to memory corruption. + * If any of the `SumType`'s members other than the one being assigned + * to contain pointers or references, it is possible for the assignment + * to cause memory corruption (see the + * ["Memory corruption" example](#memory-corruption) below for an + * illustration of how). Therefore, such assignments are considered + * `@system`. * * An individual assignment can be `@trusted` if the caller can - * guarantee that, when the assignment occurs, there are no - * outstanding references to any such members. + * guarantee that there are no outstanding references to any `SumType` + * members that contain pointers or references at the time the + * assignment occurs. + * + * Examples: + * + * $(DIVID memory-corruption, $(H3 Memory corruption)) + * + * This example shows how assignment to a `SumType` can be used to + * cause memory corruption in `@system` code. In `@safe` code, the + * assignment `s = 123` would not be allowed. + * + * --- + * SumType!(int*, int) s = new int; + * s.tryMatch!( + * (ref int* p) { + * s = 123; // overwrites `p` + * return *p; // undefined behavior + * } + * ); + * --- */ ref SumType opAssign(T rhs) { @@ -1528,7 +1569,27 @@ private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...); } /// True if `T` is a [SumType] or implicitly converts to one, otherwise false. -enum bool isSumType(T) = is(T : SumType!Args, Args...); +template isSumType(T) +{ + static if (is(T : SumType!Args, Args...)) + { + enum isSumType = true; + } + else static if (is(T == struct) && __traits(getAliasThis, T).length > 0) + { + // Workaround for https://issues.dlang.org/show_bug.cgi?id=21975 + import std.traits : ReturnType; + + alias AliasThisType = ReturnType!((T t) => + __traits(getMember, t, __traits(getAliasThis, T)[0]) + ); + enum isSumType = .isSumType!AliasThisType; + } + else + { + enum isSumType = false; + } +} /// @safe unittest @@ -1549,6 +1610,25 @@ enum bool isSumType(T) = is(T : SumType!Args, Args...); assert(!isSumType!ContainsSumType); } +@safe unittest +{ + static struct AliasThisVar(T) + { + SumType!T payload; + alias payload this; + } + + static struct AliasThisFunc(T) + { + SumType!T payload; + ref get() { return payload; } + alias get this; + } + + static assert(isSumType!(AliasThisVar!int)); + static assert(isSumType!(AliasThisFunc!int)); +} + /** * Calls a type-appropriate function with the value held in a [SumType]. * |