aboutsummaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-10-29 16:39:05 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2023-10-29 16:41:29 +0100
commite773c6c7009bb35fa50da034f3537448fd36c7f0 (patch)
tree24b60531e9364c16eb2bfd6c2bfea5f287e6afab /libphobos
parentc6929b085580cf00cbc52b0f5b0afe2b9caa2a22 (diff)
downloadgcc-e773c6c7009bb35fa50da034f3537448fd36c7f0.zip
gcc-e773c6c7009bb35fa50da034f3537448fd36c7f0.tar.gz
gcc-e773c6c7009bb35fa50da034f3537448fd36c7f0.tar.bz2
d: Merge upstream dmd, druntime e48bc0987d, phobos 2458e8f82.
D front-end changes: - Import dmd v2.106.0-beta.1. D runtime changes: - Import druntime v2.106.0-beta.1. Phobos changes: - Import phobos v2.106.0-beta.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd e48bc0987d. * expr.cc (ExprVisitor::visit (NewExp *)): Update for new front-end interface. * runtime.def (NEWARRAYT): Remove. (NEWARRAYIT): Remove. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime e48bc0987d. * src/MERGE: Merge upstream phobos 2458e8f82.
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/core/internal/array/construction.d167
-rw-r--r--libphobos/libdruntime/core/internal/array/utils.d236
-rw-r--r--libphobos/libdruntime/core/lifetime.d13
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/ifaddrs.d41
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/net/if_dl.d42
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/socket.d131
-rw-r--r--libphobos/libdruntime/core/sys/freebsd/sys/types.d58
-rw-r--r--libphobos/libdruntime/core/sys/posix/sys/types.d4
-rw-r--r--libphobos/libdruntime/object.d2
-rw-r--r--libphobos/libdruntime/rt/lifetime.d26
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/parallelism.d2
-rw-r--r--libphobos/src/std/range/primitives.d10
-rw-r--r--libphobos/src/std/traits.d57
15 files changed, 753 insertions, 40 deletions
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 7946002..2a0baf0 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-4c18eed9674e04c1ca89fbc8bd5c4e483eb5477c
+e48bc0987dfec35bc76a3015ee3e85906ce86dfd
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d
index 2508359..54f8767 100644
--- a/libphobos/libdruntime/core/internal/array/construction.d
+++ b/libphobos/libdruntime/core/internal/array/construction.d
@@ -11,6 +11,11 @@ module core.internal.array.construction;
import core.internal.traits : Unqual;
+debug(PRINTF)
+{
+ import core.stdc.stdio;
+}
+
/**
* Does array initialization (not assignment) from another array of the same element type.
* Params:
@@ -319,3 +324,165 @@ void _d_arraysetctor(Tarr : T[], T)(scope Tarr p, scope ref T value) @trusted
assert(!didThrow);
assert(counter == 4);
}
+
+/**
+ * Allocate an array with the garbage collector. Also initalize elements if
+ * their type has an initializer. Otherwise, not zero-initialize the array.
+ *
+ * Has three variants:
+ * `_d_newarrayU` leaves elements uninitialized
+ * `_d_newarrayT` initializes to 0 or based on initializer
+ *
+ * Params:
+ * length = `.length` of resulting array
+ *
+ * Returns:
+ * newly allocated array
+ */
+T[] _d_newarrayU(T)(size_t length, bool isShared=false) pure nothrow @nogc @trusted
+{
+ alias PureType = T[] function(size_t length, bool isShared) pure nothrow @nogc @trusted;
+ return (cast(PureType) &_d_newarrayUImpl!T)(length, isShared);
+}
+
+T[] _d_newarrayUImpl(T)(size_t length, bool isShared=false) @trusted
+{
+ import core.exception : onOutOfMemoryError;
+ import core.internal.array.utils : __arrayStart, __setArrayAllocLength, __arrayAlloc;
+
+ size_t elemSize = T.sizeof;
+ size_t arraySize;
+
+ debug(PRINTF) printf("_d_newarrayU(length = x%zu, size = %zu)\n", length, elemSize);
+ if (length == 0 || elemSize == 0)
+ return null;
+
+ version (D_InlineAsm_X86)
+ {
+ asm pure nothrow @nogc
+ {
+ mov EAX, elemSize ;
+ mul EAX, length ;
+ mov arraySize, EAX ;
+ jnc Lcontinue ;
+ }
+ }
+ else version (D_InlineAsm_X86_64)
+ {
+ asm pure nothrow @nogc
+ {
+ mov RAX, elemSize ;
+ mul RAX, length ;
+ mov arraySize, RAX ;
+ jnc Lcontinue ;
+ }
+ }
+ else
+ {
+ import core.checkedint : mulu;
+
+ bool overflow = false;
+ arraySize = mulu(elemSize, length, overflow);
+ if (!overflow)
+ goto Lcontinue;
+ }
+
+Loverflow:
+ onOutOfMemoryError();
+ assert(0);
+
+Lcontinue:
+ auto info = __arrayAlloc!T(arraySize);
+ if (!info.base)
+ goto Loverflow;
+ debug(PRINTF) printf("p = %p\n", info.base);
+
+ auto arrstart = __arrayStart(info);
+
+ __setArrayAllocLength!T(info, arraySize, isShared);
+
+ return (cast(T*) arrstart)[0 .. length];
+}
+
+/// ditto
+T[] _d_newarrayT(T)(size_t length, bool isShared=false) @trusted
+{
+ T[] result = _d_newarrayU!T(length, isShared);
+
+ static if (__traits(isZeroInit, T))
+ {
+ import core.stdc.string : memset;
+ memset(result.ptr, 0, length * T.sizeof);
+ }
+ else
+ {
+ import core.internal.lifetime : emplaceInitializer;
+ foreach (ref elem; result)
+ emplaceInitializer(elem);
+ }
+
+ return result;
+}
+
+unittest
+{
+ {
+ // zero-initialization
+ struct S { int x, y; }
+ S[] s = _d_newarrayT!S(10);
+
+ assert(s !is null);
+ assert(s.length == 10);
+ foreach (ref elem; s)
+ {
+ assert(elem.x == 0);
+ assert(elem.y == 0);
+ }
+ }
+ {
+ // S.init
+ struct S { int x = 2, y = 3; }
+ S[] s = _d_newarrayT!S(10);
+
+ assert(s.length == 10);
+ foreach (ref elem; s)
+ {
+ assert(elem.x == 2);
+ assert(elem.y == 3);
+ }
+ }
+}
+
+unittest
+{
+ int pblits;
+
+ struct S
+ {
+ this(this) { pblits++; }
+ }
+
+ S[] s = _d_newarrayT!S(2);
+
+ assert(s.length == 2);
+ assert(pblits == 0);
+}
+
+version (D_ProfileGC)
+{
+ /**
+ * TraceGC wrapper around $(REF _d_newitemT, core,lifetime).
+ */
+ T[] _d_newarrayTTrace(T)(string file, int line, string funcname, size_t length, bool isShared) @trusted
+ {
+ version (D_TypeInfo)
+ {
+ import core.internal.array.utils : TraceHook, gcStatsPure, accumulatePure;
+ mixin(TraceHook!(T.stringof, "_d_newarrayT"));
+
+ return _d_newarrayT!T(length, isShared);
+ }
+ else
+ assert(0, "Cannot create new array if compiling without support for runtime type information!");
+ }
+}
diff --git a/libphobos/libdruntime/core/internal/array/utils.d b/libphobos/libdruntime/core/internal/array/utils.d
index a16005e..57eb14b 100644
--- a/libphobos/libdruntime/core/internal/array/utils.d
+++ b/libphobos/libdruntime/core/internal/array/utils.d
@@ -10,6 +10,25 @@
module core.internal.array.utils;
import core.internal.traits : Parameters;
+import core.memory : GC;
+
+alias BlkInfo = GC.BlkInfo;
+alias BlkAttr = GC.BlkAttr;
+
+private
+{
+ enum : size_t
+ {
+ PAGESIZE = 4096,
+ BIGLENGTHMASK = ~(PAGESIZE - 1),
+ SMALLPAD = 1,
+ MEDPAD = ushort.sizeof,
+ LARGEPREFIX = 16, // 16 bytes padding at the front of the array
+ LARGEPAD = LARGEPREFIX + 1,
+ MAXSMALLSIZE = 256-SMALLPAD,
+ MAXMEDSIZE = (PAGESIZE / 2) - MEDPAD
+ }
+}
auto gcStatsPure() nothrow pure
{
@@ -136,3 +155,220 @@ template isPostblitNoThrow(T) {
else
enum isPostblitNoThrow = true;
}
+
+/**
+ * Clear padding that might not be zeroed by the GC (it assumes it is within the
+ * requested size from the start, but it is actually at the end of the allocated
+ * block).
+ *
+ * Params:
+ * info = array allocation data
+ * arrSize = size of the array in bytes
+ * padSize = size of the padding in bytes
+ */
+void __arrayClearPad()(ref BlkInfo info, size_t arrSize, size_t padSize) nothrow pure
+{
+ import core.stdc.string;
+ if (padSize > MEDPAD && !(info.attr & BlkAttr.NO_SCAN) && info.base)
+ {
+ if (info.size < PAGESIZE)
+ memset(info.base + arrSize, 0, padSize);
+ else
+ memset(info.base, 0, LARGEPREFIX);
+ }
+}
+
+/**
+ * Allocate an array memory block by applying the proper padding and assigning
+ * block attributes if not inherited from the existing block.
+ *
+ * Params:
+ * arrSize = size of the allocated array in bytes
+ * Returns:
+ * `BlkInfo` with allocation metadata
+ */
+BlkInfo __arrayAlloc(T)(size_t arrSize) @trusted
+{
+ import core.checkedint;
+ import core.lifetime : TypeInfoSize;
+ import core.internal.traits : hasIndirections;
+
+ enum typeInfoSize = TypeInfoSize!T;
+ BlkAttr attr = BlkAttr.APPENDABLE;
+
+ size_t padSize = arrSize > MAXMEDSIZE ?
+ LARGEPAD :
+ ((arrSize > MAXSMALLSIZE ? MEDPAD : SMALLPAD) + typeInfoSize);
+
+ bool overflow;
+ auto paddedSize = addu(arrSize, padSize, overflow);
+
+ if (overflow)
+ return BlkInfo();
+
+ /* `extern(C++)` classes don't have a classinfo pointer in their vtable,
+ * so the GC can't finalize them.
+ */
+ static if (typeInfoSize)
+ attr |= BlkAttr.STRUCTFINAL | BlkAttr.FINALIZE;
+ static if (!hasIndirections!T)
+ attr |= BlkAttr.NO_SCAN;
+
+ auto bi = GC.qalloc(paddedSize, attr, typeid(T));
+ __arrayClearPad(bi, arrSize, padSize);
+ return bi;
+}
+
+/**
+ * Get the start of the array for the given block.
+ *
+ * Params:
+ * info = array metadata
+ * Returns:
+ * pointer to the start of the array
+ */
+void *__arrayStart()(return scope BlkInfo info) nothrow pure
+{
+ return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0);
+}
+
+/**
+ * Set the allocated length of the array block. This is called when an array
+ * is appended to or its length is set.
+ *
+ * The allocated block looks like this for blocks < PAGESIZE:
+ * `|elem0|elem1|elem2|...|elemN-1|emptyspace|N*elemsize|`
+ *
+ * The size of the allocated length at the end depends on the block size:
+ * a block of 16 to 256 bytes has an 8-bit length.
+ * a block with 512 to pagesize/2 bytes has a 16-bit length.
+ *
+ * For blocks >= pagesize, the length is a size_t and is at the beginning of the
+ * block. The reason we have to do this is because the block can extend into
+ * more pages, so we cannot trust the block length if it sits at the end of the
+ * block, because it might have just been extended. If we can prove in the
+ * future that the block is unshared, we may be able to change this, but I'm not
+ * sure it's important.
+ *
+ * In order to do put the length at the front, we have to provide 16 bytes
+ * buffer space in case the block has to be aligned properly. In x86, certain
+ * SSE instructions will only work if the data is 16-byte aligned. In addition,
+ * we need the sentinel byte to prevent accidental pointers to the next block.
+ * Because of the extra overhead, we only do this for page size and above, where
+ * the overhead is minimal compared to the block size.
+ *
+ * So for those blocks, it looks like:
+ * `|N*elemsize|padding|elem0|elem1|...|elemN-1|emptyspace|sentinelbyte|``
+ *
+ * where `elem0` starts 16 bytes after the first byte.
+ */
+bool __setArrayAllocLength(T)(ref BlkInfo info, size_t newLength, bool isShared, size_t oldLength = ~0)
+{
+ import core.atomic;
+ import core.lifetime : TypeInfoSize;
+
+ size_t typeInfoSize = TypeInfoSize!T;
+
+ if (info.size <= 256)
+ {
+ import core.checkedint;
+
+ bool overflow;
+ auto newLengthPadded = addu(newLength,
+ addu(SMALLPAD, typeInfoSize, overflow),
+ overflow);
+
+ if (newLengthPadded > info.size || overflow)
+ // new size does not fit inside block
+ return false;
+
+ auto length = cast(ubyte *)(info.base + info.size - typeInfoSize - SMALLPAD);
+ if (oldLength != ~0)
+ {
+ if (isShared)
+ {
+ return cas(cast(shared)length, cast(ubyte)oldLength, cast(ubyte)newLength);
+ }
+ else
+ {
+ if (*length == cast(ubyte)oldLength)
+ *length = cast(ubyte)newLength;
+ else
+ return false;
+ }
+ }
+ else
+ {
+ // setting the initial length, no cas needed
+ *length = cast(ubyte)newLength;
+ }
+ if (typeInfoSize)
+ {
+ auto typeInfo = cast(TypeInfo*)(info.base + info.size - size_t.sizeof);
+ *typeInfo = cast()typeid(T);
+ }
+ }
+ else if (info.size < PAGESIZE)
+ {
+ if (newLength + MEDPAD + typeInfoSize > info.size)
+ // new size does not fit inside block
+ return false;
+ auto length = cast(ushort *)(info.base + info.size - typeInfoSize - MEDPAD);
+ if (oldLength != ~0)
+ {
+ if (isShared)
+ {
+ return cas(cast(shared)length, cast(ushort)oldLength, cast(ushort)newLength);
+ }
+ else
+ {
+ if (*length == oldLength)
+ *length = cast(ushort)newLength;
+ else
+ return false;
+ }
+ }
+ else
+ {
+ // setting the initial length, no cas needed
+ *length = cast(ushort)newLength;
+ }
+ if (typeInfoSize)
+ {
+ auto typeInfo = cast(TypeInfo*)(info.base + info.size - size_t.sizeof);
+ *typeInfo = cast()typeid(T);
+ }
+ }
+ else
+ {
+ if (newLength + LARGEPAD > info.size)
+ // new size does not fit inside block
+ return false;
+ auto length = cast(size_t *)(info.base);
+ if (oldLength != ~0)
+ {
+ if (isShared)
+ {
+ return cas(cast(shared)length, cast(size_t)oldLength, cast(size_t)newLength);
+ }
+ else
+ {
+ if (*length == oldLength)
+ *length = newLength;
+ else
+ return false;
+ }
+ }
+ else
+ {
+ // setting the initial length, no cas needed
+ *length = newLength;
+ }
+ if (typeInfoSize)
+ {
+ auto typeInfo = cast(TypeInfo*)(info.base + size_t.sizeof);
+ *typeInfo = cast()typeid(T);
+ }
+ }
+ return true; // resize succeeded
+}
diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d
index 3a55ca9..6b083ea 100644
--- a/libphobos/libdruntime/core/lifetime.d
+++ b/libphobos/libdruntime/core/lifetime.d
@@ -2731,7 +2731,8 @@ if (is(T == class))
{
import core.internal.traits : hasIndirections;
import core.exception : onOutOfMemoryError;
- import core.memory : GC, pureMalloc;
+ import core.memory : pureMalloc;
+ import core.memory : GC;
alias BlkAttr = GC.BlkAttr;
@@ -2820,11 +2821,11 @@ T _d_newclassTTrace(T)(string file, int line, string funcname) @trusted
T* _d_newitemT(T)() @trusted
{
import core.internal.lifetime : emplaceInitializer;
- import core.internal.traits : hasElaborateDestructor, hasIndirections;
+ import core.internal.traits : hasIndirections;
import core.memory : GC;
auto flags = !hasIndirections!T ? GC.BlkAttr.NO_SCAN : GC.BlkAttr.NONE;
- immutable tiSize = hasElaborateDestructor!T ? size_t.sizeof : 0;
+ immutable tiSize = TypeInfoSize!T;
immutable itemSize = T.sizeof;
immutable totalSize = itemSize + tiSize;
if (tiSize)
@@ -3004,3 +3005,9 @@ version (D_ProfileGC)
assert(0, "Cannot create new `struct` if compiling without support for runtime type information!");
}
}
+
+template TypeInfoSize(T)
+{
+ import core.internal.traits : hasElaborateDestructor;
+ enum TypeInfoSize = hasElaborateDestructor!T ? size_t.sizeof : 0;
+}
diff --git a/libphobos/libdruntime/core/sys/freebsd/ifaddrs.d b/libphobos/libdruntime/core/sys/freebsd/ifaddrs.d
new file mode 100644
index 0000000..aa39ac4
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/ifaddrs.d
@@ -0,0 +1,41 @@
+//Written in the D programming language
+
+/++
+ D header file for FreeBSD's ifaddrs.h.
+
+ Copyright: Copyright 2023
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: $(HTTP jmdavisprog.com, Jonathan M Davis)
+ +/
+module core.sys.freebsd.ifaddrs;
+
+version (FreeBSD):
+extern(C):
+@nogc:
+nothrow:
+
+import core.sys.posix.sys.socket : sockaddr;
+
+struct ifaddrs
+{
+ ifaddrs* ifa_next;
+ char* ifa_name;
+ uint ifa_flags;
+ sockaddr* ifa_addr;
+ sockaddr* ifa_netmask;
+ sockaddr* ifa_dstaddr;
+ void* ifa_data;
+}
+
+struct ifmaddrs
+{
+ ifmaddrs* ifma_next;
+ sockaddr* ifma_name;
+ sockaddr* ifma_addr;
+ sockaddr* ifma_lladdr;
+}
+
+int getifaddrs(ifaddrs**);
+void freeifaddrs(ifaddrs*);
+int getifmaddrs(ifmaddrs**);
+void freeifmaddrs(ifmaddrs*);
diff --git a/libphobos/libdruntime/core/sys/freebsd/net/if_dl.d b/libphobos/libdruntime/core/sys/freebsd/net/if_dl.d
new file mode 100644
index 0000000..9f83061
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/net/if_dl.d
@@ -0,0 +1,42 @@
+//Written in the D programming language
+
+/++
+ D header file for FreeBSD's net/if_dl.h.
+
+ Copyright: Copyright 2023
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: $(HTTP jmdavisprog.com, Jonathan M Davis)
+ +/
+module core.sys.freebsd.net.if_dl;
+
+version (FreeBSD):
+extern(C):
+@nogc:
+nothrow:
+
+import core.sys.freebsd.sys.types : caddr_t, c_caddr_t;
+import core.sys.posix.sys.socket : sa_family_t, sockaddr;
+
+struct sockaddr_dl
+{
+ ubyte sdl_len;
+ sa_family_t sdl_family;
+ ushort sdl_index;
+ ubyte sdl_type;
+ ubyte sdl_nlen;
+ ubyte sdl_alen;
+ ubyte sdl_slen;
+ ubyte[46] sdl_data;
+}
+
+auto LLADDR()(sockaddr_dl* s) { return cast(caddr_t)(s.sdl_data.ptr + s.sdl_nlen); }
+auto CLLADDR()(const sockaddr_dl* s) { return cast(c_caddr_t)(s.sdl_data.ptr + s.sdl_nlen); }
+ushort LLINDEX()(const sockaddr_dl* s) { return s.sdl_index; }
+
+struct ifnet;
+sockaddr_dl* link_alloc_sdl(size_t, int);
+void link_free_sdl(sockaddr* sa);
+sockaddr_dl* link_init_sdl(ifnet*, sockaddr*, ubyte);
+
+void link_addr(const char*, sockaddr_dl*);
+char* link_ntoa(const sockaddr_dl*);
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/socket.d b/libphobos/libdruntime/core/sys/freebsd/sys/socket.d
new file mode 100644
index 0000000..6d61286
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/socket.d
@@ -0,0 +1,131 @@
+//Written in the D programming language
+
+/++
+ D header file for FreeBSD's extensions to POSIX's sys/socket.h.
+
+ Copyright: Copyright 2023
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: $(HTTP jmdavisprog.com, Jonathan M Davis)
+ +/
+module core.sys.freebsd.sys.socket;
+
+public import core.sys.posix.sys.socket;
+
+version (FreeBSD):
+extern(C):
+@nogc:
+nothrow:
+
+// Creation flags, OR'ed into socket() and socketpair() type argument.
+enum : uint
+{
+ SOCK_CLOEXEC = 0x10000000,
+ SOCK_NONBLOCK = 0x20000000,
+}
+
+// Option flags per-socket.
+enum : uint
+{
+ SO_USELOOPBACK = 0x00000040,
+ SO_TIMESTAMP = 0x00000400,
+ SO_ACCEPTFILTER = 0x00001000,
+ SO_BINTIME = 0x00002000,
+
+ SO_NO_OFFLOAD = 0x00004000,
+ SO_NO_DDP = 0x00008000,
+ SO_REUSEPORT_LB = 0x00010000,
+ SO_RERROR = 0x00020000,
+}
+
+
+// Additional options, not kept in so_options.
+enum : uint
+{
+ SO_LABEL = 0x1009,
+ SO_PEERLABEL = 0x1010,
+ SO_LISTENQLIMIT = 0x1011,
+ SO_LISTENQLEN = 0x1012,
+ SO_LISTENINCQLEN = 0x1013,
+ SO_SETFIB = 0x1014,
+ SO_USER_COOKIE = 0x1015,
+ SO_PROTOCOL = 0x1016,
+ SO_PROTOTYPE = SO_PROTOCOL,
+ SO_TS_CLOCK = 0x1017,
+ SO_MAX_PACING_RATE = 0x1018,
+ SO_DOMAIN = 0x1019,
+
+ SO_TS_REALTIME_MICRO = 0,
+ SO_TS_BINTIME = 1,
+ SO_TS_REALTIME = 2,
+ SO_TS_MONOTONIC = 3,
+ SO_TS_DEFAULT = SO_TS_REALTIME_MICRO,
+ SO_TS_CLOCK_MAX = SO_TS_MONOTONIC,
+}
+
+/+
+ Space reserved for new socket options added by third-party vendors.
+ This range applies to all socket option levels. New socket options
+ in FreeBSD should always use an option value less than SO_VENDOR.
+ +/
+enum : uint
+{
+ SO_VENDOR = 0x80000000,
+}
+
+struct accept_filter_arg
+{
+ char[16] af_name;
+ char [256-16] af_arg;
+}
+
+// Address families.
+enum : uint
+{
+ AF_LOCAL = AF_UNIX,
+
+ AF_IMPLINK = 3,
+ AF_PUP = 4,
+ AF_CHAOS = 5,
+ AF_NETBIOS = 6,
+ AF_ISO = 7,
+ AF_OSI = AF_ISO,
+ AF_ECMA = 8,
+ AF_DATAKIT = 9,
+ AF_CCITT = 10,
+ AF_SNA = 11,
+ AF_DECnet = 12,
+ AF_DLI = 13,
+ AF_LAT = 14,
+ AF_HYLINK = 15,
+
+ AF_ROUTE = 17,
+ AF_LINK = 18,
+ pseudo_AF_XTP = 19,
+ AF_COIP = 20,
+ AF_CNT = 21,
+ pseudo_AF_RTIP = 22,
+
+ AF_SIP = 24,
+ pseudo_AF_PIP = 25,
+ AF_ISDN = 26,
+ AF_E164 = AF_ISDN,
+ pseudo_AF_KEY = 27,
+
+ AF_NATM = 29,
+ AF_ATM = 30,
+ pseudo_AF_HDRCMPLT = 31,
+ AF_NETGRAPH = 32,
+ AF_SLOW = 33,
+ AF_SCLUSTER = 34,
+ AF_ARP = 35,
+ AF_BLUETOOTH = 36,
+ AF_IEEE80211 = 37,
+ AF_NETLINK = 38,
+
+ AF_INET_SDP = 40,
+
+ AF_INET6_SDP = 42,
+ AF_HYPERV = 43,
+ AF_DIVERT = 44,
+ AF_MAX = 44,
+}
diff --git a/libphobos/libdruntime/core/sys/freebsd/sys/types.d b/libphobos/libdruntime/core/sys/freebsd/sys/types.d
new file mode 100644
index 0000000..b927ddf
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/freebsd/sys/types.d
@@ -0,0 +1,58 @@
+//Written in the D programming language
+
+/++
+ D header file for FreeBSD's extensions to POSIX's sys/types.h.
+
+ Copyright: Copyright 2023
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: $(HTTP jmdavisprog.com, Jonathan M Davis)
+ +/
+module core.sys.freebsd.sys.types;
+
+public import core.sys.posix.sys.types;
+
+version (FreeBSD):
+extern(C):
+@nogc:
+nothrow:
+
+import core.stdc.config;
+
+alias caddr_t = ubyte*;
+alias c_caddr_t = const(ubyte)*;
+
+alias cpuwhich_t = int;
+alias cpulevel_t = int;
+alias cpusetid_t = int;
+
+alias critical_t = size_t;
+alias daddr_t = long;
+
+alias fixpt_t = uint;
+
+alias accmode_t = int;
+
+alias register_t = size_t;
+
+alias sbintime_t = long;
+
+alias segsz_t = size_t;
+
+alias u_register_t = size_t;
+
+alias cap_ioctl_t = size_t;
+
+alias kpaddr_t = ulong;
+alias kvaddr_t = ulong;
+alias ksize_t = ulong;
+alias kssize_t = long;
+
+alias vm_offset_t = size_t;
+alias vm_ooffset_t = ulong;
+alias vm_paddr_t = ulong;
+alias vm_pindex_t = ulong;
+alias vm_size_t = size_t;
+
+alias rman_res_t = ulong;
+
+alias syscallarg_t = register_t;
diff --git a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d
index f0ce29f..642b383 100644
--- a/libphobos/libdruntime/core/sys/posix/sys/types.d
+++ b/libphobos/libdruntime/core/sys/posix/sys/types.d
@@ -187,7 +187,7 @@ else version (FreeBSD)
alias c_long ssize_t;
alias c_long time_t;
alias uint uid_t;
- alias uint fflags_t;
+ alias uint fflags_t; // non-standard
}
else version (NetBSD)
{
@@ -866,7 +866,7 @@ else version (Darwin)
}
else version (FreeBSD)
{
- alias int lwpid_t;
+ alias int lwpid_t; // non-standard
alias void* pthread_attr_t;
alias void* pthread_cond_t;
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index 294d34d..0111be0 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -4668,6 +4668,7 @@ version (D_ProfileGC)
public import core.internal.array.appending : _d_arrayappendTTrace;
public import core.internal.array.concatenation : _d_arraycatnTXTrace;
public import core.lifetime : _d_newitemTTrace;
+ public import core.internal.array.construction : _d_newarrayTTrace;
}
public import core.internal.array.appending : _d_arrayappendcTXImpl;
public import core.internal.array.comparison : __cmp;
@@ -4676,6 +4677,7 @@ public import core.internal.array.casting: __ArrayCast;
public import core.internal.array.concatenation : _d_arraycatnTX;
public import core.internal.array.construction : _d_arrayctor;
public import core.internal.array.construction : _d_arraysetctor;
+public import core.internal.array.construction : _d_newarrayT;
public import core.internal.array.arrayassign : _d_arrayassign_l;
public import core.internal.array.arrayassign : _d_arrayassign_r;
public import core.internal.array.arrayassign : _d_arraysetassign;
diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index 1245374..af3c6bb 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -13,6 +13,7 @@
module rt.lifetime;
import core.attribute : weak;
+import core.internal.array.utils : __arrayStart, __arrayClearPad;
import core.memory;
debug(PRINTF) import core.stdc.stdio;
static import rt.tlsgc;
@@ -226,7 +227,6 @@ size_t structTypeInfoSize(const TypeInfo ti) pure nothrow @nogc
private class ArrayAllocLengthLock
{}
-
/**
Set the allocated length of the array block. This is called
any time an array is appended to or its length is set.
@@ -387,14 +387,6 @@ private size_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure
}
/**
- get the start of the array for the given block
- */
-private void *__arrayStart(return scope BlkInfo info) nothrow pure
-{
- return info.base + ((info.size & BIGLENGTHMASK) ? LARGEPREFIX : 0);
-}
-
-/**
get the padding required to allocate size bytes. Note that the padding is
NOT included in the passed in size. Therefore, do NOT call this function
with the size of an allocated block.
@@ -405,22 +397,6 @@ private size_t __arrayPad(size_t size, const TypeInfo tinext) nothrow pure @trus
}
/**
- clear padding that might not be zeroed by the GC (it assumes it is within the
- requested size from the start, but it is actually at the end of the allocated block)
- */
-private void __arrayClearPad(ref BlkInfo info, size_t arrsize, size_t padsize) nothrow pure
-{
- import core.stdc.string;
- if (padsize > MEDPAD && !(info.attr & BlkAttr.NO_SCAN) && info.base)
- {
- if (info.size < PAGESIZE)
- memset(info.base + arrsize, 0, padsize);
- else
- memset(info.base, 0, LARGEPREFIX);
- }
-}
-
-/**
allocate an array memory block by applying the proper padding and
assigning block attributes if not inherited from the existing block
*/
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index 9a97927..a7bf856 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-d945686a4ff7d9fda0e2ee8d2ee201b66be2a287
+2458e8f82e3004197d8a66239a6b72e17264bb26
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/parallelism.d b/libphobos/src/std/parallelism.d
index 9b231f3..3fe8cd6 100644
--- a/libphobos/src/std/parallelism.d
+++ b/libphobos/src/std/parallelism.d
@@ -1581,7 +1581,7 @@ public:
auto logs = new double[10_000_000];
// Parallel foreach works with or without an index
- // variable. It can be iterate by ref if range.front
+ // variable. It can iterate by ref if range.front
// returns by ref.
// Iterate over logs using work units of size 100.
diff --git a/libphobos/src/std/range/primitives.d b/libphobos/src/std/range/primitives.d
index ef34a85..1a3fb06 100644
--- a/libphobos/src/std/range/primitives.d
+++ b/libphobos/src/std/range/primitives.d
@@ -540,13 +540,9 @@ private void putChar(R, E)(ref R r, E e)
if (isSomeChar!E)
{
// https://issues.dlang.org/show_bug.cgi?id=9186: Can't use (E[]).init
- ref const( char)[] cstringInit();
- ref const(wchar)[] wstringInit();
- ref const(dchar)[] dstringInit();
-
- enum csCond = is(typeof(doPut(r, cstringInit())));
- enum wsCond = is(typeof(doPut(r, wstringInit())));
- enum dsCond = is(typeof(doPut(r, dstringInit())));
+ enum csCond = is(typeof(doPut(r, (){ ref const( char)[] cstringInit(); return cstringInit(); }())));
+ enum wsCond = is(typeof(doPut(r, (){ ref const(wchar)[] wstringInit(); return wstringInit(); }())));
+ enum dsCond = is(typeof(doPut(r, (){ ref const(dchar)[] dstringInit(); return dstringInit(); }())));
//Use "max" to avoid static type demotion
enum ccCond = is(typeof(doPut(r, char.max)));
diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d
index 2ed7ee5..aa69aac 100644
--- a/libphobos/src/std/traits.d
+++ b/libphobos/src/std/traits.d
@@ -67,6 +67,7 @@
* $(LREF isAssignable)
* $(LREF isCovariantWith)
* $(LREF isImplicitlyConvertible)
+ * $(LREF isQualifierConvertible)
* ))
* $(TR $(TD Type Constructors) $(TD
* $(LREF InoutOf)
@@ -5167,6 +5168,62 @@ enum bool isImplicitlyConvertible(From, To) = is(From : To);
}
/**
+Is `From` $(DDSUBLINK spec/const3, implicit_qualifier_conversions, qualifier-convertible) to `To`?
+*/
+enum bool isQualifierConvertible(From, To) =
+ is(immutable From == immutable To) && is(From* : To*);
+
+///
+@safe unittest
+{
+ // Mutable and immmutable both convert to const...
+ static assert( isQualifierConvertible!(char, const(char)));
+ static assert( isQualifierConvertible!(immutable(char), const(char)));
+ // ...but const does not convert back to mutable or immutable
+ static assert(!isQualifierConvertible!(const(char), char));
+ static assert(!isQualifierConvertible!(const(char), immutable(char)));
+}
+
+@safe unittest
+{
+ import std.meta : AliasSeq;
+
+ alias Ts = AliasSeq!(int, const int, shared int, inout int, const shared int,
+ const inout int, inout shared int, const inout shared int, immutable int);
+
+ // https://dlang.org/spec/const3.html#implicit_qualifier_conversions
+ enum _ = 0;
+ static immutable bool[Ts.length][Ts.length] conversions = [
+ // m c s i cs ci is cis im
+ [1, 1, _, _, _, _, _, _, _], // mutable
+ [_, 1, _, _, _, _, _, _, _], // const
+ [_, _, 1, _, 1, _, _, _, _], // shared
+ [_, 1, _, 1, _, 1, _, _, _], // inout
+ [_, _, _, _, 1, _, _, _, _], // const shared
+ [_, 1, _, _, _, 1, _, _, _], // const inout
+ [_, _, _, _, 1, _, 1, 1, _], // inout shared
+ [_, _, _, _, 1, _, _, 1, _], // const inout shared
+ [_, 1, _, _, 1, 1, _, 1, 1], // immutable
+ ];
+
+ static foreach (i, From; Ts)
+ {
+ static foreach (j, To; Ts)
+ {
+ static assert(isQualifierConvertible!(From, To) == conversions[i][j],
+ "`isQualifierConvertible!(" ~ From.stringof ~ ", " ~ To.stringof ~ ")`"
+ ~ " should be `" ~ (conversions[i][j] ? "true" : "false") ~ "`");
+ }
+ }
+}
+
+@safe unittest
+{
+ // int* -> void* is not a qualifier conversion
+ static assert(!isQualifierConvertible!(int, void));
+}
+
+/**
Returns `true` iff a value of type `Rhs` can be assigned to a variable of
type `Lhs`.