summaryrefslogtreecommitdiff
path: root/libphobos/src
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2022-02-28 15:47:52 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2022-02-28 17:49:01 +0100
commit1027dc459204894f4503f713a3d73826e4bbab15 (patch)
tree606564b15e0978c77c76d0e618c00c25a78aaf38 /libphobos/src
parent430c89274d7f82810724126637ffdc5507d442f0 (diff)
downloadgcc-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/MERGE2
-rw-r--r--libphobos/src/std/file.d4
-rw-r--r--libphobos/src/std/getopt.d8
-rw-r--r--libphobos/src/std/range/primitives.d11
-rw-r--r--libphobos/src/std/sumtype.d108
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].
*