aboutsummaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-07-10 17:16:17 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2023-07-10 23:31:29 +0200
commite9251fea2debebfebe1f762a4a8d5b3b1d4c75ef (patch)
tree09b47f4d760019131aa27d19bfb8e5ee0f1ed31f /libphobos
parent2d7c95e31431a297060c94697af84f498abf97a2 (diff)
downloadgcc-e9251fea2debebfebe1f762a4a8d5b3b1d4c75ef.zip
gcc-e9251fea2debebfebe1f762a4a8d5b3b1d4c75ef.tar.gz
gcc-e9251fea2debebfebe1f762a4a8d5b3b1d4c75ef.tar.bz2
d: Merge upstream dmd, druntime a88e1335f7, phobos 1921d29df.
D front-end changes: - Import dmd v2.104.1. - Deprecation phase ended for access to private method when overloaded with public method. D runtime changes: - Import druntime v2.104.1. - Linux input header translations were added to druntime. - Integration with the Valgrind `memcheck' tool has been added to the garbage collector. Phobos changes: - Import phobos v2.104.1. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd a88e1335f7. * dmd/VERSION: Bump version to v2.104.1. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime a88e1335f7. * src/MERGE: Merge upstream phobos 1921d29df. * config.h.in: Regenerate. * configure: Regenerate. * configure.ac (libphobos-checking): Add valgrind flag. (DRUNTIME_LIBRARIES_VALGRIND): Call. * libdruntime/Makefile.am (DRUNTIME_CSOURCES): Add etc/valgrind/valgrind_.c. (DRUNTIME_DSOURCES): Add etc/valgrind/valgrind.d. (DRUNTIME_DSOURCES_LINUX): Add core/sys/linux/input.d, core/sys/linux/input_event_codes.d, core/sys/linux/uinput.d. * libdruntime/Makefile.in: Regenerate. * m4/druntime/libraries.m4 (DRUNTIME_LIBRARIES_VALGRIND): Define.
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/config.h.in12
-rwxr-xr-xlibphobos/configure101
-rw-r--r--libphobos/configure.ac16
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/Makefile.am16
-rw-r--r--libphobos/libdruntime/Makefile.in58
-rw-r--r--libphobos/libdruntime/core/atomic.d10
-rw-r--r--libphobos/libdruntime/core/internal/array/concatenation.d17
-rw-r--r--libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d131
-rw-r--r--libphobos/libdruntime/core/internal/gc/proxy.d7
-rw-r--r--libphobos/libdruntime/core/internal/parseoptions.d12
-rw-r--r--libphobos/libdruntime/core/lifetime.d10
-rw-r--r--libphobos/libdruntime/core/stdc/assert_.d13
-rw-r--r--libphobos/libdruntime/core/stdc/wchar_.d5
-rw-r--r--libphobos/libdruntime/core/sys/linux/input.d236
-rw-r--r--libphobos/libdruntime/core/sys/linux/input_event_codes.d758
-rw-r--r--libphobos/libdruntime/core/sys/linux/uinput.d85
-rw-r--r--libphobos/libdruntime/core/sys/openbsd/unistd.d4
-rw-r--r--libphobos/libdruntime/core/sys/windows/dll.d49
-rw-r--r--libphobos/libdruntime/etc/valgrind/valgrind.d85
-rw-r--r--libphobos/libdruntime/etc/valgrind/valgrind_.c102
-rw-r--r--libphobos/libdruntime/object.d40
-rw-r--r--libphobos/libdruntime/rt/lifetime.d12
-rw-r--r--libphobos/libdruntime/rt/minfo.d4
-rw-r--r--libphobos/libdruntime/rt/util/typeinfo.d2
-rw-r--r--libphobos/m4/druntime/libraries.m453
-rw-r--r--libphobos/src/MERGE2
-rw-r--r--libphobos/src/std/algorithm/iteration.d4
-rw-r--r--libphobos/src/std/algorithm/mutation.d2
-rw-r--r--libphobos/src/std/algorithm/searching.d48
-rw-r--r--libphobos/src/std/complex.d4
-rw-r--r--libphobos/src/std/container/array.d2
-rw-r--r--libphobos/src/std/conv.d22
-rw-r--r--libphobos/src/std/exception.d2
-rw-r--r--libphobos/src/std/experimental/allocator/building_blocks/kernighan_ritchie.d2
-rw-r--r--libphobos/src/std/format/internal/floats.d12
-rw-r--r--libphobos/src/std/format/internal/write.d8
-rw-r--r--libphobos/src/std/math/operations.d15
-rw-r--r--libphobos/src/std/path.d22
-rw-r--r--libphobos/src/std/random.d4
-rw-r--r--libphobos/src/std/range/package.d41
-rw-r--r--libphobos/src/std/regex/internal/ir.d25
-rw-r--r--libphobos/src/std/signals.d4
-rw-r--r--libphobos/src/std/stdio.d90
-rw-r--r--libphobos/src/std/traits.d6
-rw-r--r--libphobos/src/std/typecons.d134
-rw-r--r--libphobos/src/std/uni/package.d39
47 files changed, 2096 insertions, 232 deletions
diff --git a/libphobos/config.h.in b/libphobos/config.h.in
index 0249849..6ecb3f2 100644
--- a/libphobos/config.h.in
+++ b/libphobos/config.h.in
@@ -1,14 +1,23 @@
/* config.h.in. Generated from configure.ac by autoheader. */
+/* Define to enable to integrate valgrind (a memory checker) in the GC. */
+#undef ENABLE_VALGRIND_CHECKING
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define if valgrind's memcheck.h header is installed. */
+#undef HAVE_MEMCHECK_H
+
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
@@ -30,6 +39,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define if valgrind's valgrind/memcheck.h header is installed. */
+#undef HAVE_VALGRIND_MEMCHECK_H
+
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
diff --git a/libphobos/configure b/libphobos/configure
index 925c53c..d702c8f 100755
--- a/libphobos/configure
+++ b/libphobos/configure
@@ -1498,8 +1498,8 @@ Optional Features:
--enable-libphobos-checking[=LIST]
enable expensive run-time checks. With LIST, enable
only specific categories of checks. Categories are:
- yes,no,all,none,release. Flags are: assert or other
- strings
+ yes,no,all,none,release. Flags are: assert,valgrind
+ or other strings
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -15553,16 +15553,20 @@ for check in release $ac_checking_flags
do
case $check in
# These set all the flags to specific states
- yes|all) RELEASE_FLAG="-fno-release" ; ASSERT_FLAG= ;;
- no|none|release) RELEASE_FLAG="-frelease" ; ASSERT_FLAG= ;;
+ yes|all) RELEASE_FLAG="-fno-release" ; ASSERT_FLAG= ;
+ VALGRIND_FLAG= ;;
+ no|none|release) RELEASE_FLAG="-frelease" ; ASSERT_FLAG= ;
+ VALGRIND_FLAG= ;;
# These enable particular checks
- assert) ASSERT_FLAG="-fassert" ;;
+ assert) ASSERT_FLAG="-fassert" ;;
+ valgrind) VALGRIND_FLAG="-fdebug=VALGRIND" ;;
# Accept
*) ;;
esac
done
IFS="$ac_save_IFS"
-CHECKING_DFLAGS="$RELEASE_FLAG $ASSERT_FLAG"
+CHECKING_DFLAGS="$RELEASE_FLAG $ASSERT_FLAG $VALGRIND_FLAG"
+
# Add drtbegin.o/drtend.o to startfile/endfile specs in libgphobos.spec
@@ -15600,6 +15604,91 @@ fi
+
+ for ac_header in stddef.h stdlib.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "valgrind.h" "ac_cv_header_valgrind_h" "$ac_includes_default"
+if test "x$ac_cv_header_valgrind_h" = xyes; then :
+ have_valgrind_h=yes
+else
+ have_valgrind_h=no
+fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <valgrind/memcheck.h>" >&5
+$as_echo_n "checking for VALGRIND_DISCARD in <valgrind/memcheck.h>... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <valgrind/memcheck.h>
+ #ifndef VALGRIND_DISCARD
+ #error VALGRIND_DISCARD not defined
+ #endif
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ have_valgrind_memcheck_h=yes
+else
+ have_valgrind_memcheck_h=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_valgrind_memcheck_h" >&5
+$as_echo "$have_valgrind_memcheck_h" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <memcheck.h>" >&5
+$as_echo_n "checking for VALGRIND_DISCARD in <memcheck.h>... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <memcheck.h>
+ #ifndef VALGRIND_DISCARD
+ #error VALGRIND_DISCARD not defined
+ #endif
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ have_memcheck_h=yes
+else
+ have_memcheck_h=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_memcheck_h" >&5
+$as_echo "$have_memcheck_h" >&6; }
+
+ if test x$VALGRIND_FLAG != x ; then
+
+$as_echo "#define ENABLE_VALGRIND_CHECKING 1" >>confdefs.h
+
+ fi
+ if test $have_valgrind_memcheck_h = yes; then
+
+$as_echo "#define HAVE_VALGRIND_MEMCHECK_H 1" >>confdefs.h
+
+ fi
+ if test $have_memcheck_h = yes; then
+
+$as_echo "#define HAVE_MEMCHECK_H 1" >>confdefs.h
+
+ fi
+
+ if test x$VALGRIND_FLAG != x; then
+ if (test $have_valgrind_h = no \
+ && test $have_memcheck_h = no \
+ && test $have_valgrind_memcheck_h = no); then
+ as_fn_error $? "*** valgrind checking requested, but
+*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h" "$LINENO" 5
+ fi
+ fi
+
+
ac_config_files="$ac_config_files Makefile"
diff --git a/libphobos/configure.ac b/libphobos/configure.ac
index 464f410..3b2e6df 100644
--- a/libphobos/configure.ac
+++ b/libphobos/configure.ac
@@ -221,25 +221,29 @@ AC_ARG_ENABLE(libphobos-checking,
[enable expensive run-time checks. With LIST,
enable only specific categories of checks.
Categories are: yes,no,all,none,release.
- Flags are: assert or other strings])],
+ Flags are: assert,valgrind or other strings])],
[ac_checking_flags="${enableval}"],[ac_checking_flags=release])
IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="$IFS,"
for check in release $ac_checking_flags
do
case $check in
# These set all the flags to specific states
- yes|all) RELEASE_FLAG="-fno-release" ; ASSERT_FLAG= ;;
- no|none|release) RELEASE_FLAG="-frelease" ; ASSERT_FLAG= ;;
+ yes|all) RELEASE_FLAG="-fno-release" ; ASSERT_FLAG= ;
+ VALGRIND_FLAG= ;;
+ no|none|release) RELEASE_FLAG="-frelease" ; ASSERT_FLAG= ;
+ VALGRIND_FLAG= ;;
# These enable particular checks
- assert) ASSERT_FLAG="-fassert" ;;
+ assert) ASSERT_FLAG="-fassert" ;;
+ valgrind) VALGRIND_FLAG="-fdebug=VALGRIND" ;;
# Accept
*) ;;
esac
done
IFS="$ac_save_IFS"
-CHECKING_DFLAGS="$RELEASE_FLAG $ASSERT_FLAG"
+CHECKING_DFLAGS="$RELEASE_FLAG $ASSERT_FLAG $VALGRIND_FLAG"
AC_SUBST(CHECKING_DFLAGS)
+
# Add drtbegin.o/drtend.o to startfile/endfile specs in libgphobos.spec
if test "$DCFG_MINFO_BRACKETING" = "false"; then
DRTSTUFF_SPEC=$srcdir/src/drtstuff.spec
@@ -269,6 +273,8 @@ AC_SUBST(WARN_DFLAGS)
AC_CHECK_HEADER(stdio.h,:,
[AC_MSG_ERROR([cannot find stdio.h.])])
+DRUNTIME_LIBRARIES_VALGRIND
+
AC_CONFIG_FILES(Makefile)
AC_CONFIG_FILES(libdruntime/gcc/config.d libdruntime/gcc/libbacktrace.d)
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 1cff48a..308d51b 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-17ccd12af386543c0b9935bf7e0a8e701b903105
+a88e1335f7ea767ef438c34998f5d1f26008c586
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/Makefile.am b/libphobos/libdruntime/Makefile.am
index 8225ba4..832a052 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -165,7 +165,7 @@ install-data-local:
# Can't use wildcards here:
# https://www.gnu.org/software/automake/manual/html_node/Wildcards.html
-DRUNTIME_CSOURCES = core/stdc/errno_.c
+DRUNTIME_CSOURCES = core/stdc/errno_.c etc/valgrind/valgrind_.c
DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/builtins.d core/checkedint.d core/cpuid.d core/demangle.d \
@@ -205,11 +205,11 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/sync/semaphore.d core/thread/context.d core/thread/fiber.d \
core/thread/osthread.d core/thread/package.d core/thread/threadbase.d \
core/thread/threadgroup.d core/thread/types.d core/time.d \
- core/vararg.d core/volatile.d gcc/attribute.d gcc/attributes.d \
- gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
- gcc/sections/common.d gcc/sections/elf.d gcc/sections/macho.d \
- gcc/sections/package.d gcc/sections/pecoff.d gcc/simd.d \
- gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \
+ core/vararg.d core/volatile.d etc/valgrind/valgrind.d gcc/attribute.d \
+ gcc/attributes.d gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d \
+ gcc/gthread.d gcc/sections/common.d gcc/sections/elf.d \
+ gcc/sections/macho.d gcc/sections/package.d gcc/sections/pecoff.d \
+ gcc/simd.d gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \
gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \
rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arraycat.d rt/cast_.d \
rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d rt/ehalloc.d \
@@ -273,6 +273,7 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \
core/sys/linux/err.d core/sys/linux/errno.d core/sys/linux/execinfo.d \
core/sys/linux/fcntl.d core/sys/linux/fs.d core/sys/linux/ifaddrs.d \
+ core/sys/linux/input.d core/sys/linux/input_event_codes.d \
core/sys/linux/io_uring.d core/sys/linux/link.d \
core/sys/linux/netinet/in_.d core/sys/linux/netinet/tcp.d \
core/sys/linux/perf_event.d core/sys/linux/sched.d \
@@ -284,7 +285,8 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.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/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/timerfd.d core/sys/linux/tipc.d core/sys/linux/uinput.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 797d643..61a2a77 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -235,12 +235,12 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
core/thread/osthread.lo core/thread/package.lo \
core/thread/threadbase.lo core/thread/threadgroup.lo \
core/thread/types.lo core/time.lo core/vararg.lo \
- core/volatile.lo gcc/attribute.lo gcc/attributes.lo \
- gcc/backtrace.lo gcc/builtins.lo gcc/deh.lo gcc/emutls.lo \
- gcc/gthread.lo gcc/sections/common.lo gcc/sections/elf.lo \
- gcc/sections/macho.lo gcc/sections/package.lo \
- gcc/sections/pecoff.lo gcc/simd.lo gcc/unwind/arm.lo \
- gcc/unwind/arm_common.lo gcc/unwind/c6x.lo \
+ core/volatile.lo etc/valgrind/valgrind.lo gcc/attribute.lo \
+ gcc/attributes.lo gcc/backtrace.lo gcc/builtins.lo gcc/deh.lo \
+ gcc/emutls.lo gcc/gthread.lo gcc/sections/common.lo \
+ gcc/sections/elf.lo gcc/sections/macho.lo \
+ gcc/sections/package.lo gcc/sections/pecoff.lo gcc/simd.lo \
+ gcc/unwind/arm.lo gcc/unwind/arm_common.lo gcc/unwind/c6x.lo \
gcc/unwind/generic.lo gcc/unwind/package.lo gcc/unwind/pe.lo \
object.lo rt/aApply.lo rt/aApplyR.lo rt/aaA.lo rt/adi.lo \
rt/arraycat.lo rt/cast_.lo rt/config.lo rt/critical_.lo \
@@ -248,7 +248,8 @@ am__objects_1 = core/atomic.lo core/attribute.lo core/bitop.lo \
rt/lifetime.lo rt/memory.lo rt/minfo.lo rt/monitor_.lo \
rt/profilegc.lo rt/sections.lo rt/tlsgc.lo rt/util/typeinfo.lo \
rt/util/utility.lo
-am__objects_2 = core/stdc/libgdruntime_la-errno_.lo
+am__objects_2 = core/stdc/libgdruntime_la-errno_.lo \
+ etc/valgrind/libgdruntime_la-valgrind_.lo
am__objects_3 = core/sys/elf/package.lo
am__objects_4 = core/stdcpp/allocator.lo core/stdcpp/array.lo \
core/stdcpp/exception.lo core/stdcpp/memory.lo \
@@ -363,6 +364,7 @@ am__objects_19 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
core/sys/linux/err.lo core/sys/linux/errno.lo \
core/sys/linux/execinfo.lo core/sys/linux/fcntl.lo \
core/sys/linux/fs.lo core/sys/linux/ifaddrs.lo \
+ core/sys/linux/input.lo core/sys/linux/input_event_codes.lo \
core/sys/linux/io_uring.lo core/sys/linux/link.lo \
core/sys/linux/netinet/in_.lo core/sys/linux/netinet/tcp.lo \
core/sys/linux/perf_event.lo core/sys/linux/sched.lo \
@@ -375,7 +377,7 @@ am__objects_19 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
core/sys/linux/sys/time.lo core/sys/linux/sys/xattr.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/uinput.lo core/sys/linux/unistd.lo
@DRUNTIME_OS_LINUX_TRUE@am__objects_20 = $(am__objects_19)
am__objects_21 = core/sys/windows/accctrl.lo \
core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \
@@ -497,7 +499,8 @@ am__objects_35 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
am_libgdruntime_la_OBJECTS = $(am__objects_35)
libgdruntime_la_OBJECTS = $(am_libgdruntime_la_OBJECTS)
am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
-am__objects_36 = core/stdc/libgdruntime_convenience_la-errno_.lo
+am__objects_36 = core/stdc/libgdruntime_convenience_la-errno_.lo \
+ etc/valgrind/libgdruntime_convenience_la-valgrind_.lo
@DRUNTIME_OS_MINGW_TRUE@am__objects_37 = $(am__objects_21) \
@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_convenience_la-msvc.lo
@DRUNTIME_CPU_AARCH64_TRUE@am__objects_38 = config/aarch64/libgdruntime_convenience_la-switchcontext.lo
@@ -836,7 +839,7 @@ libgdruntime_convenience_la_LINK = $(libgdruntime_la_LINK)
# https://gist.github.com/jpf91/8ad1dbc9902d6ad876313f134c6527d1
# Can't use wildcards here:
# https://www.gnu.org/software/automake/manual/html_node/Wildcards.html
-DRUNTIME_CSOURCES = core/stdc/errno_.c
+DRUNTIME_CSOURCES = core/stdc/errno_.c etc/valgrind/valgrind_.c
DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/builtins.d core/checkedint.d core/cpuid.d core/demangle.d \
core/exception.d core/factory.d core/gc/config.d core/gc/gcinterface.d \
@@ -875,11 +878,11 @@ DRUNTIME_DSOURCES = core/atomic.d core/attribute.d core/bitop.d \
core/sync/semaphore.d core/thread/context.d core/thread/fiber.d \
core/thread/osthread.d core/thread/package.d core/thread/threadbase.d \
core/thread/threadgroup.d core/thread/types.d core/time.d \
- core/vararg.d core/volatile.d gcc/attribute.d gcc/attributes.d \
- gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d gcc/gthread.d \
- gcc/sections/common.d gcc/sections/elf.d gcc/sections/macho.d \
- gcc/sections/package.d gcc/sections/pecoff.d gcc/simd.d \
- gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \
+ core/vararg.d core/volatile.d etc/valgrind/valgrind.d gcc/attribute.d \
+ gcc/attributes.d gcc/backtrace.d gcc/builtins.d gcc/deh.d gcc/emutls.d \
+ gcc/gthread.d gcc/sections/common.d gcc/sections/elf.d \
+ gcc/sections/macho.d gcc/sections/package.d gcc/sections/pecoff.d \
+ gcc/simd.d gcc/unwind/arm.d gcc/unwind/arm_common.d gcc/unwind/c6x.d \
gcc/unwind/generic.d gcc/unwind/package.d gcc/unwind/pe.d object.d \
rt/aApply.d rt/aApplyR.d rt/aaA.d rt/adi.d rt/arraycat.d rt/cast_.d \
rt/config.d rt/critical_.d rt/deh.d rt/dmain2.d rt/ehalloc.d \
@@ -942,6 +945,7 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.d \
core/sys/linux/dlfcn.d core/sys/linux/elf.d core/sys/linux/epoll.d \
core/sys/linux/err.d core/sys/linux/errno.d core/sys/linux/execinfo.d \
core/sys/linux/fcntl.d core/sys/linux/fs.d core/sys/linux/ifaddrs.d \
+ core/sys/linux/input.d core/sys/linux/input_event_codes.d \
core/sys/linux/io_uring.d core/sys/linux/link.d \
core/sys/linux/netinet/in_.d core/sys/linux/netinet/tcp.d \
core/sys/linux/perf_event.d core/sys/linux/sched.d \
@@ -953,7 +957,8 @@ DRUNTIME_DSOURCES_LINUX = core/sys/linux/config.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/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/timerfd.d core/sys/linux/tipc.d core/sys/linux/uinput.d \
+ core/sys/linux/unistd.d
DRUNTIME_DSOURCES_NETBSD = core/sys/netbsd/dlfcn.d \
core/sys/netbsd/err.d core/sys/netbsd/execinfo.d \
@@ -1331,6 +1336,10 @@ core/thread/types.lo: core/thread/$(am__dirstamp)
core/time.lo: core/$(am__dirstamp)
core/vararg.lo: core/$(am__dirstamp)
core/volatile.lo: core/$(am__dirstamp)
+etc/valgrind/$(am__dirstamp):
+ @$(MKDIR_P) etc/valgrind
+ @: > etc/valgrind/$(am__dirstamp)
+etc/valgrind/valgrind.lo: etc/valgrind/$(am__dirstamp)
gcc/$(am__dirstamp):
@$(MKDIR_P) gcc
@: > gcc/$(am__dirstamp)
@@ -1387,6 +1396,8 @@ rt/util/$(am__dirstamp):
rt/util/typeinfo.lo: rt/util/$(am__dirstamp)
rt/util/utility.lo: rt/util/$(am__dirstamp)
core/stdc/libgdruntime_la-errno_.lo: core/stdc/$(am__dirstamp)
+etc/valgrind/libgdruntime_la-valgrind_.lo: \
+ etc/valgrind/$(am__dirstamp)
core/sys/elf/$(am__dirstamp):
@$(MKDIR_P) core/sys/elf
@: > core/sys/elf/$(am__dirstamp)
@@ -1668,6 +1679,8 @@ core/sys/linux/execinfo.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/fcntl.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/fs.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/ifaddrs.lo: core/sys/linux/$(am__dirstamp)
+core/sys/linux/input.lo: core/sys/linux/$(am__dirstamp)
+core/sys/linux/input_event_codes.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/io_uring.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/link.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/netinet/$(am__dirstamp):
@@ -1698,6 +1711,7 @@ 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)
core/sys/linux/tipc.lo: core/sys/linux/$(am__dirstamp)
+core/sys/linux/uinput.lo: core/sys/linux/$(am__dirstamp)
core/sys/linux/unistd.lo: core/sys/linux/$(am__dirstamp)
core/sys/windows/$(am__dirstamp):
@$(MKDIR_P) core/sys/windows
@@ -1951,6 +1965,8 @@ libgdruntime.la: $(libgdruntime_la_OBJECTS) $(libgdruntime_la_DEPENDENCIES) $(EX
$(AM_V_GEN)$(libgdruntime_la_LINK) -rpath $(toolexeclibdir) $(libgdruntime_la_OBJECTS) $(libgdruntime_la_LIBADD) $(LIBS)
core/stdc/libgdruntime_convenience_la-errno_.lo: \
core/stdc/$(am__dirstamp)
+etc/valgrind/libgdruntime_convenience_la-valgrind_.lo: \
+ etc/valgrind/$(am__dirstamp)
config/mingw/libgdruntime_convenience_la-msvc.lo: \
config/mingw/$(am__dirstamp)
config/aarch64/libgdruntime_convenience_la-switchcontext.lo: \
@@ -2077,6 +2093,8 @@ mostlyclean-compile:
-rm -f core/sys/windows/stdc/*.lo
-rm -f core/thread/*.$(OBJEXT)
-rm -f core/thread/*.lo
+ -rm -f etc/valgrind/*.$(OBJEXT)
+ -rm -f etc/valgrind/*.lo
-rm -f gcc/*.$(OBJEXT)
-rm -f gcc/*.lo
-rm -f gcc/sections/*.$(OBJEXT)
@@ -2160,12 +2178,18 @@ config/s390/libgdruntime_convenience_la-get_tls_offset.lo: config/s390/get_tls_o
core/stdc/libgdruntime_la-errno_.lo: core/stdc/errno_.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
+etc/valgrind/libgdruntime_la-valgrind_.lo: etc/valgrind/valgrind_.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o etc/valgrind/libgdruntime_la-valgrind_.lo `test -f 'etc/valgrind/valgrind_.c' || echo '$(srcdir)/'`etc/valgrind/valgrind_.c
+
config/mingw/libgdruntime_la-msvc.lo: config/mingw/msvc.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config/mingw/libgdruntime_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
core/stdc/libgdruntime_convenience_la-errno_.lo: core/stdc/errno_.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o core/stdc/libgdruntime_convenience_la-errno_.lo `test -f 'core/stdc/errno_.c' || echo '$(srcdir)/'`core/stdc/errno_.c
+etc/valgrind/libgdruntime_convenience_la-valgrind_.lo: etc/valgrind/valgrind_.c
+ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o etc/valgrind/libgdruntime_convenience_la-valgrind_.lo `test -f 'etc/valgrind/valgrind_.c' || echo '$(srcdir)/'`etc/valgrind/valgrind_.c
+
config/mingw/libgdruntime_convenience_la-msvc.lo: config/mingw/msvc.c
$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgdruntime_convenience_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config/mingw/libgdruntime_convenience_la-msvc.lo `test -f 'config/mingw/msvc.c' || echo '$(srcdir)/'`config/mingw/msvc.c
@@ -2225,6 +2249,7 @@ clean-libtool:
-rm -rf core/sys/windows/.libs core/sys/windows/_libs
-rm -rf core/sys/windows/stdc/.libs core/sys/windows/stdc/_libs
-rm -rf core/thread/.libs core/thread/_libs
+ -rm -rf etc/valgrind/.libs etc/valgrind/_libs
-rm -rf gcc/.libs gcc/_libs
-rm -rf gcc/sections/.libs gcc/sections/_libs
-rm -rf gcc/unwind/.libs gcc/unwind/_libs
@@ -2387,6 +2412,7 @@ distclean-generic:
-rm -f core/sys/windows/$(am__dirstamp)
-rm -f core/sys/windows/stdc/$(am__dirstamp)
-rm -f core/thread/$(am__dirstamp)
+ -rm -f etc/valgrind/$(am__dirstamp)
-rm -f gcc/$(am__dirstamp)
-rm -f gcc/sections/$(am__dirstamp)
-rm -f gcc/unwind/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/atomic.d b/libphobos/libdruntime/core/atomic.d
index 5a7d00c..ff7f7ab 100644
--- a/libphobos/libdruntime/core/atomic.d
+++ b/libphobos/libdruntime/core/atomic.d
@@ -85,7 +85,7 @@ enum MemoryOrder
* Returns:
* The value of 'val'.
*/
-T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(ref return scope const T val) pure nothrow @nogc @trusted
+T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(auto ref return scope const T val) pure nothrow @nogc @trusted
if (!is(T == shared U, U) && !is(T == shared inout U, U) && !is(T == shared const U, U))
{
static if (__traits(isFloating, T))
@@ -99,7 +99,7 @@ T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(ref return scope const T val)
}
/// Ditto
-T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(ref return scope shared const T val) pure nothrow @nogc @trusted
+T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(auto ref return scope shared const T val) pure nothrow @nogc @trusted
if (!hasUnsharedIndirections!T)
{
import core.internal.traits : hasUnsharedIndirections;
@@ -109,7 +109,7 @@ T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(ref return scope shared const
}
/// Ditto
-TailShared!T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(ref shared const T val) pure nothrow @nogc @trusted
+TailShared!T atomicLoad(MemoryOrder ms = MemoryOrder.seq, T)(auto ref shared const T val) pure nothrow @nogc @trusted
if (hasUnsharedIndirections!T)
{
// HACK: DEPRECATE THIS FUNCTION, IT IS INVALID TO DO ATOMIC LOAD OF SHARED CLASS
@@ -1203,7 +1203,7 @@ version (CoreUnittest)
}
}
- @betterC pure nothrow @nogc @safe unittest // issue 16651
+ @betterC pure nothrow @nogc @safe unittest // https://issues.dlang.org/show_bug.cgi?id=16651
{
shared ulong a = 2;
uint b = 1;
@@ -1216,7 +1216,7 @@ version (CoreUnittest)
assert(c == 1);
}
- pure nothrow @safe unittest // issue 16230
+ pure nothrow @safe unittest // https://issues.dlang.org/show_bug.cgi?id=16230
{
shared int i;
static assert(is(typeof(atomicLoad(i)) == int));
diff --git a/libphobos/libdruntime/core/internal/array/concatenation.d b/libphobos/libdruntime/core/internal/array/concatenation.d
index ff777a6..4a05b50 100644
--- a/libphobos/libdruntime/core/internal/array/concatenation.d
+++ b/libphobos/libdruntime/core/internal/array/concatenation.d
@@ -19,6 +19,7 @@ module core.internal.array.concatenation;
*/
Tret _d_arraycatnTX(Tret, Tarr...)(auto ref Tarr froms) @trusted
{
+ import core.internal.array.capacity : _d_arraysetlengthTImpl;
import core.internal.traits : hasElaborateCopyConstructor, Unqual;
import core.lifetime : copyEmplace;
import core.stdc.string : memcpy;
@@ -38,7 +39,21 @@ Tret _d_arraycatnTX(Tret, Tarr...)(auto ref Tarr froms) @trusted
if (totalLen == 0)
return res;
- res.length = totalLen;
+
+ // We cannot use this, because it refuses to work if the array type has disabled default construction.
+ // res.length = totalLen;
+ // Call the runtime function directly instead.
+ // TODO: once `__arrayAlloc` is templated, call that instead.
+ version (D_ProfileGC)
+ {
+ // TODO: forward file, line, name from _d_arraycatnTXTrace
+ _d_arraysetlengthTImpl!(typeof(res))._d_arraysetlengthTTrace(
+ __FILE__, __LINE__, "_d_arraycatnTX", res, totalLen);
+ }
+ else
+ {
+ _d_arraysetlengthTImpl!(typeof(res))._d_arraysetlengthT(res, totalLen);
+ }
/* Currently, if both a postblit and a cpctor are defined, the postblit is
* used. If this changes, the condition below will have to be adapted.
diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
index 62ce941..39cd30a 100644
--- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
+++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
@@ -26,6 +26,7 @@ module core.internal.gc.impl.conservative.gc;
//debug = INVARIANT; // enable invariants
//debug = PROFILE_API; // profile API calls for config.profile > 1
//debug = GC_RECURSIVE_LOCK; // check for recursive locking on the same thread
+//debug = VALGRIND; // Valgrind memcheck integration
/***************************************************/
version = COLLECT_PARALLEL; // parallel scanning
@@ -52,6 +53,8 @@ version (GNU) import gcc.builtins;
debug (PRINTF_TO_FILE) import core.stdc.stdio : sprintf, fprintf, fopen, fflush, FILE;
else import core.stdc.stdio : sprintf, printf; // needed to output profiling results
+debug (VALGRIND) import etc.valgrind.valgrind;
+
import core.time;
alias currTime = MonoTime.currTime;
@@ -90,7 +93,7 @@ private
int rt_hasFinalizerInSegment(void* p, size_t size, uint attr, const scope void[] segment) nothrow;
// Declared as an extern instead of importing core.exception
- // to avoid inlining - see issue 13725.
+ // to avoid inlining - see https://issues.dlang.org/show_bug.cgi?id=13725.
void onInvalidMemoryOperationError(void* pretend_sideffect = null) @trusted pure nothrow @nogc;
void onOutOfMemoryErrorNoGC() @trusted nothrow @nogc;
@@ -480,6 +483,8 @@ class ConservativeGC : GC
auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, bits, localAllocSize, ti);
+ invalidate(p[0 .. localAllocSize], 0xF0, true);
+
if (!(bits & BlkAttr.NO_SCAN))
{
memset(p + size, 0, localAllocSize - size);
@@ -567,6 +572,9 @@ class ConservativeGC : GC
auto p = runLocked!(mallocNoSync, mallocTime, numMallocs)(size, bits, localAllocSize, ti);
+ debug (VALGRIND) makeMemUndefined(p[0..size]);
+ invalidate((p + size)[0 .. localAllocSize - size], 0xF0, true);
+
memset(p, 0, size);
if (!(bits & BlkAttr.NO_SCAN))
{
@@ -688,7 +696,7 @@ class ConservativeGC : GC
else if (newsz < psz)
{
// Shrink in place
- debug (MEMSTOMP) memset(p + size, 0xF2, psize - size);
+ invalidate((p + size)[0 .. psize - size], 0xF2, false);
lpool.freePages(pagenum + newsz, psz - newsz);
lpool.mergeFreePageOffsets!(false, true)(pagenum + newsz, psz - newsz);
lpool.bPageOffsets[pagenum] = cast(uint) newsz;
@@ -704,7 +712,7 @@ class ConservativeGC : GC
if (freesz < newPages)
return doMalloc(); // free range too small
- debug (MEMSTOMP) memset(p + psize, 0xF0, size - psize);
+ invalidate((p + psize)[0 .. size - psize], 0xF0, true);
debug (PRINTF) printFreeInfo(pool);
memset(&lpool.pagetable[pagenum + psz], Bins.B_PAGEPLUS, newPages);
lpool.bPageOffsets[pagenum] = cast(uint) newsz;
@@ -795,7 +803,7 @@ class ConservativeGC : GC
if (freesz < minsz)
return 0;
size_t sz = freesz > maxsz ? maxsz : freesz;
- debug (MEMSTOMP) memset(pool.baseAddr + (pagenum + psz) * PAGESIZE, 0xF0, sz * PAGESIZE);
+ invalidate((pool.baseAddr + (pagenum + psz) * PAGESIZE)[0 .. sz * PAGESIZE], 0xF0, true);
memset(lpool.pagetable + pagenum + psz, Bins.B_PAGEPLUS, sz);
lpool.bPageOffsets[pagenum] = cast(uint) (psz + sz);
for (auto offset = psz; offset < psz + sz; offset++)
@@ -911,7 +919,7 @@ class ConservativeGC : GC
size_t npages = lpool.bPageOffsets[pagenum];
auto size = npages * PAGESIZE;
ssize = sentinel_size(q, size);
- debug (MEMSTOMP) memset(p, 0xF2, size);
+ invalidate(p[0 .. size], 0xF2, false);
lpool.freePages(pagenum, npages);
lpool.mergeFreePageOffsets!(true, true)(pagenum, npages);
}
@@ -925,13 +933,13 @@ class ConservativeGC : GC
auto size = binsize[bin];
ssize = sentinel_size(q, size);
- debug (MEMSTOMP) memset(p, 0xF2, size);
+ invalidate(p[0 .. size], 0xF2, false);
// in case the page hasn't been recovered yet, don't add the object to the free list
if (!gcx.recoverPool[bin] || pool.binPageChain[pagenum] == Pool.PageRecovered)
{
- list.next = gcx.bucket[bin];
- list.pool = pool;
+ undefinedWrite(list.next, gcx.bucket[bin]);
+ undefinedWrite(list.pool, pool);
gcx.bucket[bin] = list;
}
pool.freebits.set(biti);
@@ -1965,8 +1973,8 @@ struct Gcx
assert(p !is null);
L_hasBin:
// Return next item from free list
- bucket[bin] = (cast(List*)p).next;
- auto pool = (cast(List*)p).pool;
+ bucket[bin] = undefinedRead((cast(List*)p).next);
+ auto pool = undefinedRead((cast(List*)p).pool);
auto biti = (p - pool.baseAddr) >> pool.shiftBy;
assert(pool.freebits.test(biti));
@@ -1976,7 +1984,7 @@ struct Gcx
if (bits)
pool.setBits(biti, bits);
//debug(PRINTF) printf("\tmalloc => %p\n", p);
- debug (MEMSTOMP) memset(p, 0xF0, alloc_size);
+ invalidate(p[0 .. alloc_size], 0xF0, true);
if (ConservativeGC.isPrecise)
{
@@ -2059,7 +2067,7 @@ struct Gcx
auto p = pool.baseAddr + pn * PAGESIZE;
debug(PRINTF) printf("Got large alloc: %p, pt = %d, np = %d\n", p, pool.pagetable[pn], npages);
- debug (MEMSTOMP) memset(p, 0xF1, size);
+ invalidate(p[0 .. size], 0xF1, true);
alloc_size = npages * PAGESIZE;
//debug(PRINTF) printf("\tp = %p\n", p);
@@ -2241,6 +2249,7 @@ struct Gcx
immutable ncap = _cap ? 2 * _cap : initSize / RANGE.sizeof;
auto p = cast(RANGE*)os_mem_map(ncap * RANGE.sizeof);
if (p is null) onOutOfMemoryErrorNoGC();
+ debug (VALGRIND) makeMemUndefined(p[0..ncap]);
if (_p !is null)
{
p[0 .. _length] = _p[0 .. _length];
@@ -2295,7 +2304,8 @@ struct Gcx
for (;;)
{
- auto p = *cast(void**)(rng.pbot);
+ auto p = undefinedRead(*cast(void**)(rng.pbot));
+ debug (VALGRIND) makeMemDefined((&p)[0 .. 1]);
debug(MARK_PRINTF) printf("\tmark %p: %p\n", rng.pbot, p);
@@ -2525,6 +2535,7 @@ struct Gcx
for (auto p = cast(void**)pbot; cast(void*)p < ptop; p++)
{
auto ptr = *p;
+ debug (VALGRIND) makeMemDefined((&ptr)[0 .. 1]);
if (cast(size_t)(ptr - minAddr) < memSize)
toscanRoots.push(ptr);
}
@@ -2650,7 +2661,7 @@ struct Gcx
pool.freepages += npages;
numFree += npages;
- debug (MEMSTOMP) memset(p, 0xF3, npages * PAGESIZE);
+ invalidate(p[0 .. npages * PAGESIZE], 0xF3, false);
// Don't need to update searchStart here because
// pn is guaranteed to be greater than last time
// we updated it.
@@ -2765,7 +2776,7 @@ struct Gcx
debug(COLLECT_PRINTF) printf("\tcollecting %p\n", p);
leakDetector.log_free(q, sentinel_size(q, size));
- debug (MEMSTOMP) memset(p, 0xF3, size);
+ invalidate(p[0 .. size], 0xF3, false);
}
}
}
@@ -2830,11 +2841,11 @@ struct Gcx
if (!core.bitop.bt(freebitsdata, u / 16))
continue;
auto elem = cast(List *)(p + u);
- elem.pool = &pool.base;
- *bucketTail = elem;
+ undefinedWrite(elem.pool, &pool.base);
+ undefinedWrite(*bucketTail, elem);
bucketTail = &elem.next;
}
- *bucketTail = null;
+ undefinedWrite(*bucketTail, null);
assert(bucket[bin] !is null);
return true;
}
@@ -3572,6 +3583,7 @@ struct Pool
//debug(PRINTF) printf("Pool::Pool(%u)\n", npages);
poolsize = npages * PAGESIZE;
baseAddr = cast(byte *)os_mem_map(poolsize);
+ version (VALGRIND) makeMemNoAccess(baseAddr[0..poolsize]);
// Some of the code depends on page alignment of memory pools
assert((cast(size_t)baseAddr & (PAGESIZE - 1)) == 0);
@@ -4275,7 +4287,7 @@ struct LargeObjectPool
for (; pn + n < npages; ++n)
if (pagetable[pn + n] != Bins.B_PAGEPLUS)
break;
- debug (MEMSTOMP) memset(baseAddr + pn * PAGESIZE, 0xF3, n * PAGESIZE);
+ invalidate((baseAddr + pn * PAGESIZE)[0 .. n * PAGESIZE], 0xF3, false);
freePages(pn, n);
mergeFreePageOffsets!(true, true)(pn, n);
}
@@ -4394,7 +4406,7 @@ struct SmallObjectPool
debug(COLLECT_PRINTF) printf("\tcollecting %p\n", p);
//log_free(sentinel_add(p));
- debug (MEMSTOMP) memset(p, 0xF3, size);
+ invalidate(p[0 .. size], 0xF3, false);
}
if (freeBits)
@@ -4431,17 +4443,17 @@ struct SmallObjectPool
void* ptop = p + PAGESIZE - 2 * size + 1;
for (; p < ptop; p += size)
{
- (cast(List *)p).next = cast(List *)(p + size);
- (cast(List *)p).pool = &base;
+ undefinedWrite((cast(List *)p).next, cast(List *)(p + size));
+ undefinedWrite((cast(List *)p).pool, &base);
}
- (cast(List *)p).next = null;
- (cast(List *)p).pool = &base;
+ undefinedWrite((cast(List *)p).next, null);
+ undefinedWrite((cast(List *)p).pool, &base);
return first;
}
}
debug(SENTINEL) {} else // no additional capacity with SENTINEL
-unittest // bugzilla 14467
+unittest // https://issues.dlang.org/show_bug.cgi?id=14467
{
int[] arr = new int[10];
assert(arr.capacity);
@@ -4449,7 +4461,7 @@ unittest // bugzilla 14467
assert(arr.capacity);
}
-unittest // bugzilla 15353
+unittest // https://issues.dlang.org/show_bug.cgi?id=15353
{
import core.memory : GC;
@@ -4466,7 +4478,7 @@ unittest // bugzilla 15353
GC.collect();
}
-unittest // bugzilla 15822
+unittest // https://issues.dlang.org/show_bug.cgi?id=15822
{
import core.memory : GC;
@@ -4487,7 +4499,7 @@ unittest // bugzilla 15822
GC.collect();
}
-unittest // bugzilla 1180
+unittest // https://issues.dlang.org/show_bug.cgi?id=1180
{
import core.exception;
try
@@ -4823,13 +4835,22 @@ debug (SENTINEL)
{
assert(size <= uint.max);
*sentinel_psize(p) = cast(uint)size;
- *sentinel_pre(p) = SENTINEL_PRE;
- *sentinel_post(p) = SENTINEL_POST;
+ debug (VALGRIND)
+ {
+ makeMemNoAccess(sentinel_pre(p)[0..1]);
+ makeMemNoAccess(sentinel_post(p)[0..1]);
+ }
+ else
+ {
+ *sentinel_pre(p) = SENTINEL_PRE;
+ *sentinel_post(p) = SENTINEL_POST;
+ }
}
void sentinel_Invariant(const void *p) nothrow @nogc
{
+ debug (VALGRIND) {} else
debug
{
assert(*sentinel_pre(p) == SENTINEL_PRE);
@@ -5063,3 +5084,53 @@ unittest
printf("unexpected pointers %p and %p\n", p.ptr, q.ptr);
}
}
+
+/* ============================ MEMSTOMP =============================== */
+
+/// Mark the specified memory region as uninitialized -
+/// reading from this region is an error.
+/// If writable is false, writing to it is also an error.
+pragma(inline, true)
+void invalidate(void[] mem, ubyte pattern, bool writable) nothrow @nogc
+{
+ debug (MEMSTOMP) memset(mem.ptr, pattern, mem.length);
+ debug (VALGRIND)
+ {
+ if (writable)
+ makeMemUndefined(mem);
+ else
+ makeMemNoAccess(mem);
+ }
+}
+
+/// Read memory that should otherwise be marked as unreadable
+/// (e.g. free lists overlapped with unallocated heap objects).
+pragma(inline, true)
+T undefinedRead(T)(ref T var) nothrow
+{
+ debug (VALGRIND)
+ {
+ auto varArr = (&var)[0..1];
+ disableAddrReportingInRange(varArr);
+ T result = var;
+ enableAddrReportingInRange(varArr);
+ return result;
+ }
+ else
+ return var;
+}
+
+/// Write memory that should otherwise be marked as unwritable.
+pragma(inline, true)
+void undefinedWrite(T)(ref T var, T value) nothrow
+{
+ debug (VALGRIND)
+ {
+ auto varArr = (&var)[0..1];
+ disableAddrReportingInRange(varArr);
+ var = value;
+ enableAddrReportingInRange(varArr);
+ }
+ else
+ var = value;
+}
diff --git a/libphobos/libdruntime/core/internal/gc/proxy.d b/libphobos/libdruntime/core/internal/gc/proxy.d
index 695ef06..abc8c6a 100644
--- a/libphobos/libdruntime/core/internal/gc/proxy.d
+++ b/libphobos/libdruntime/core/internal/gc/proxy.d
@@ -62,8 +62,9 @@ extern (C)
{
import core.stdc.stdio : fprintf, stderr;
import core.stdc.stdlib : exit;
+ import core.atomic : atomicLoad;
- fprintf(stderr, "No GC was initialized, please recheck the name of the selected GC ('%.*s').\n", cast(int)config.gc.length, config.gc.ptr);
+ fprintf(atomicLoad(stderr), "No GC was initialized, please recheck the name of the selected GC ('%.*s').\n", cast(int)config.gc.length, config.gc.ptr);
instanceLock.unlock();
exit(1);
@@ -97,7 +98,9 @@ extern (C)
{
default:
import core.stdc.stdio : fprintf, stderr;
- fprintf(stderr, "Unknown GC cleanup method, please recheck ('%.*s').\n",
+ import core.atomic : atomicLoad;
+
+ fprintf(atomicLoad(stderr), "Unknown GC cleanup method, please recheck ('%.*s').\n",
cast(int)config.cleanup.length, config.cleanup.ptr);
break;
case "none":
diff --git a/libphobos/libdruntime/core/internal/parseoptions.d b/libphobos/libdruntime/core/internal/parseoptions.d
index ed6251f..ac0eb82 100644
--- a/libphobos/libdruntime/core/internal/parseoptions.d
+++ b/libphobos/libdruntime/core/internal/parseoptions.d
@@ -146,9 +146,11 @@ private:
bool optError(const scope char[] msg, const scope char[] name, const(char)[] errName)
{
+ import core.atomic : atomicLoad;
+
version (CoreUnittest) if (inUnittest) return false;
- fprintf(stderr, "%.*s %.*s option '%.*s'.\n",
+ fprintf(atomicLoad(stderr), "%.*s %.*s option '%.*s'.\n",
cast(int)msg.length, msg.ptr,
cast(int)errName.length, errName.ptr,
cast(int)name.length, name.ptr);
@@ -332,9 +334,11 @@ do
bool parseError(const scope char[] exp, const scope char[] opt, const scope char[] got, const(char)[] errName)
{
+ import core.atomic : atomicLoad;
+
version (CoreUnittest) if (inUnittest) return false;
- fprintf(stderr, "Expecting %.*s as argument for %.*s option '%.*s', got '%.*s' instead.\n",
+ fprintf(atomicLoad(stderr), "Expecting %.*s as argument for %.*s option '%.*s', got '%.*s' instead.\n",
cast(int)exp.length, exp.ptr,
cast(int)errName.length, errName.ptr,
cast(int)opt.length, opt.ptr,
@@ -344,9 +348,11 @@ bool parseError(const scope char[] exp, const scope char[] opt, const scope char
bool overflowedError(const scope char[] opt, const scope char[] got)
{
+ import core.atomic : atomicLoad;
+
version (CoreUnittest) if (inUnittest) return false;
- fprintf(stderr, "Argument for %.*s option '%.*s' is too big.\n",
+ fprintf(atomicLoad(stderr), "Argument for %.*s option '%.*s' is too big.\n",
cast(int)opt.length, opt.ptr,
cast(int)got.length, got.ptr);
return false;
diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d
index ae047cb..89236db 100644
--- a/libphobos/libdruntime/core/lifetime.d
+++ b/libphobos/libdruntime/core/lifetime.d
@@ -364,7 +364,7 @@ T* emplace(T, Args...)(void[] chunk, auto ref Args args)
assert(u1.a == "hello");
}
-@system unittest // bugzilla 15772
+@system unittest // https://issues.dlang.org/show_bug.cgi?id=15772
{
abstract class Foo {}
class Bar: Foo {}
@@ -2322,7 +2322,7 @@ pure nothrow @nogc @system unittest
assert(val == 1);
}
-// issue 18913
+// https://issues.dlang.org/show_bug.cgi?id=18913
@safe unittest
{
static struct NoCopy
@@ -2454,7 +2454,7 @@ template _d_delstructImpl(T)
assert(outerDtors == 1);
}
-// issue 25552
+// https://issues.dlang.org/show_bug.cgi?id=25552
pure nothrow @system unittest
{
int i;
@@ -2478,7 +2478,7 @@ pure nothrow @system unittest
assert(i == 2);
}
-// issue 25552
+// https://issues.dlang.org/show_bug.cgi?id=25552
@safe unittest
{
int i;
@@ -2527,7 +2527,7 @@ pure nothrow @system unittest
assert(i == 6);
}
-// issue 25552
+// https://issues.dlang.org/show_bug.cgi?id=25552
@safe unittest
{
int i;
diff --git a/libphobos/libdruntime/core/stdc/assert_.d b/libphobos/libdruntime/core/stdc/assert_.d
index a8909e2..d6cb8a6 100644
--- a/libphobos/libdruntime/core/stdc/assert_.d
+++ b/libphobos/libdruntime/core/stdc/assert_.d
@@ -59,7 +59,7 @@ else version (FreeBSD)
/***
* Assert failure function in the FreeBSD C library.
*/
- noreturn __assert(const(char)* exp, const(char)* file, uint line, const(char)* exp);
+ noreturn __assert(const(char)* func, const(char)* file, uint line, const(char)* exp);
}
else version (NetBSD)
{
@@ -67,6 +67,8 @@ else version (NetBSD)
* Assert failure function in the NetBSD C library.
*/
noreturn __assert(const(char)* file, int line, const(char)* exp);
+ ///
+ noreturn __assert13(const(char)* file, int line, const(char)* func, const(char)* exp);
}
else version (OpenBSD)
{
@@ -75,14 +77,14 @@ else version (OpenBSD)
*/
noreturn __assert(const(char)* file, int line, const(char)* exp);
///
- void __assert2(const(char)* file, int line, const(char)* func, const(char)* exp);
+ noreturn __assert2(const(char)* file, int line, const(char)* func, const(char)* exp);
}
else version (DragonFlyBSD)
{
/***
* Assert failure function in the DragonFlyBSD C library.
*/
- noreturn __assert(const(char)* exp, const(char)* file, uint line, const(char)* exp);
+ noreturn __assert(const(char)* func, const(char)* file, uint line, const(char)* exp);
}
else version (CRuntime_Glibc)
{
@@ -97,7 +99,12 @@ else version (CRuntime_Glibc)
}
else version (CRuntime_Bionic)
{
+ /***
+ * Assert failure functions in the Bionic library.
+ */
noreturn __assert(const(char)* __file, int __line, const(char)* __msg);
+ ///
+ noreturn __assert2(const(char)* __file, int __line, const(char)* __function, const(char)* __msg);
}
else version (CRuntime_Musl)
{
diff --git a/libphobos/libdruntime/core/stdc/wchar_.d b/libphobos/libdruntime/core/stdc/wchar_.d
index fe5fce4..2d01e26 100644
--- a/libphobos/libdruntime/core/stdc/wchar_.d
+++ b/libphobos/libdruntime/core/stdc/wchar_.d
@@ -17,6 +17,7 @@ module core.stdc.wchar_;
import core.stdc.config;
import core.stdc.stdarg; // for va_list
import core.stdc.stdio; // for FILE, not exposed per spec
+import core.atomic : atomicLoad;
public import core.stdc.stddef; // for wchar_t
public import core.stdc.time; // for tm
public import core.stdc.stdint; // for WCHAR_MIN, WCHAR_MAX
@@ -211,9 +212,9 @@ int fputws(const scope wchar_t* s, FILE* stream);
extern (D) @trusted
{
///
- wint_t getwchar() { return fgetwc(stdin); }
+ wint_t getwchar() { return fgetwc(atomicLoad(stdin)); }
///
- wint_t putwchar(wchar_t c) { return fputwc(c,stdout); }
+ wint_t putwchar(wchar_t c) { return fputwc(c,atomicLoad(stdout)); }
}
///
diff --git a/libphobos/libdruntime/core/sys/linux/input.d b/libphobos/libdruntime/core/sys/linux/input.d
new file mode 100644
index 0000000..1bf356d
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/linux/input.d
@@ -0,0 +1,236 @@
+module core.sys.linux.input;
+
+version (linux):
+extern(C):
+nothrow:
+
+import core.sys.linux.sys.time;
+import core.sys.posix.sys.ioctl;
+
+public import core.sys.linux.input_event_codes;
+
+struct input_event
+{
+ timeval time;
+ ushort type;
+ ushort code;
+ int value;
+}
+
+enum EV_VERSION = 0x010001;
+
+struct input_id
+{
+ ushort bustype;
+ ushort vendor;
+ ushort product;
+ ushort version_;
+}
+
+struct input_absinfo
+{
+ int value;
+ int minimum;
+ int maximum;
+ int fuzz;
+ int flat;
+ int resolution;
+}
+
+enum INPUT_KEYMAP_BY_INDEX = (1 << 0);
+struct input_keymap_entry
+{
+ ubyte flags;
+ ubyte len;
+ ushort index;
+ uint keycode;
+ ubyte[32] scancode;
+}
+
+struct input_mask
+{
+ uint type;
+ uint codes_size;
+ ulong codes_ptr;
+}
+
+enum EVIOCGVERSION = _IOR!int('E', 0x01);
+enum EVIOCGID = _IOR!input_id('E', 0x02);
+enum EVIOCGREP = _IOR!(uint[2])('E', 0x03);
+enum EVIOCSREP = _IOW!(uint[2])('E', 0x03);
+
+enum EVIOCGKEYCODE = _IOR!(uint[2])('E', 0x04);
+enum EVIOCGKEYCODE_V2 = _IOR!input_keymap_entry('E', 0x04);
+enum EVIOCSKEYCODE = _IOW!(uint[2])('E', 0x04);
+enum EVIOCSKEYCODE_V2 = _IOW!input_keymap_entry('E', 0x04);
+
+enum EVIOCGNAME(len) = _IOC(_IOC_READ, 'E', 0x06, len);
+enum EVIOCGPHYS(len) = _IOC(_IOC_READ, 'E', 0x07, len);
+enum EVIOCGUNIQ(len) = _IOC(_IOC_READ, 'E', 0x08, len);
+enum EVIOCGPROP(len) = _IOC(_IOC_READ, 'E', 0x09, len);
+
+enum EVIOCGMTSLOTS(len) = _IOC(_IOC_READ, 'E', 0x0a, len);
+
+enum EVIOCGKEY(len) = _IOC(_IOC_READ, 'E', 0x18, len);
+enum EVIOCGLED(len) = _IOC(_IOC_READ, 'E', 0x19, len);
+enum EVIOCGSND(len) = _IOC(_IOC_READ, 'E', 0x1a, len);
+enum EVIOCGSW(len) = _IOC(_IOC_READ, 'E', 0x1b, len);
+
+enum EVIOCGBIT(ev,len) = _IOC(_IOC_READ, 'E', 0x20 + (ev), len);
+enum EVIOCGABS(abs) = _IOR!input_absinfo('E', 0x40 + (abs));
+enum EVIOCSABS(abs) = _IOW!input_absinfo('E', 0xc0 + (abs));
+
+enum EVIOCSFF = _IOW!ff_effect('E', 0x80);
+enum EVIOCRMFF = _IOW!int('E', 0x81);
+enum EVIOCGEFFECTS = _IOR!int('E', 0x84);
+
+enum EVIOCGRAB = _IOW!int('E', 0x90);
+enum EVIOCREVOKE = _IOW!int('E', 0x91);
+
+enum EVIOCGMASK = _IOR!input_mask('E', 0x92);
+
+enum EVIOCSMASK = _IOW!input_mask('E', 0x93);
+
+enum EVIOCSCLOCKID = _IOW!int('E', 0xa0);
+
+enum ID_BUS = 0;
+enum ID_VENDOR = 1;
+enum ID_PRODUCT = 2;
+enum ID_VERSION = 3;
+
+enum BUS_PCI = 0x01;
+enum BUS_ISAPNP = 0x02;
+enum BUS_USB = 0x03;
+enum BUS_HIL = 0x04;
+enum BUS_BLUETOOTH = 0x05;
+enum BUS_VIRTUAL = 0x06;
+
+enum BUS_ISA = 0x10;
+enum BUS_I8042 = 0x11;
+enum BUS_XTKBD = 0x12;
+enum BUS_RS232 = 0x13;
+enum BUS_GAMEPORT = 0x14;
+enum BUS_PARPORT = 0x15;
+enum BUS_AMIGA = 0x16;
+enum BUS_ADB = 0x17;
+enum BUS_I2C = 0x18;
+enum BUS_HOST = 0x19;
+enum BUS_GSC = 0x1A;
+enum BUS_ATARI = 0x1B;
+enum BUS_SPI = 0x1C;
+enum BUS_RMI = 0x1D;
+enum BUS_CEC = 0x1E;
+enum BUS_INTEL_ISHTP = 0x1F;
+
+enum MT_TOOL_FINGER = 0;
+enum MT_TOOL_PEN = 1;
+enum MT_TOOL_PALM = 2;
+enum MT_TOOL_MAX = 2;
+
+enum FF_STATUS_STOPPED = 0x00;
+enum FF_STATUS_PLAYING = 0x01;
+enum FF_STATUS_MAX = 0x01;
+
+struct ff_replay {
+ ushort length;
+ ushort delay;
+};
+
+struct ff_trigger {
+ ushort button;
+ ushort interval;
+};
+
+struct ff_envelope {
+ ushort attack_length;
+ ushort attack_level;
+ ushort fade_length;
+ ushort fade_level;
+};
+
+struct ff_constant_effect {
+ short level;
+ ff_envelope envelope;
+};
+
+struct ff_ramp_effect {
+ short start_level;
+ short end_level;
+ ff_envelope envelope;
+};
+
+struct ff_condition_effect {
+ ushort right_saturation;
+ ushort left_saturation;
+
+ short right_coeff;
+ short left_coeff;
+
+ ushort deadband;
+ short center;
+};
+
+struct ff_periodic_effect {
+ ushort waveform;
+ ushort period;
+ short magnitude;
+ short offset;
+ ushort phase;
+
+ ff_envelope envelope;
+
+ uint custom_len;
+ short *custom_data;
+};
+
+struct ff_rumble_effect {
+ ushort strong_magnitude;
+ ushort weak_magnitude;
+};
+
+struct ff_effect {
+ ushort type;
+ short id;
+ ushort direction;
+ ff_trigger trigger;
+ ff_replay replay;
+
+ union U {
+ ff_constant_effect constant;
+ ff_ramp_effect ramp;
+ ff_periodic_effect periodic;
+ ff_condition_effect[2] condition;
+ ff_rumble_effect rumble;
+ }
+ U u;
+};
+
+enum FF_RUMBLE = 0x50;
+enum FF_PERIODIC = 0x51;
+enum FF_CONSTANT = 0x52;
+enum FF_SPRING = 0x53;
+enum FF_FRICTION = 0x54;
+enum FF_DAMPER = 0x55;
+enum FF_INERTIA = 0x56;
+enum FF_RAMP = 0x57;
+
+enum FF_EFFECT_MIN = FF_RUMBLE;
+enum FF_EFFECT_MAX = FF_RAMP;
+
+enum FF_SQUARE = 0x58;
+enum FF_TRIANGLE = 0x59;
+enum FF_SINE = 0x5a;
+enum FF_SAW_UP = 0x5b;
+enum FF_SAW_DOWN = 0x5c;
+enum FF_CUSTOM = 0x5d;
+
+enum FF_WAVEFORM_MIN = FF_SQUARE;
+enum FF_WAVEFORM_MAX = FF_CUSTOM;
+
+enum FF_GAIN = 0x60;
+enum FF_AUTOCENTER = 0x61;
+
+enum FF_MAX_EFFECTS = FF_GAIN;
+
+enum FF_MAX = 0x7f;
+enum FF_CNT = (FF_MAX+1);
diff --git a/libphobos/libdruntime/core/sys/linux/input_event_codes.d b/libphobos/libdruntime/core/sys/linux/input_event_codes.d
new file mode 100644
index 0000000..3ebda69
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/linux/input_event_codes.d
@@ -0,0 +1,758 @@
+module core.sys.linux.input_event_codes;
+
+version (linux):
+extern(C):
+nothrow:
+
+enum INPUT_PROP_POINTER = 0x00;
+enum INPUT_PROP_DIRECT = 0x01;
+enum INPUT_PROP_BUTTONPAD = 0x02;
+enum INPUT_PROP_SEMI_MT = 0x03;
+enum INPUT_PROP_TOPBUTTONPAD = 0x04;
+enum INPUT_PROP_POINTING_STICK = 0x05;
+enum INPUT_PROP_ACCELEROMETER = 0x06;
+
+enum INPUT_PROP_MAX = 0x1f;
+enum INPUT_PROP_CNT = (INPUT_PROP_MAX + 1);
+
+enum EV_SYN = 0x00;
+enum EV_KEY = 0x01;
+enum EV_REL = 0x02;
+enum EV_ABS = 0x03;
+enum EV_MSC = 0x04;
+enum EV_SW = 0x05;
+enum EV_LED = 0x11;
+enum EV_SND = 0x12;
+enum EV_REP = 0x14;
+enum EV_FF = 0x15;
+enum EV_PWR = 0x16;
+enum EV_FF_STATUS = 0x17;
+enum EV_MAX = 0x1f;
+enum EV_CNT = (EV_MAX+1);
+
+enum SYN_REPORT = 0;
+enum SYN_CONFIG = 1;
+enum SYN_MT_REPORT = 2;
+enum SYN_DROPPED = 3;
+enum SYN_MAX = 0xf;
+enum SYN_CNT = (SYN_MAX+1);
+
+enum KEY_RESERVED = 0;
+enum KEY_ESC = 1;
+enum KEY_1 = 2;
+enum KEY_2 = 3;
+enum KEY_3 = 4;
+enum KEY_4 = 5;
+enum KEY_5 = 6;
+enum KEY_6 = 7;
+enum KEY_7 = 8;
+enum KEY_8 = 9;
+enum KEY_9 = 10;
+enum KEY_0 = 11;
+enum KEY_MINUS = 12;
+enum KEY_EQUAL = 13;
+enum KEY_BACKSPACE = 14;
+enum KEY_TAB = 15;
+enum KEY_Q = 16;
+enum KEY_W = 17;
+enum KEY_E = 18;
+enum KEY_R = 19;
+enum KEY_T = 20;
+enum KEY_Y = 21;
+enum KEY_U = 22;
+enum KEY_I = 23;
+enum KEY_O = 24;
+enum KEY_P = 25;
+enum KEY_LEFTBRACE = 26;
+enum KEY_RIGHTBRACE = 27;
+enum KEY_ENTER = 28;
+enum KEY_LEFTCTRL = 29;
+enum KEY_A = 30;
+enum KEY_S = 31;
+enum KEY_D = 32;
+enum KEY_F = 33;
+enum KEY_G = 34;
+enum KEY_H = 35;
+enum KEY_J = 36;
+enum KEY_K = 37;
+enum KEY_L = 38;
+enum KEY_SEMICOLON = 39;
+enum KEY_APOSTROPHE = 40;
+enum KEY_GRAVE = 41;
+enum KEY_LEFTSHIFT = 42;
+enum KEY_BACKSLASH = 43;
+enum KEY_Z = 44;
+enum KEY_X = 45;
+enum KEY_C = 46;
+enum KEY_V = 47;
+enum KEY_B = 48;
+enum KEY_N = 49;
+enum KEY_M = 50;
+enum KEY_COMMA = 51;
+enum KEY_DOT = 52;
+enum KEY_SLASH = 53;
+enum KEY_RIGHTSHIFT = 54;
+enum KEY_KPASTERISK = 55;
+enum KEY_LEFTALT = 56;
+enum KEY_SPACE = 57;
+enum KEY_CAPSLOCK = 58;
+enum KEY_F1 = 59;
+enum KEY_F2 = 60;
+enum KEY_F3 = 61;
+enum KEY_F4 = 62;
+enum KEY_F5 = 63;
+enum KEY_F6 = 64;
+enum KEY_F7 = 65;
+enum KEY_F8 = 66;
+enum KEY_F9 = 67;
+enum KEY_F10 = 68;
+enum KEY_NUMLOCK = 69;
+enum KEY_SCROLLLOCK = 70;
+enum KEY_KP7 = 71;
+enum KEY_KP8 = 72;
+enum KEY_KP9 = 73;
+enum KEY_KPMINUS = 74;
+enum KEY_KP4 = 75;
+enum KEY_KP5 = 76;
+enum KEY_KP6 = 77;
+enum KEY_KPPLUS = 78;
+enum KEY_KP1 = 79;
+enum KEY_KP2 = 80;
+enum KEY_KP3 = 81;
+enum KEY_KP0 = 82;
+enum KEY_KPDOT = 83;
+
+enum KEY_ZENKAKUHANKAKU = 85;
+enum KEY_102ND = 86;
+enum KEY_F11 = 87;
+enum KEY_F12 = 88;
+enum KEY_RO = 89;
+enum KEY_KATAKANA = 90;
+enum KEY_HIRAGANA = 91;
+enum KEY_HENKAN = 92;
+enum KEY_KATAKANAHIRAGANA = 93;
+enum KEY_MUHENKAN = 94;
+enum KEY_KPJPCOMMA = 95;
+enum KEY_KPENTER = 96;
+enum KEY_RIGHTCTRL = 97;
+enum KEY_KPSLASH = 98;
+enum KEY_SYSRQ = 99;
+enum KEY_RIGHTALT = 100;
+enum KEY_LINEFEED = 101;
+enum KEY_HOME = 102;
+enum KEY_UP = 103;
+enum KEY_PAGEUP = 104;
+enum KEY_LEFT = 105;
+enum KEY_RIGHT = 106;
+enum KEY_END = 107;
+enum KEY_DOWN = 108;
+enum KEY_PAGEDOWN = 109;
+enum KEY_INSERT = 110;
+enum KEY_DELETE = 111;
+enum KEY_MACRO = 112;
+enum KEY_MUTE = 113;
+enum KEY_VOLUMEDOWN = 114;
+enum KEY_VOLUMEUP = 115;
+enum KEY_POWER = 116;
+enum KEY_KPEQUAL = 117;
+enum KEY_KPPLUSMINUS = 118;
+enum KEY_PAUSE = 119;
+enum KEY_SCALE = 120;
+
+enum KEY_KPCOMMA = 121;
+enum KEY_HANGEUL = 122;
+enum KEY_HANGUEL = KEY_HANGEUL;
+enum KEY_HANJA = 123;
+enum KEY_YEN = 124;
+enum KEY_LEFTMETA = 125;
+enum KEY_RIGHTMETA = 126;
+enum KEY_COMPOSE = 127;
+
+enum KEY_STOP = 128;
+enum KEY_AGAIN = 129;
+enum KEY_PROPS = 130;
+enum KEY_UNDO = 131;
+enum KEY_FRONT = 132;
+enum KEY_COPY = 133;
+enum KEY_OPEN = 134;
+enum KEY_PASTE = 135;
+enum KEY_FIND = 136;
+enum KEY_CUT = 137;
+enum KEY_HELP = 138;
+enum KEY_MENU = 139;
+enum KEY_CALC = 140;
+enum KEY_SETUP = 141;
+enum KEY_SLEEP = 142;
+enum KEY_WAKEUP = 143;
+enum KEY_FILE = 144;
+enum KEY_SENDFILE = 145;
+enum KEY_DELETEFILE = 146;
+enum KEY_XFER = 147;
+enum KEY_PROG1 = 148;
+enum KEY_PROG2 = 149;
+enum KEY_WWW = 150;
+enum KEY_MSDOS = 151;
+enum KEY_COFFEE = 152;
+enum KEY_SCREENLOCK = KEY_COFFEE;
+enum KEY_ROTATE_DISPLAY = 153;
+enum KEY_DIRECTION = KEY_ROTATE_DISPLAY;
+enum KEY_CYCLEWINDOWS = 154;
+enum KEY_MAIL = 155;
+enum KEY_BOOKMARKS = 156;
+enum KEY_COMPUTER = 157;
+enum KEY_BACK = 158;
+enum KEY_FORWARD = 159;
+enum KEY_CLOSECD = 160;
+enum KEY_EJECTCD = 161;
+enum KEY_EJECTCLOSECD = 162;
+enum KEY_NEXTSONG = 163;
+enum KEY_PLAYPAUSE = 164;
+enum KEY_PREVIOUSSONG = 165;
+enum KEY_STOPCD = 166;
+enum KEY_RECORD = 167;
+enum KEY_REWIND = 168;
+enum KEY_PHONE = 169;
+enum KEY_ISO = 170;
+enum KEY_CONFIG = 171;
+enum KEY_HOMEPAGE = 172;
+enum KEY_REFRESH = 173;
+enum KEY_EXIT = 174;
+enum KEY_MOVE = 175;
+enum KEY_EDIT = 176;
+enum KEY_SCROLLUP = 177;
+enum KEY_SCROLLDOWN = 178;
+enum KEY_KPLEFTPAREN = 179;
+enum KEY_KPRIGHTPAREN = 180;
+enum KEY_NEW = 181;
+enum KEY_REDO = 182;
+
+enum KEY_F13 = 183;
+enum KEY_F14 = 184;
+enum KEY_F15 = 185;
+enum KEY_F16 = 186;
+enum KEY_F17 = 187;
+enum KEY_F18 = 188;
+enum KEY_F19 = 189;
+enum KEY_F20 = 190;
+enum KEY_F21 = 191;
+enum KEY_F22 = 192;
+enum KEY_F23 = 193;
+enum KEY_F24 = 194;
+
+enum KEY_PLAYCD = 200;
+enum KEY_PAUSECD = 201;
+enum KEY_PROG3 = 202;
+enum KEY_PROG4 = 203;
+enum KEY_DASHBOARD = 204;
+enum KEY_SUSPEND = 205;
+enum KEY_CLOSE = 206;
+enum KEY_PLAY = 207;
+enum KEY_FASTFORWARD = 208;
+enum KEY_BASSBOOST = 209;
+enum KEY_PRINT = 210;
+enum KEY_HP = 211;
+enum KEY_CAMERA = 212;
+enum KEY_SOUND = 213;
+enum KEY_QUESTION = 214;
+enum KEY_EMAIL = 215;
+enum KEY_CHAT = 216;
+enum KEY_SEARCH = 217;
+enum KEY_CONNECT = 218;
+enum KEY_FINANCE = 219;
+enum KEY_SPORT = 220;
+enum KEY_SHOP = 221;
+enum KEY_ALTERASE = 222;
+enum KEY_CANCEL = 223;
+enum KEY_BRIGHTNESSDOWN = 224;
+enum KEY_BRIGHTNESSUP = 225;
+enum KEY_MEDIA = 226;
+
+enum KEY_SWITCHVIDEOMODE = 227;
+enum KEY_KBDILLUMTOGGLE = 228;
+enum KEY_KBDILLUMDOWN = 229;
+enum KEY_KBDILLUMUP = 230;
+
+enum KEY_SEND = 231;
+enum KEY_REPLY = 232;
+enum KEY_FORWARDMAIL = 233;
+enum KEY_SAVE = 234;
+enum KEY_DOCUMENTS = 235;
+
+enum KEY_BATTERY = 236;
+
+enum KEY_BLUETOOTH = 237;
+enum KEY_WLAN = 238;
+enum KEY_UWB = 239;
+
+enum KEY_UNKNOWN = 240;
+
+enum KEY_VIDEO_NEXT = 241;
+enum KEY_VIDEO_PREV = 242;
+enum KEY_BRIGHTNESS_CYCLE = 243;
+enum KEY_BRIGHTNESS_AUTO = 244;
+enum KEY_BRIGHTNESS_ZERO = KEY_BRIGHTNESS_AUTO;
+enum KEY_DISPLAY_OFF = 245;
+
+enum KEY_WWAN = 246;
+enum KEY_WIMAX = KEY_WWAN;
+enum KEY_RFKILL = 247;
+
+enum KEY_MICMUTE = 248;
+
+enum BTN_MISC = 0x100;
+enum BTN_0 = 0x100;
+enum BTN_1 = 0x101;
+enum BTN_2 = 0x102;
+enum BTN_3 = 0x103;
+enum BTN_4 = 0x104;
+enum BTN_5 = 0x105;
+enum BTN_6 = 0x106;
+enum BTN_7 = 0x107;
+enum BTN_8 = 0x108;
+enum BTN_9 = 0x109;
+
+enum BTN_MOUSE = 0x110;
+enum BTN_LEFT = 0x110;
+enum BTN_RIGHT = 0x111;
+enum BTN_MIDDLE = 0x112;
+enum BTN_SIDE = 0x113;
+enum BTN_EXTRA = 0x114;
+enum BTN_FORWARD = 0x115;
+enum BTN_BACK = 0x116;
+enum BTN_TASK = 0x117;
+
+enum BTN_JOYSTICK = 0x120;
+enum BTN_TRIGGER = 0x120;
+enum BTN_THUMB = 0x121;
+enum BTN_THUMB2 = 0x122;
+enum BTN_TOP = 0x123;
+enum BTN_TOP2 = 0x124;
+enum BTN_PINKIE = 0x125;
+enum BTN_BASE = 0x126;
+enum BTN_BASE2 = 0x127;
+enum BTN_BASE3 = 0x128;
+enum BTN_BASE4 = 0x129;
+enum BTN_BASE5 = 0x12a;
+enum BTN_BASE6 = 0x12b;
+enum BTN_DEAD = 0x12f;
+
+enum BTN_GAMEPAD = 0x130;
+enum BTN_SOUTH = 0x130;
+enum BTN_A = BTN_SOUTH;
+enum BTN_EAST = 0x131;
+enum BTN_B = BTN_EAST;
+enum BTN_C = 0x132;
+enum BTN_NORTH = 0x133;
+enum BTN_X = BTN_NORTH;
+enum BTN_WEST = 0x134;
+enum BTN_Y = BTN_WEST;
+enum BTN_Z = 0x135;
+enum BTN_TL = 0x136;
+enum BTN_TR = 0x137;
+enum BTN_TL2 = 0x138;
+enum BTN_TR2 = 0x139;
+enum BTN_SELECT = 0x13a;
+enum BTN_START = 0x13b;
+enum BTN_MODE = 0x13c;
+enum BTN_THUMBL = 0x13d;
+enum BTN_THUMBR = 0x13e;
+
+enum BTN_DIGI = 0x140;
+enum BTN_TOOL_PEN = 0x140;
+enum BTN_TOOL_RUBBER = 0x141;
+enum BTN_TOOL_BRUSH = 0x142;
+enum BTN_TOOL_PENCIL = 0x143;
+enum BTN_TOOL_AIRBRUSH = 0x144;
+enum BTN_TOOL_FINGER = 0x145;
+enum BTN_TOOL_MOUSE = 0x146;
+enum BTN_TOOL_LENS = 0x147;
+enum BTN_TOOL_QUINTTAP = 0x148;
+enum BTN_STYLUS3 = 0x149;
+enum BTN_TOUCH = 0x14a;
+enum BTN_STYLUS = 0x14b;
+enum BTN_STYLUS2 = 0x14c;
+enum BTN_TOOL_DOUBLETAP = 0x14d;
+enum BTN_TOOL_TRIPLETAP = 0x14e;
+enum BTN_TOOL_QUADTAP = 0x14f;
+
+enum BTN_WHEEL = 0x150;
+enum BTN_GEAR_DOWN = 0x150;
+enum BTN_GEAR_UP = 0x151;
+
+enum KEY_OK = 0x160;
+enum KEY_SELECT = 0x161;
+enum KEY_GOTO = 0x162;
+enum KEY_CLEAR = 0x163;
+enum KEY_POWER2 = 0x164;
+enum KEY_OPTION = 0x165;
+enum KEY_INFO = 0x166;
+enum KEY_TIME = 0x167;
+enum KEY_VENDOR = 0x168;
+enum KEY_ARCHIVE = 0x169;
+enum KEY_PROGRAM = 0x16a;
+enum KEY_CHANNEL = 0x16b;
+enum KEY_FAVORITES = 0x16c;
+enum KEY_EPG = 0x16d;
+enum KEY_PVR = 0x16e;
+enum KEY_MHP = 0x16f;
+enum KEY_LANGUAGE = 0x170;
+enum KEY_TITLE = 0x171;
+enum KEY_SUBTITLE = 0x172;
+enum KEY_ANGLE = 0x173;
+enum KEY_ZOOM = 0x174;
+enum KEY_MODE = 0x175;
+enum KEY_KEYBOARD = 0x176;
+enum KEY_SCREEN = 0x177;
+enum KEY_PC = 0x178;
+enum KEY_TV = 0x179;
+enum KEY_TV2 = 0x17a;
+enum KEY_VCR = 0x17b;
+enum KEY_VCR2 = 0x17c;
+enum KEY_SAT = 0x17d;
+enum KEY_SAT2 = 0x17e;
+enum KEY_CD = 0x17f;
+enum KEY_TAPE = 0x180;
+enum KEY_RADIO = 0x181;
+enum KEY_TUNER = 0x182;
+enum KEY_PLAYER = 0x183;
+enum KEY_TEXT = 0x184;
+enum KEY_DVD = 0x185;
+enum KEY_AUX = 0x186;
+enum KEY_MP3 = 0x187;
+enum KEY_AUDIO = 0x188;
+enum KEY_VIDEO = 0x189;
+enum KEY_DIRECTORY = 0x18a;
+enum KEY_LIST = 0x18b;
+enum KEY_MEMO = 0x18c;
+enum KEY_CALENDAR = 0x18d;
+enum KEY_RED = 0x18e;
+enum KEY_GREEN = 0x18f;
+enum KEY_YELLOW = 0x190;
+enum KEY_BLUE = 0x191;
+enum KEY_CHANNELUP = 0x192;
+enum KEY_CHANNELDOWN = 0x193;
+enum KEY_FIRST = 0x194;
+enum KEY_LAST = 0x195;
+enum KEY_AB = 0x196;
+enum KEY_NEXT = 0x197;
+enum KEY_RESTART = 0x198;
+enum KEY_SLOW = 0x199;
+enum KEY_SHUFFLE = 0x19a;
+enum KEY_BREAK = 0x19b;
+enum KEY_PREVIOUS = 0x19c;
+enum KEY_DIGITS = 0x19d;
+enum KEY_TEEN = 0x19e;
+enum KEY_TWEN = 0x19f;
+enum KEY_VIDEOPHONE = 0x1a0;
+enum KEY_GAMES = 0x1a1;
+enum KEY_ZOOMIN = 0x1a2;
+enum KEY_ZOOMOUT = 0x1a3;
+enum KEY_ZOOMRESET = 0x1a4;
+enum KEY_WORDPROCESSOR = 0x1a5;
+enum KEY_EDITOR = 0x1a6;
+enum KEY_SPREADSHEET = 0x1a7;
+enum KEY_GRAPHICSEDITOR = 0x1a8;
+enum KEY_PRESENTATION = 0x1a9;
+enum KEY_DATABASE = 0x1aa;
+enum KEY_NEWS = 0x1ab;
+enum KEY_VOICEMAIL = 0x1ac;
+enum KEY_ADDRESSBOOK = 0x1ad;
+enum KEY_MESSENGER = 0x1ae;
+enum KEY_DISPLAYTOGGLE = 0x1af;
+enum KEY_BRIGHTNESS_TOGGLE = KEY_DISPLAYTOGGLE;
+enum KEY_SPELLCHECK = 0x1b0;
+enum KEY_LOGOFF = 0x1b1;
+
+enum KEY_DOLLAR = 0x1b2;
+enum KEY_EURO = 0x1b3;
+
+enum KEY_FRAMEBACK = 0x1b4;
+enum KEY_FRAMEFORWARD = 0x1b5;
+enum KEY_CONTEXT_MENU = 0x1b6;
+enum KEY_MEDIA_REPEAT = 0x1b7;
+enum KEY_10CHANNELSUP = 0x1b8;
+enum KEY_10CHANNELSDOWN = 0x1b9;
+enum KEY_IMAGES = 0x1ba;
+
+enum KEY_DEL_EOL = 0x1c0;
+enum KEY_DEL_EOS = 0x1c1;
+enum KEY_INS_LINE = 0x1c2;
+enum KEY_DEL_LINE = 0x1c3;
+
+enum KEY_FN = 0x1d0;
+enum KEY_FN_ESC = 0x1d1;
+enum KEY_FN_F1 = 0x1d2;
+enum KEY_FN_F2 = 0x1d3;
+enum KEY_FN_F3 = 0x1d4;
+enum KEY_FN_F4 = 0x1d5;
+enum KEY_FN_F5 = 0x1d6;
+enum KEY_FN_F6 = 0x1d7;
+enum KEY_FN_F7 = 0x1d8;
+enum KEY_FN_F8 = 0x1d9;
+enum KEY_FN_F9 = 0x1da;
+enum KEY_FN_F10 = 0x1db;
+enum KEY_FN_F11 = 0x1dc;
+enum KEY_FN_F12 = 0x1dd;
+enum KEY_FN_1 = 0x1de;
+enum KEY_FN_2 = 0x1df;
+enum KEY_FN_D = 0x1e0;
+enum KEY_FN_E = 0x1e1;
+enum KEY_FN_F = 0x1e2;
+enum KEY_FN_S = 0x1e3;
+enum KEY_FN_B = 0x1e4;
+
+enum KEY_BRL_DOT1 = 0x1f1;
+enum KEY_BRL_DOT2 = 0x1f2;
+enum KEY_BRL_DOT3 = 0x1f3;
+enum KEY_BRL_DOT4 = 0x1f4;
+enum KEY_BRL_DOT5 = 0x1f5;
+enum KEY_BRL_DOT6 = 0x1f6;
+enum KEY_BRL_DOT7 = 0x1f7;
+enum KEY_BRL_DOT8 = 0x1f8;
+enum KEY_BRL_DOT9 = 0x1f9;
+enum KEY_BRL_DOT10 = 0x1fa;
+
+enum KEY_NUMERIC_0 = 0x200;
+enum KEY_NUMERIC_1 = 0x201;
+enum KEY_NUMERIC_2 = 0x202;
+enum KEY_NUMERIC_3 = 0x203;
+enum KEY_NUMERIC_4 = 0x204;
+enum KEY_NUMERIC_5 = 0x205;
+enum KEY_NUMERIC_6 = 0x206;
+enum KEY_NUMERIC_7 = 0x207;
+enum KEY_NUMERIC_8 = 0x208;
+enum KEY_NUMERIC_9 = 0x209;
+enum KEY_NUMERIC_STAR = 0x20a;
+enum KEY_NUMERIC_POUND = 0x20b;
+enum KEY_NUMERIC_A = 0x20c;
+enum KEY_NUMERIC_B = 0x20d;
+enum KEY_NUMERIC_C = 0x20e;
+enum KEY_NUMERIC_D = 0x20f;
+
+enum KEY_CAMERA_FOCUS = 0x210;
+enum KEY_WPS_BUTTON = 0x211;
+
+enum KEY_TOUCHPAD_TOGGLE = 0x212;
+enum KEY_TOUCHPAD_ON = 0x213;
+enum KEY_TOUCHPAD_OFF = 0x214;
+
+enum KEY_CAMERA_ZOOMIN = 0x215;
+enum KEY_CAMERA_ZOOMOUT = 0x216;
+enum KEY_CAMERA_UP = 0x217;
+enum KEY_CAMERA_DOWN = 0x218;
+enum KEY_CAMERA_LEFT = 0x219;
+enum KEY_CAMERA_RIGHT = 0x21a;
+
+enum KEY_ATTENDANT_ON = 0x21b;
+enum KEY_ATTENDANT_OFF = 0x21c;
+enum KEY_ATTENDANT_TOGGLE = 0x21d;
+enum KEY_LIGHTS_TOGGLE = 0x21e;
+
+enum BTN_DPAD_UP = 0x220;
+enum BTN_DPAD_DOWN = 0x221;
+enum BTN_DPAD_LEFT = 0x222;
+enum BTN_DPAD_RIGHT = 0x223;
+
+enum KEY_ALS_TOGGLE = 0x230;
+enum KEY_ROTATE_LOCK_TOGGLE = 0x231;
+
+enum KEY_BUTTONCONFIG = 0x240;
+enum KEY_TASKMANAGER = 0x241;
+enum KEY_JOURNAL = 0x242;
+enum KEY_CONTROLPANEL = 0x243;
+enum KEY_APPSELECT = 0x244;
+enum KEY_SCREENSAVER = 0x245;
+enum KEY_VOICECOMMAND = 0x246;
+enum KEY_ASSISTANT = 0x247;
+
+enum KEY_BRIGHTNESS_MIN = 0x250;
+enum KEY_BRIGHTNESS_MAX = 0x251;
+
+enum KEY_KBDINPUTASSIST_PREV = 0x260;
+enum KEY_KBDINPUTASSIST_NEXT = 0x261;
+enum KEY_KBDINPUTASSIST_PREVGROUP = 0x262;
+enum KEY_KBDINPUTASSIST_NEXTGROUP = 0x263;
+enum KEY_KBDINPUTASSIST_ACCEPT = 0x264;
+enum KEY_KBDINPUTASSIST_CANCEL = 0x265;
+
+enum KEY_RIGHT_UP = 0x266;
+enum KEY_RIGHT_DOWN = 0x267;
+enum KEY_LEFT_UP = 0x268;
+enum KEY_LEFT_DOWN = 0x269;
+
+enum KEY_ROOT_MENU = 0x26a;
+enum KEY_MEDIA_TOP_MENU = 0x26b;
+enum KEY_NUMERIC_11 = 0x26c;
+enum KEY_NUMERIC_12 = 0x26d;
+enum KEY_AUDIO_DESC = 0x26e;
+enum KEY_3D_MODE = 0x26f;
+enum KEY_NEXT_FAVORITE = 0x270;
+enum KEY_STOP_RECORD = 0x271;
+enum KEY_PAUSE_RECORD = 0x272;
+enum KEY_VOD = 0x273;
+enum KEY_UNMUTE = 0x274;
+enum KEY_FASTREVERSE = 0x275;
+enum KEY_SLOWREVERSE = 0x276;
+enum KEY_DATA = 0x277;
+enum KEY_ONSCREEN_KEYBOARD = 0x278;
+
+enum BTN_TRIGGER_HAPPY = 0x2c0;
+enum BTN_TRIGGER_HAPPY1 = 0x2c0;
+enum BTN_TRIGGER_HAPPY2 = 0x2c1;
+enum BTN_TRIGGER_HAPPY3 = 0x2c2;
+enum BTN_TRIGGER_HAPPY4 = 0x2c3;
+enum BTN_TRIGGER_HAPPY5 = 0x2c4;
+enum BTN_TRIGGER_HAPPY6 = 0x2c5;
+enum BTN_TRIGGER_HAPPY7 = 0x2c6;
+enum BTN_TRIGGER_HAPPY8 = 0x2c7;
+enum BTN_TRIGGER_HAPPY9 = 0x2c8;
+enum BTN_TRIGGER_HAPPY10 = 0x2c9;
+enum BTN_TRIGGER_HAPPY11 = 0x2ca;
+enum BTN_TRIGGER_HAPPY12 = 0x2cb;
+enum BTN_TRIGGER_HAPPY13 = 0x2cc;
+enum BTN_TRIGGER_HAPPY14 = 0x2cd;
+enum BTN_TRIGGER_HAPPY15 = 0x2ce;
+enum BTN_TRIGGER_HAPPY16 = 0x2cf;
+enum BTN_TRIGGER_HAPPY17 = 0x2d0;
+enum BTN_TRIGGER_HAPPY18 = 0x2d1;
+enum BTN_TRIGGER_HAPPY19 = 0x2d2;
+enum BTN_TRIGGER_HAPPY20 = 0x2d3;
+enum BTN_TRIGGER_HAPPY21 = 0x2d4;
+enum BTN_TRIGGER_HAPPY22 = 0x2d5;
+enum BTN_TRIGGER_HAPPY23 = 0x2d6;
+enum BTN_TRIGGER_HAPPY24 = 0x2d7;
+enum BTN_TRIGGER_HAPPY25 = 0x2d8;
+enum BTN_TRIGGER_HAPPY26 = 0x2d9;
+enum BTN_TRIGGER_HAPPY27 = 0x2da;
+enum BTN_TRIGGER_HAPPY28 = 0x2db;
+enum BTN_TRIGGER_HAPPY29 = 0x2dc;
+enum BTN_TRIGGER_HAPPY30 = 0x2dd;
+enum BTN_TRIGGER_HAPPY31 = 0x2de;
+enum BTN_TRIGGER_HAPPY32 = 0x2df;
+enum BTN_TRIGGER_HAPPY33 = 0x2e0;
+enum BTN_TRIGGER_HAPPY34 = 0x2e1;
+enum BTN_TRIGGER_HAPPY35 = 0x2e2;
+enum BTN_TRIGGER_HAPPY36 = 0x2e3;
+enum BTN_TRIGGER_HAPPY37 = 0x2e4;
+enum BTN_TRIGGER_HAPPY38 = 0x2e5;
+enum BTN_TRIGGER_HAPPY39 = 0x2e6;
+enum BTN_TRIGGER_HAPPY40 = 0x2e7;
+
+enum KEY_MIN_INTERESTING = KEY_MUTE;
+enum KEY_MAX = 0x2ff;
+enum KEY_CNT = (KEY_MAX+1);
+
+enum REL_X = 0x00;
+enum REL_Y = 0x01;
+enum REL_Z = 0x02;
+enum REL_RX = 0x03;
+enum REL_RY = 0x04;
+enum REL_RZ = 0x05;
+enum REL_HWHEEL = 0x06;
+enum REL_DIAL = 0x07;
+enum REL_WHEEL = 0x08;
+enum REL_MISC = 0x09;
+enum REL_MAX = 0x0f;
+enum REL_CNT = (REL_MAX+1);
+
+enum ABS_X = 0x00;
+enum ABS_Y = 0x01;
+enum ABS_Z = 0x02;
+enum ABS_RX = 0x03;
+enum ABS_RY = 0x04;
+enum ABS_RZ = 0x05;
+enum ABS_THROTTLE = 0x06;
+enum ABS_RUDDER = 0x07;
+enum ABS_WHEEL = 0x08;
+enum ABS_GAS = 0x09;
+enum ABS_BRAKE = 0x0a;
+enum ABS_HAT0X = 0x10;
+enum ABS_HAT0Y = 0x11;
+enum ABS_HAT1X = 0x12;
+enum ABS_HAT1Y = 0x13;
+enum ABS_HAT2X = 0x14;
+enum ABS_HAT2Y = 0x15;
+enum ABS_HAT3X = 0x16;
+enum ABS_HAT3Y = 0x17;
+enum ABS_PRESSURE = 0x18;
+enum ABS_DISTANCE = 0x19;
+enum ABS_TILT_X = 0x1a;
+enum ABS_TILT_Y = 0x1b;
+enum ABS_TOOL_WIDTH = 0x1c;
+
+enum ABS_VOLUME = 0x20;
+
+enum ABS_MISC = 0x28;
+
+enum ABS_MT_SLOT = 0x2f;
+enum ABS_MT_TOUCH_MAJOR = 0x30;
+enum ABS_MT_TOUCH_MINOR = 0x31;
+enum ABS_MT_WIDTH_MAJOR = 0x32;
+enum ABS_MT_WIDTH_MINOR = 0x33;
+enum ABS_MT_ORIENTATION = 0x34;
+enum ABS_MT_POSITION_X = 0x35;
+enum ABS_MT_POSITION_Y = 0x36;
+enum ABS_MT_TOOL_TYPE = 0x37;
+enum ABS_MT_BLOB_ID = 0x38;
+enum ABS_MT_TRACKING_ID = 0x39;
+enum ABS_MT_PRESSURE = 0x3a;
+enum ABS_MT_DISTANCE = 0x3b;
+enum ABS_MT_TOOL_X = 0x3c;
+enum ABS_MT_TOOL_Y = 0x3d;
+
+enum ABS_MAX = 0x3f;
+enum ABS_CNT = (ABS_MAX+1);
+
+enum SW_LID = 0x00;
+enum SW_TABLET_MODE = 0x01;
+enum SW_HEADPHONE_INSERT = 0x02;
+enum SW_RFKILL_ALL = 0x03;
+enum SW_RADIO = SW_RFKILL_ALL;
+enum SW_MICROPHONE_INSERT = 0x04;
+enum SW_DOCK = 0x05;
+enum SW_LINEOUT_INSERT = 0x06;
+enum SW_JACK_PHYSICAL_INSERT = 0x07;
+enum SW_VIDEOOUT_INSERT = 0x08;
+enum SW_CAMERA_LENS_COVER = 0x09;
+enum SW_KEYPAD_SLIDE = 0x0a;
+enum SW_FRONT_PROXIMITY = 0x0b;
+enum SW_ROTATE_LOCK = 0x0c;
+enum SW_LINEIN_INSERT = 0x0d;
+enum SW_MUTE_DEVICE = 0x0e;
+enum SW_PEN_INSERTED = 0x0f;
+enum SW_MAX = 0x0f;
+enum SW_CNT = (SW_MAX+1);
+
+enum MSC_SERIAL = 0x00;
+enum MSC_PULSELED = 0x01;
+enum MSC_GESTURE = 0x02;
+enum MSC_RAW = 0x03;
+enum MSC_SCAN = 0x04;
+enum MSC_TIMESTAMP = 0x05;
+enum MSC_MAX = 0x07;
+enum MSC_CNT = (MSC_MAX+1);
+
+enum LED_NUML = 0x00;
+enum LED_CAPSL = 0x01;
+enum LED_SCROLLL = 0x02;
+enum LED_COMPOSE = 0x03;
+enum LED_KANA = 0x04;
+enum LED_SLEEP = 0x05;
+enum LED_SUSPEND = 0x06;
+enum LED_MUTE = 0x07;
+enum LED_MISC = 0x08;
+enum LED_MAIL = 0x09;
+enum LED_CHARGING = 0x0a;
+enum LED_MAX = 0x0f;
+enum LED_CNT = (LED_MAX+1);
+
+enum REP_DELAY = 0x00;
+enum REP_PERIOD = 0x01;
+enum REP_MAX = 0x01;
+enum REP_CNT = (REP_MAX+1);
+
+enum SND_CLICK = 0x00;
+enum SND_BELL = 0x01;
+enum SND_TONE = 0x02;
+enum SND_MAX = 0x07;
+enum SND_CNT = (SND_MAX+1);
diff --git a/libphobos/libdruntime/core/sys/linux/uinput.d b/libphobos/libdruntime/core/sys/linux/uinput.d
new file mode 100644
index 0000000..abb61f9
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/linux/uinput.d
@@ -0,0 +1,85 @@
+module core.sys.linux.uinput;
+
+version (linux):
+extern(C):
+nothrow:
+
+import core.sys.posix.sys.ioctl;
+
+public import core.sys.linux.input;
+public import core.sys.linux.input_event_codes;
+
+enum UINPUT_VERSION = 5;
+enum UINPUT_MAX_NAME_SIZE = 80;
+
+struct uinput_ff_upload
+{
+ uint request_id;
+ int retval;
+ ff_effect effect;
+ ff_effect old;
+}
+
+struct uinput_ff_erase
+{
+ uint request_id;
+ int retval;
+ uint effect_id;
+}
+
+enum UINPUT_IOCTL_BASE = 'U';
+enum UI_DEV_CREATE = _IO(UINPUT_IOCTL_BASE, 1);
+enum UI_DEV_DESTROY = _IO(UINPUT_IOCTL_BASE, 2);
+
+struct uinput_setup
+{
+ input_id id;
+ char[UINPUT_MAX_NAME_SIZE] name;
+ uint ff_effects_max;
+}
+
+enum UI_DEV_SETUP = _IOW!uinput_setup(UINPUT_IOCTL_BASE, 3);
+
+struct uinput_abs_setup
+{
+ ushort code;
+
+ input_absinfo absinfo;
+}
+
+enum UI_ABS_SETUP = _IOW!uinput_abs_setup(UINPUT_IOCTL_BASE, 4);
+
+enum UI_SET_EVBIT = _IOW!int(UINPUT_IOCTL_BASE, 100);
+enum UI_SET_KEYBIT = _IOW!int(UINPUT_IOCTL_BASE, 101);
+enum UI_SET_RELBIT = _IOW!int(UINPUT_IOCTL_BASE, 102);
+enum UI_SET_ABSBIT = _IOW!int(UINPUT_IOCTL_BASE, 103);
+enum UI_SET_MSCBIT = _IOW!int(UINPUT_IOCTL_BASE, 104);
+enum UI_SET_LEDBIT = _IOW!int(UINPUT_IOCTL_BASE, 105);
+enum UI_SET_SNDBIT = _IOW!int(UINPUT_IOCTL_BASE, 106);
+enum UI_SET_FFBIT = _IOW!int(UINPUT_IOCTL_BASE, 107);
+enum UI_SET_PHYS = _IOW!(char*)(UINPUT_IOCTL_BASE, 108);
+enum UI_SET_SWBIT = _IOW!int(UINPUT_IOCTL_BASE, 109);
+enum UI_SET_PROPBIT = _IOW!int(UINPUT_IOCTL_BASE, 110);
+
+enum UI_BEGIN_FF_UPLOAD = _IOWR!uinput_ff_upload(UINPUT_IOCTL_BASE, 200);
+enum UI_END_FF_UPLOAD = _IOW!uinput_ff_upload(UINPUT_IOCTL_BASE, 201);
+enum UI_BEGIN_FF_ERASE = _IOWR!uinput_ff_erase(UINPUT_IOCTL_BASE, 202);
+enum UI_END_FF_ERASE = _IOW!uinput_ff_erase(UINPUT_IOCTL_BASE, 203);
+
+enum UI_GET_SYSNAME(len) = _IOC(_IOC_READ, UINPUT_IOCTL_BASE, 44, len);
+
+enum UI_GET_VERSION = _IOR!uint(UINPUT_IOCTL_BASE, 45);
+
+enum EV_UINPUT = 0x0101;
+enum UI_FF_UPLOAD = 1;
+enum UI_FF_ERASE = 2;
+
+struct uinput_user_dev {
+ char[UINPUT_MAX_NAME_SIZE] name;
+ input_id id;
+ uint ff_effects_max;
+ int[ABS_CNT] absmax;
+ int[ABS_CNT] absmin;
+ int[ABS_CNT] absfuzz;
+ int[ABS_CNT] absflat;
+}
diff --git a/libphobos/libdruntime/core/sys/openbsd/unistd.d b/libphobos/libdruntime/core/sys/openbsd/unistd.d
index 0b8580f..4232c03 100644
--- a/libphobos/libdruntime/core/sys/openbsd/unistd.d
+++ b/libphobos/libdruntime/core/sys/openbsd/unistd.d
@@ -12,6 +12,10 @@ extern (C):
nothrow:
@nogc:
+public import core.sys.posix.sys.types;
+
int getentropy(void*, size_t);
+int getthrname(pid_t, char*, size_t);
int pledge(const scope char*, const scope char*);
+int setthrname(pid_t, const scope char*);
int unveil(const scope char*, const scope char*);
diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d
index 367c1d9..5b02fb5 100644
--- a/libphobos/libdruntime/core/sys/windows/dll.d
+++ b/libphobos/libdruntime/core/sys/windows/dll.d
@@ -328,6 +328,8 @@ public:
* first access to a __declspec(thread) variable occurs, that is."
*
* _tls_index is initialized by the compiler to 0, so we can use this as a test.
+ * Returns:
+ * true for success, false for failure
*/
bool dll_fixTLS( HINSTANCE hInstance, void* tlsstart, void* tlsend, void* tls_callbacks_a, int* tlsindex ) nothrow
{
@@ -448,8 +450,13 @@ int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc
return ldrMod.LoadCount;
}
-// fixup TLS storage, initialize runtime and attach to threads
-// to be called from DllMain with reason DLL_PROCESS_ATTACH
+/*****************************
+ * To be called from DllMain with reason DLL_PROCESS_ATTACH
+ *
+ * fixup TLS storage, initialize runtime and attach to threads
+ * Returns:
+ * true = success, false = failure
+ */
bool dll_process_attach( HINSTANCE hInstance, bool attach_threads,
void* tlsstart, void* tlsend, void* tls_callbacks_a, int* tlsindex )
{
@@ -480,7 +487,8 @@ bool dll_process_attach( HINSTANCE hInstance, bool attach_threads,
}, null );
}
-// same as above, but only usable if druntime is linked statically
+/** same as above, but only usable if druntime is linked statically
+ */
bool dll_process_attach( HINSTANCE hInstance, bool attach_threads = true )
{
version (Win64)
@@ -495,7 +503,9 @@ bool dll_process_attach( HINSTANCE hInstance, bool attach_threads = true )
}
}
-// to be called from DllMain with reason DLL_PROCESS_DETACH
+/**
+ * to be called from DllMain with reason DLL_PROCESS_DETACH
+ */
void dll_process_detach( HINSTANCE hInstance, bool detach_threads = true )
{
// notify core.thread.joinLowLevelThread that the DLL is about to be unloaded
@@ -527,7 +537,11 @@ static bool tlsCtorRun;
static this() { tlsCtorRun = true; }
static ~this() { tlsCtorRun = false; }
-// to be called from DllMain with reason DLL_THREAD_ATTACH
+/**
+ * To be called from DllMain with reason DLL_THREAD_ATTACH
+ * Returns:
+ * true for success, false for failure
+ */
bool dll_thread_attach( bool attach_thread = true, bool initTls = true )
{
// if the OS has not prepared TLS for us, don't attach to the thread
@@ -546,7 +560,11 @@ bool dll_thread_attach( bool attach_thread = true, bool initTls = true )
return true;
}
-// to be called from DllMain with reason DLL_THREAD_DETACH
+/**
+ * To be called from DllMain with reason DLL_THREAD_DETACH
+ * Returns:
+ * true for success, false for failure
+ */
bool dll_thread_detach( bool detach_thread = true, bool exitTls = true )
{
// if the OS has not prepared TLS for us, we did not attach to the thread
@@ -562,14 +580,17 @@ bool dll_thread_detach( bool detach_thread = true, bool exitTls = true )
return true;
}
-/// A simple mixin to provide a $(D DllMain) which calls the necessary
-/// runtime initialization and termination functions automatically.
-///
-/// Instead of writing a custom $(D DllMain), simply write:
-///
-/// ---
-/// mixin SimpleDllMain;
-/// ---
+/**********************************
+ * A mixin to provide a $(D DllMain) which calls the necessary
+ * D runtime initialization and termination functions automatically.
+ *
+ * Example:
+ * ---
+ * module dllmain;
+ * import core.sys.windows.dll;
+ * mixin SimpleDllMain;
+ * ---
+ */
mixin template SimpleDllMain()
{
import core.sys.windows.windef : HINSTANCE, BOOL, DWORD, LPVOID;
diff --git a/libphobos/libdruntime/etc/valgrind/valgrind.d b/libphobos/libdruntime/etc/valgrind/valgrind.d
new file mode 100644
index 0000000..21829fc
--- /dev/null
+++ b/libphobos/libdruntime/etc/valgrind/valgrind.d
@@ -0,0 +1,85 @@
+/// D wrapper for the Valgrind client API.
+/// Note that you must include this file into your program's compilation
+/// and compile with `-debug=VALGRIND` to access the declarations below.
+module etc.valgrind.valgrind;
+
+version (StdDdoc)
+{
+ /// Mark the memory covered by `mem` as unaddressable.
+ void makeMemNoAccess (const(void)[] mem) nothrow @nogc;
+
+ /// Similarly, mark memory covered by `mem` as addressable but undefined.
+ void makeMemUndefined(const(void)[] mem) nothrow @nogc;
+
+ /// Similarly, mark memory covered by `mem` as addressable and defined.
+ void makeMemDefined (const(void)[] mem) nothrow @nogc;
+
+ /// Get the validity data for the address range covered by `mem` and copy it
+ /// into the provided `bits` array.
+ /// Returns:
+ /// - 0 if not running on valgrind
+ /// - 1 success
+ /// - 2 [previously indicated unaligned arrays; these are now allowed]
+ /// - 3 if any parts of `mem`/`bits` are not addressable.
+ /// The metadata is not copied in cases 0, 2 or 3 so it should be
+ /// impossible to segfault your system by using this call.
+ uint getVBits(const(void)[] mem, ubyte[] bits) nothrow @nogc;
+
+ /// Set the validity data for the address range covered by `mem`, copying it
+ /// from the provided `bits` array.
+ /// Returns:
+ /// - 0 if not running on valgrind
+ /// - 1 success
+ /// - 2 [previously indicated unaligned arrays; these are now allowed]
+ /// - 3 if any parts of `mem`/`bits` are not addressable.
+ /// The metadata is not copied in cases 0, 2 or 3 so it should be
+ /// impossible to segfault your system by using this call.
+ uint setVBits(const(void)[] mem, ubyte[] bits) nothrow @nogc;
+
+ /// Disable and re-enable reporting of addressing errors in the
+ /// address range covered by `mem`.
+ void disableAddrReportingInRange(const(void)[] mem) nothrow @nogc;
+
+ /// ditto
+ void enableAddrReportingInRange(const(void)[] mem) nothrow @nogc;
+}
+else:
+
+debug(VALGRIND):
+
+private extern(C) nothrow @nogc
+{
+ void _d_valgrind_make_mem_noaccess (const(void)* addr, size_t len);
+ void _d_valgrind_make_mem_undefined(const(void)* addr, size_t len);
+ void _d_valgrind_make_mem_defined (const(void)* addr, size_t len);
+ uint _d_valgrind_get_vbits(const(void)* addr, ubyte* bits, size_t len);
+ uint _d_valgrind_set_vbits(const(void)* addr, ubyte* bits, size_t len);
+ void _d_valgrind_disable_addr_reporting_in_range(const(void)* addr, size_t len);
+ void _d_valgrind_enable_addr_reporting_in_range (const(void)* addr, size_t len);
+}
+
+void makeMemNoAccess (const(void)[] mem) nothrow @nogc { _d_valgrind_make_mem_noaccess (mem.ptr, mem.length); }
+void makeMemUndefined(const(void)[] mem) nothrow @nogc { _d_valgrind_make_mem_undefined(mem.ptr, mem.length); }
+void makeMemDefined (const(void)[] mem) nothrow @nogc { _d_valgrind_make_mem_defined (mem.ptr, mem.length); }
+
+uint getVBits(const(void)[] mem, ubyte[] bits) nothrow @nogc
+{
+ assert(mem.length == bits.length);
+ return _d_valgrind_get_vbits(mem.ptr, bits.ptr, mem.length);
+}
+
+uint setVBits(const(void)[] mem, ubyte[] bits) nothrow @nogc
+{
+ assert(mem.length == bits.length);
+ return _d_valgrind_set_vbits(mem.ptr, bits.ptr, mem.length);
+}
+
+void disableAddrReportingInRange(const(void)[] mem) nothrow @nogc
+{
+ _d_valgrind_disable_addr_reporting_in_range(mem.ptr, mem.length);
+}
+
+void enableAddrReportingInRange(const(void)[] mem) nothrow @nogc
+{
+ _d_valgrind_enable_addr_reporting_in_range(mem.ptr, mem.length);
+}
diff --git a/libphobos/libdruntime/etc/valgrind/valgrind_.c b/libphobos/libdruntime/etc/valgrind/valgrind_.c
new file mode 100644
index 0000000..4dc4a17
--- /dev/null
+++ b/libphobos/libdruntime/etc/valgrind/valgrind_.c
@@ -0,0 +1,102 @@
+/**
+ * This file contains wrapper functions for macro-defined valgrind routines.
+ *
+ * Copyright: Copyright: Copyright (C) D Language Foundation 2023
+ * License: Distributed under the
+ * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
+ * (See accompanying file LICENSE)
+ * Source: $(DRUNTIMESRC etc/valgrind/valgrind.c)
+ */
+
+/* NOTE: This file has been patched from the original DMD distribution to
+ * work with the GDC compiler.
+ */
+#include "config.h"
+
+#ifdef ENABLE_VALGRIND_CHECKING
+
+#ifdef HAVE_STDDEF_H
+# include <stddef.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+#ifdef HAVE_VALGRIND_MEMCHECK_H
+# include <valgrind/memcheck.h>
+#elif defined HAVE_MEMCHECK_H
+# include <memcheck.h>
+#else
+# include <valgrind.h>
+#endif
+
+#ifndef VALGRIND_MAKE_MEM_NOACCESS
+# define VALGRIND_MAKE_MEM_NOACCESS VALGRIND_MAKE_NOACCESS
+#endif
+#ifndef VALGRIND_MAKE_MEM_UNDEFINED
+# define VALGRIND_MAKE_MEM_UNDEFINED VALGRIND_MAKE_WRITABLE
+#endif
+#ifndef VALGRIND_MAKE_MEM_DEFINED
+# define VALGRIND_MAKE_MEM_DEFINED VALGRIND_MAKE_READABLE
+#endif
+
+#ifndef VALGRIND_GET_VBITS
+# define VALGRIND_GET_VBITS(a,b,l) 0
+#endif
+#ifndef VALGRIND_SET_VBITS
+# define VALGRIND_SET_VBITS(a,b,l) 0
+#endif
+#ifndef VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE
+# define VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(a,l)
+#endif
+#ifndef VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE
+# define VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(a,l)
+#endif
+
+#define MAYBE_UNUSED __attribute__((unused))
+
+void _d_valgrind_make_mem_noaccess(const void* addr, size_t len)
+{
+ VALGRIND_DISCARD(VALGRIND_MAKE_MEM_NOACCESS(addr, len));
+}
+
+void _d_valgrind_make_mem_undefined(const void* addr, size_t len)
+{
+ VALGRIND_DISCARD(VALGRIND_MAKE_MEM_UNDEFINED(addr, len));
+}
+
+void _d_valgrind_make_mem_defined(const void* addr, size_t len)
+{
+ VALGRIND_DISCARD(VALGRIND_MAKE_MEM_DEFINED(addr, len));
+}
+
+unsigned _d_valgrind_get_vbits(const void* addr MAYBE_UNUSED,
+ char* bits MAYBE_UNUSED,
+ size_t len MAYBE_UNUSED)
+{
+ return VALGRIND_GET_VBITS(addr, bits, len);
+}
+
+unsigned _d_valgrind_set_vbits(const void* addr MAYBE_UNUSED,
+ char* bits MAYBE_UNUSED,
+ size_t len MAYBE_UNUSED)
+{
+ return VALGRIND_SET_VBITS(addr, bits, len);
+}
+
+void _d_valgrind_disable_addr_reporting_in_range(const void* addr MAYBE_UNUSED,
+ size_t len MAYBE_UNUSED)
+{
+ VALGRIND_DISCARD(VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(addr, len));
+}
+
+void _d_valgrind_enable_addr_reporting_in_range(const void* addr MAYBE_UNUSED,
+ size_t len MAYBE_UNUSED)
+{
+ VALGRIND_DISCARD(VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(addr, len));
+}
+
+#endif /* ENABLE_VALGRIND_CHECKING */
diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d
index 337eabf..b0889b6 100644
--- a/libphobos/libdruntime/object.d
+++ b/libphobos/libdruntime/object.d
@@ -289,8 +289,9 @@ if ((is(LHS : const Object) || is(LHS : const shared Object)) &&
// If same exact type => one call to method opEquals
if (typeid(lhs) is typeid(rhs) ||
!__ctfe && typeid(lhs).opEquals(typeid(rhs)))
- /* CTFE doesn't like typeid much. 'is' works, but opEquals doesn't
- (issue 7147). But CTFE also guarantees that equal TypeInfos are
+ /* CTFE doesn't like typeid much. 'is' works, but opEquals doesn't:
+ https://issues.dlang.org/show_bug.cgi?id=7147
+ But CTFE also guarantees that equal TypeInfos are
always identical. So, no opEquals needed during CTFE. */
{
return true;
@@ -983,7 +984,7 @@ class TypeInfo_Enum : TypeInfo
}
-@safe unittest // issue 12233
+@safe unittest // https://issues.dlang.org/show_bug.cgi?id=12233
{
static assert(is(typeof(TypeInfo.init) == TypeInfo));
assert(TypeInfo.init is null);
@@ -4195,8 +4196,11 @@ void destroy(bool initialize = true, T)(T obj) if (is(T == interface))
assert(c.s == "S"); // `c.s` is back to its inital state, `"S"`
assert(c.a.dtorCount == 1); // `c.a`'s destructor was called
assert(c.a.x == 10); // `c.a.x` is back to its inital state, `10`
+}
- // check C++ classes work too!
+/// C++ classes work too
+@system unittest
+{
extern (C++) class CPP
{
struct Agg
@@ -4247,6 +4251,34 @@ void destroy(bool initialize = true, T)(T obj) if (is(T == interface))
assert(i == 0); // `i` is back to its initial state `0`
}
+/// Nested struct type
+@system unittest
+{
+ int dtorCount;
+ struct A
+ {
+ int i;
+ ~this()
+ {
+ dtorCount++; // capture local variable
+ }
+ }
+ A a = A(5);
+ destroy!false(a);
+ assert(dtorCount == 1);
+ assert(a.i == 5);
+
+ destroy(a);
+ assert(dtorCount == 2);
+ assert(a.i == 0);
+
+ // the context pointer is now null
+ // restore it so the dtor can run
+ import core.lifetime : emplace;
+ emplace(&a, A(0));
+ // dtor also called here
+}
+
@system unittest
{
extern(C++)
diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index 40fa3e0..1245374 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -1307,12 +1307,19 @@ int hasArrayFinalizerInSegment(void* p, size_t size, in void[] segment) nothrow
return cast(size_t)(cast(void*)si.xdtor - segment.ptr) < segment.length;
}
+debug (VALGRIND) import etc.valgrind.valgrind;
+
// called by the GC
void finalize_array2(void* p, size_t size) nothrow
{
debug(PRINTF) printf("rt_finalize_array2(p = %p)\n", p);
TypeInfo_Struct si = void;
+ debug (VALGRIND)
+ {
+ auto block = p[0..size];
+ disableAddrReportingInRange(block);
+ }
if (size <= 256)
{
si = *cast(TypeInfo_Struct*)(p + size - size_t.sizeof);
@@ -1329,6 +1336,7 @@ void finalize_array2(void* p, size_t size) nothrow
size = *cast(size_t*)p;
p += LARGEPREFIX;
}
+ debug (VALGRIND) enableAddrReportingInRange(block);
try
{
@@ -2373,7 +2381,7 @@ unittest
unittest
{
- // bugzilla 13854
+ // https://issues.dlang.org/show_bug.cgi?id=13854
auto arr = new ubyte[PAGESIZE]; // ensure page size
auto info1 = GC.query(arr.ptr);
assert(info1.base !is arr.ptr); // offset is required for page size or larger
@@ -2416,7 +2424,7 @@ unittest
unittest
{
- // bugzilla 13878
+ // https://issues.dlang.org/show_bug.cgi?id=13878
auto arr = new ubyte[1];
auto info = GC.query(arr.ptr);
assert(info.attr & BlkAttr.NO_SCAN); // should be NO_SCAN
diff --git a/libphobos/libdruntime/rt/minfo.d b/libphobos/libdruntime/rt/minfo.d
index 7489150..b5c868f 100644
--- a/libphobos/libdruntime/rt/minfo.d
+++ b/libphobos/libdruntime/rt/minfo.d
@@ -268,7 +268,9 @@ struct ModuleGroup
}
}
// trim space to what is needed.
- edges[i] = (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges];
+ edges[i] = nEdges > 0
+ ? (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges]
+ : null;
}
}
diff --git a/libphobos/libdruntime/rt/util/typeinfo.d b/libphobos/libdruntime/rt/util/typeinfo.d
index 7b55693..730649e 100644
--- a/libphobos/libdruntime/rt/util/typeinfo.d
+++ b/libphobos/libdruntime/rt/util/typeinfo.d
@@ -545,7 +545,7 @@ unittest
unittest
{
- // Original test case from issue 13073
+ // Original test case from https://issues.dlang.org/show_bug.cgi?id=13073
uint x = 0x22_DF_FF_FF;
uint y = 0xA2_DF_FF_FF;
assert(!(x < y && y < x));
diff --git a/libphobos/m4/druntime/libraries.m4 b/libphobos/m4/druntime/libraries.m4
index 45a56f6..8dd9c7d 100644
--- a/libphobos/m4/druntime/libraries.m4
+++ b/libphobos/m4/druntime/libraries.m4
@@ -233,3 +233,56 @@ AC_DEFUN([DRUNTIME_LIBRARIES_UCONTEXT],
AC_MSG_ERROR([swapcontext required but not found]))
fi
])
+
+# DRUNTIME_LIBRARIES_VALGRIND
+# ------------------------------
+# Allow specifying whether to use valgrind integration in the GC, which enables
+# the D run-time to communicate which memory access operations are valid.
+# This is only required if `--enable-libphobos-checking=valgrind' was seen.
+AC_DEFUN([DRUNTIME_LIBRARIES_VALGRIND],
+[
+ AC_CHECK_HEADERS(stddef.h stdlib.h)
+
+ AC_CHECK_HEADER(valgrind.h, have_valgrind_h=yes, have_valgrind_h=no)
+
+ AC_MSG_CHECKING(for VALGRIND_DISCARD in <valgrind/memcheck.h>)
+ AC_PREPROC_IFELSE([AC_LANG_SOURCE(
+ [[#include <valgrind/memcheck.h>
+ #ifndef VALGRIND_DISCARD
+ #error VALGRIND_DISCARD not defined
+ #endif]])],
+ [have_valgrind_memcheck_h=yes],
+ [have_valgrind_memcheck_h=no])
+ AC_MSG_RESULT($have_valgrind_memcheck_h)
+ AC_MSG_CHECKING(for VALGRIND_DISCARD in <memcheck.h>)
+ AC_PREPROC_IFELSE([AC_LANG_SOURCE(
+ [[#include <memcheck.h>
+ #ifndef VALGRIND_DISCARD
+ #error VALGRIND_DISCARD not defined
+ #endif]])],
+ [have_memcheck_h=yes],
+ [have_memcheck_h=no])
+ AC_MSG_RESULT($have_memcheck_h)
+
+ if test x$VALGRIND_FLAG != x ; then
+ AC_DEFINE(ENABLE_VALGRIND_CHECKING, 1,
+ [Define to enable to integrate valgrind (a memory checker) in the GC.])
+ fi
+ if test $have_valgrind_memcheck_h = yes; then
+ AC_DEFINE(HAVE_VALGRIND_MEMCHECK_H, 1,
+ [Define if valgrind's valgrind/memcheck.h header is installed.])
+ fi
+ if test $have_memcheck_h = yes; then
+ AC_DEFINE(HAVE_MEMCHECK_H, 1,
+ [Define if valgrind's memcheck.h header is installed.])
+ fi
+
+ if test x$VALGRIND_FLAG != x; then
+ if (test $have_valgrind_h = no \
+ && test $have_memcheck_h = no \
+ && test $have_valgrind_memcheck_h = no); then
+ AC_MSG_ERROR([*** valgrind checking requested, but
+*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h])
+ fi
+ fi
+])
diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE
index d3ebf74..e0011d7 100644
--- a/libphobos/src/MERGE
+++ b/libphobos/src/MERGE
@@ -1,4 +1,4 @@
-8d3800bee23db56f71ef4066f74bce057fcce256
+1921d29df25f2b44d6014c224e2018ce63ac2b71
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 55ccb51..39927be 100644
--- a/libphobos/src/std/algorithm/iteration.d
+++ b/libphobos/src/std/algorithm/iteration.d
@@ -2026,7 +2026,7 @@ private struct ChunkByGroup(alias eq, Range, bool eqEquivalenceAssured)
}
}
- // Cannot be a copy constructor due to issue 22239
+ // Cannot be a copy constructor due to https://issues.dlang.org/show_bug.cgi?id=22239
this(this) @trusted
{
import core.lifetime : emplace;
@@ -2128,7 +2128,7 @@ if (isForwardRange!Range)
}();
}
- // Cannot be a copy constructor due to issue 22239
+ // Cannot be a copy constructor due to https://issues.dlang.org/show_bug.cgi?id=22239
this(this) @trusted
{
import core.lifetime : emplace;
diff --git a/libphobos/src/std/algorithm/mutation.d b/libphobos/src/std/algorithm/mutation.d
index 9b1d920..61b6a5e 100644
--- a/libphobos/src/std/algorithm/mutation.d
+++ b/libphobos/src/std/algorithm/mutation.d
@@ -3049,7 +3049,7 @@ if (isBlitAssignable!T && !is(typeof(lhs.proxySwap(rhs))))
swap(b1, b2);
}
-// issue 20732
+// https://issues.dlang.org/show_bug.cgi?id=20732
@safe unittest
{
static struct A
diff --git a/libphobos/src/std/algorithm/searching.d b/libphobos/src/std/algorithm/searching.d
index ee318c8..f061915 100644
--- a/libphobos/src/std/algorithm/searching.d
+++ b/libphobos/src/std/algorithm/searching.d
@@ -1282,7 +1282,7 @@ if (isInputRange!R &&
@safe pure unittest
{
- //example from issue 19727
+ //example from https://issues.dlang.org/show_bug.cgi?id=19727
import std.path : asRelativePath;
string[] ext = ["abc", "def", "ghi"];
string path = "/foo/file.def";
@@ -1315,19 +1315,12 @@ in
}
do
{
- import std.typecons : Rebindable;
+ import std.typecons : Rebindable2;
alias Element = ElementType!Range;
- Rebindable!Element seed = r.front;
+ auto seed = Rebindable2!Element(r.front);
r.popFront();
- static if (is(Rebindable!Element == T[], T))
- {
- return extremum!(map, selector)(r, seed);
- }
- else
- {
- return extremum!(map, selector)(r, seed.get);
- }
+ return extremum!(map, selector)(r, seed.get);
}
private auto extremum(alias map, alias selector = "a < b", Range,
@@ -1337,25 +1330,24 @@ if (isInputRange!Range && !isInfinite!Range &&
!is(CommonType!(ElementType!Range, RangeElementType) == void) &&
is(typeof(unaryFun!map(ElementType!(Range).init))))
{
- import std.typecons : Rebindable;
+ import std.typecons : Rebindable2;
alias mapFun = unaryFun!map;
alias selectorFun = binaryFun!selector;
alias Element = ElementType!Range;
alias CommonElement = CommonType!(Element, RangeElementType);
- Rebindable!CommonElement extremeElement = seedElement;
+ auto extremeElement = Rebindable2!CommonElement(seedElement);
// if we only have one statement in the loop, it can be optimized a lot better
static if (__traits(isSame, map, a => a))
{
-
// direct access via a random access range is faster
static if (isRandomAccessRange!Range)
{
foreach (const i; 0 .. r.length)
{
- if (selectorFun(r[i], extremeElement))
+ if (selectorFun(r[i], extremeElement.get))
{
extremeElement = r[i];
}
@@ -1365,7 +1357,7 @@ if (isInputRange!Range && !isInfinite!Range &&
{
while (!r.empty)
{
- if (selectorFun(r.front, extremeElement))
+ if (selectorFun(r.front, extremeElement.get))
{
extremeElement = r.front;
}
@@ -1376,7 +1368,7 @@ if (isInputRange!Range && !isInfinite!Range &&
else
{
alias MapType = Unqual!(typeof(mapFun(CommonElement.init)));
- MapType extremeElementMapped = mapFun(extremeElement);
+ MapType extremeElementMapped = mapFun(extremeElement.get);
// direct access via a random access range is faster
static if (isRandomAccessRange!Range)
@@ -1405,15 +1397,7 @@ if (isInputRange!Range && !isInfinite!Range &&
}
}
}
- // Rebindable is an alias to T for arrays
- static if (is(typeof(extremeElement) == T[], T))
- {
- return extremeElement;
- }
- else
- {
- return extremeElement.get;
- }
+ return extremeElement.get;
}
private auto extremum(alias selector = "a < b", Range)(Range r)
@@ -2309,7 +2293,7 @@ private R1 simpleMindedFind(alias pred, R1, R2)(R1 haystack, scope R2 needle)
@safe:
string _impl;
- // This is what triggers issue 7992.
+ // This is what triggers https://issues.dlang.org/show_bug.cgi?id=7992.
@property size_t length() const { return _impl.length; }
@property void length(size_t len) { _impl.length = len; }
@@ -2322,7 +2306,7 @@ private R1 simpleMindedFind(alias pred, R1, R2)(R1 haystack, scope R2 needle)
@property CustomString save() { return this; }
}
- // If issue 7992 occurs, this will throw an exception from calling
+ // If https://issues.dlang.org/show_bug.cgi?id=7992 occurs, this will throw an exception from calling
// popFront() on an empty range.
auto r = find(CustomString("a"), CustomString("b"));
assert(r.empty);
@@ -3880,6 +3864,14 @@ if (isInputRange!Range && !isInfinite!Range &&
assert(arr.maxElement!"a.val".val == 1);
}
+// https://issues.dlang.org/show_bug.cgi?id=23993
+@safe unittest
+{
+ import std.bigint : BigInt;
+
+ assert([BigInt(2), BigInt(3)].maxElement == BigInt(3));
+}
+
// minPos
/**
Computes a subrange of `range` starting at the first occurrence of `range`'s
diff --git a/libphobos/src/std/complex.d b/libphobos/src/std/complex.d
index 3b860fe..347e351 100644
--- a/libphobos/src/std/complex.d
+++ b/libphobos/src/std/complex.d
@@ -1066,7 +1066,7 @@ Complex!T asin(T)(Complex!T z) @safe pure nothrow @nogc
{
import std.math.operations : isClose;
import std.math.constants : PI;
- version (DigitalMars) {} else // Disabled because of issue 21376
+ version (DigitalMars) {} else // Disabled because of https://issues.dlang.org/show_bug.cgi?id=21376
assert(isClose(asin(complex(0.5f)), float(PI) / 6));
}
@@ -1092,7 +1092,7 @@ Complex!T acos(T)(Complex!T z) @safe pure nothrow @nogc
{
import std.math.operations : isClose;
import std.math.constants : PI;
- version (DigitalMars) {} else // Disabled because of issue 21376
+ version (DigitalMars) {} else // Disabled because of https://issues.dlang.org/show_bug.cgi?id=21376
assert(isClose(acos(complex(0.5f)), float(PI) / 3));
}
diff --git a/libphobos/src/std/container/array.d b/libphobos/src/std/container/array.d
index f5efe6d..0d6be93 100644
--- a/libphobos/src/std/container/array.d
+++ b/libphobos/src/std/container/array.d
@@ -1566,7 +1566,7 @@ if (!is(immutable T == immutable bool))
r2[0 .. 0] += 0;
}
-// Test issue 11194
+// Test https://issues.dlang.org/show_bug.cgi?id=11194
@system unittest
{
static struct S {
diff --git a/libphobos/src/std/conv.d b/libphobos/src/std/conv.d
index 89d4e5e..aabcd78 100644
--- a/libphobos/src/std/conv.d
+++ b/libphobos/src/std/conv.d
@@ -209,14 +209,14 @@ template to(T)
return toImpl!T(args);
}
- // Fix issue 6175
+ // Fix https://issues.dlang.org/show_bug.cgi?id=6175
T to(S)(ref S arg)
if (isStaticArray!S)
{
return toImpl!T(arg);
}
- // Fix issue 16108
+ // Fix https://issues.dlang.org/show_bug.cgi?id=16108
T to(S)(ref S arg)
if (isAggregateType!S && !isCopyable!S)
{
@@ -423,7 +423,7 @@ template to(T)
assert(c == "abcx");
}
-// Tests for issue 6175
+// Tests for https://issues.dlang.org/show_bug.cgi?id=6175
@safe pure nothrow unittest
{
char[9] sarr = "blablabla";
@@ -432,7 +432,7 @@ template to(T)
assert(sarr.length == darr.length);
}
-// Tests for issue 7348
+// Tests for https://issues.dlang.org/show_bug.cgi?id=7348
@safe pure /+nothrow+/ unittest
{
assert(to!string(null) == "null");
@@ -454,7 +454,7 @@ template to(T)
assert(text("a", s) == "aS");
}
-// Tests for issue 11390
+// Tests for https://issues.dlang.org/show_bug.cgi?id=11390
@safe pure /+nothrow+/ unittest
{
const(typeof(null)) ctn;
@@ -463,7 +463,7 @@ template to(T)
assert(to!string(itn) == "null");
}
-// Tests for issue 8729: do NOT skip leading WS
+// Tests for https://issues.dlang.org/show_bug.cgi?id=8729: do NOT skip leading WS
@safe pure unittest
{
import std.exception;
@@ -1370,7 +1370,7 @@ if (is (T == immutable) && isExactSomeString!T && is(S == enum))
S2 s2;
assert(to!string(s2) == "S2(42, 43.5)");
- // Test for issue 8080
+ // Test for https://issues.dlang.org/show_bug.cgi?id=8080
struct S8080
{
short[4] data;
@@ -1972,7 +1972,7 @@ $(UL
private T toImpl(T, S)(S value)
if (isInputRange!S && isSomeChar!(ElementEncodingType!S) &&
!isExactSomeString!T && is(typeof(parse!T(value))) &&
- // issue 20539
+ // https://issues.dlang.org/show_bug.cgi?id=20539
!(is(T == enum) && is(typeof(value == OriginalType!T.init)) && !isSomeString!(OriginalType!T)))
{
scope(success)
@@ -5560,7 +5560,7 @@ private bool isHexLiteral(String)(scope const String hexData)
static assert( ("5A 01A C FF de 1b"d).isHexLiteral);
static assert( ("0123456789abcdefABCDEF"d).isHexLiteral);
static assert( (" 012 34 5 6789 abcd ef\rAB\nCDEF"d).isHexLiteral);
- // library version allows what's pointed by issue 10454
+ // library version allows what's pointed by https://issues.dlang.org/show_bug.cgi?id=10454
static assert( ("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF").isHexLiteral);
}
@@ -5931,7 +5931,7 @@ if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) &&
}
}
-@safe unittest // opSlice (issue 16192)
+@safe unittest // opSlice (https://issues.dlang.org/show_bug.cgi?id=16192)
{
import std.meta : AliasSeq;
@@ -5959,7 +5959,7 @@ if ((radix == 2 || radix == 8 || radix == 10 || radix == 16) &&
for (; !r.empty; r.popFront(), ++i)
{
assert(original[i .. original.length].tupleof == r.tupleof);
- // tupleof is used to work around issue 16216.
+ // tupleof is used to work around https://issues.dlang.org/show_bug.cgi?id=16216.
}
// opSlice vs popBack
diff --git a/libphobos/src/std/exception.d b/libphobos/src/std/exception.d
index 6ffc0f7..1d93d35 100644
--- a/libphobos/src/std/exception.d
+++ b/libphobos/src/std/exception.d
@@ -1035,7 +1035,7 @@ Params:
Bugs:
The function is explicitly annotated `@nogc` because inference could fail,
- see $(LINK2 https://issues.dlang.org/show_bug.cgi?id=17084, issue 17084).
+ see $(LINK2 https://issues.dlang.org/show_bug.cgi?id=17084, Bugzilla issue 17084).
Returns: `true` if `source`'s representation embeds a pointer
that points to `target`'s representation or somewhere inside
diff --git a/libphobos/src/std/experimental/allocator/building_blocks/kernighan_ritchie.d b/libphobos/src/std/experimental/allocator/building_blocks/kernighan_ritchie.d
index 65226e7..6883d33 100644
--- a/libphobos/src/std/experimental/allocator/building_blocks/kernighan_ritchie.d
+++ b/libphobos/src/std/experimental/allocator/building_blocks/kernighan_ritchie.d
@@ -827,7 +827,7 @@ version (StdUnittest)
// Both sequences must work on either system
- // A sequence of allocs which generates the error described in issue 16564
+ // A sequence of allocs which generates the error described in https://issues.dlang.org/show_bug.cgi?id=16564
// that is a gap at the end of buf from the perspective of the allocator
// for 64 bit systems (leftover balance = 8 bytes < 16)
diff --git a/libphobos/src/std/format/internal/floats.d b/libphobos/src/std/format/internal/floats.d
index 632bf76..afe0bfa 100644
--- a/libphobos/src/std/format/internal/floats.d
+++ b/libphobos/src/std/format/internal/floats.d
@@ -1449,7 +1449,7 @@ if (is(T == float) || is(T == double)
assert(printFloat(-0.1L, f) == "-1.000000e-01");
assert(printFloat(10.0L, f) == "1.000000e+01");
assert(printFloat(-10.0L, f) == "-1.000000e+01");
- version (Windows) {} // issue 20972
+ version (Windows) {} // https://issues.dlang.org/show_bug.cgi?id=20972
else
{
assert(printFloat(1e4000L, f) == "1.000000e+4000");
@@ -1472,7 +1472,7 @@ if (is(T == float) || is(T == double)
{
// log2 is broken for x87-reals on some computers in CTFE
// the following tests excludes these computers from the tests
- // (issue 21757)
+ // (https://issues.dlang.org/show_bug.cgi?id=21757)
enum test = cast(int) log2(3.05e2312L);
static if (real.mant_dig == 64 && test == 7681)
{
@@ -2120,7 +2120,7 @@ if (is(T == float) || is(T == double)
assert(printFloat(-0.1L, f) == "-0.100000");
assert(printFloat(10.0L, f) == "10.000000");
assert(printFloat(-10.0L, f) == "-10.000000");
- version (Windows) {} // issue 20972
+ version (Windows) {} // https://issues.dlang.org/show_bug.cgi?id=20972
else
{
auto result1 = printFloat(1e4000L, f);
@@ -2145,7 +2145,7 @@ if (is(T == float) || is(T == double)
{
// log2 is broken for x87-reals on some computers in CTFE
// the following tests excludes these computers from the tests
- // (issue 21757)
+ // (https://issues.dlang.org/show_bug.cgi?id=21757)
enum test = cast(int) log2(3.05e2312L);
static if (real.mant_dig == 64 && test == 7681)
{
@@ -2803,7 +2803,7 @@ if (is(T == float) || is(T == double)
assert(printFloat(-0.1L, f) == "-0.1");
assert(printFloat(10.0L, f) == "10");
assert(printFloat(-10.0L, f) == "-10");
- version (Windows) {} // issue 20972
+ version (Windows) {} // https://issues.dlang.org/show_bug.cgi?id=20972
else
{
assert(printFloat(1e4000L, f) == "1e+4000");
@@ -2826,7 +2826,7 @@ if (is(T == float) || is(T == double)
{
// log2 is broken for x87-reals on some computers in CTFE
// the following tests excludes these computers from the tests
- // (issue 21757)
+ // (https://issues.dlang.org/show_bug.cgi?id=21757)
enum test = cast(int) log2(3.05e2312L);
static if (real.mant_dig == 64 && test == 7681)
{
diff --git a/libphobos/src/std/format/internal/write.d b/libphobos/src/std/format/internal/write.d
index 7f127c0..8eb70ea 100644
--- a/libphobos/src/std/format/internal/write.d
+++ b/libphobos/src/std/format/internal/write.d
@@ -738,7 +738,7 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
assert(FloatingPointControl.rounding == FloatingPointControl.roundToNearest);
}
- // issue 20320
+ // https://issues.dlang.org/show_bug.cgi?id=20320
real a = 0.16;
real b = 0.016;
assert(format("%.1f", a) == "0.2");
@@ -749,7 +749,7 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
assert(format("%.1f", a1) == "0.2");
assert(format("%.2f", b1) == "0.02");
- // issue 9889
+ // https://issues.dlang.org/show_bug.cgi?id=9889
assert(format("%.1f", 0.09) == "0.1");
assert(format("%.1f", -0.09) == "-0.1");
assert(format("%.1f", 0.095) == "0.1");
@@ -907,7 +907,7 @@ if (is(FloatingPointTypeOf!T) && !is(T == enum) && !hasToString!(T, Char))
// log2 is broken for x87-reals on some computers in CTFE
// the following test excludes these computers from the test
- // (issue 21757)
+ // (https://issues.dlang.org/show_bug.cgi?id=21757)
enum test = cast(int) log2(3.05e2312L);
static if (real.mant_dig == 64 && test == 7681) // 80 bit reals
{
@@ -3334,7 +3334,7 @@ if (isSomeString!T1 && isSomeString!T2 && isSomeString!T3 && isSomeString!T4)
long fractsWidth = fracts.length; // TODO: does not take graphemes into account
long suffixWidth;
- // TODO: remove this workaround which hides issue 21815
+ // TODO: remove this workaround which hides https://issues.dlang.org/show_bug.cgi?id=21815
if (f.width > 0)
{
prefixWidth = getWidth(prefix);
diff --git a/libphobos/src/std/math/operations.d b/libphobos/src/std/math/operations.d
index f2e1800..4bf19ee 100644
--- a/libphobos/src/std/math/operations.d
+++ b/libphobos/src/std/math/operations.d
@@ -1287,11 +1287,12 @@ bool isClose(T, U, V = CommonType!(FloatingPointBaseType!T,FloatingPointBaseType
// two numbers
if (lhs == rhs) return true;
- static if (is(typeof(lhs.infinity)) && is(typeof(rhs.infinity)))
- {
- if (lhs == lhs.infinity || rhs == rhs.infinity ||
- lhs == -lhs.infinity || rhs == -rhs.infinity) return false;
- }
+ static if (is(typeof(lhs.infinity)))
+ if (lhs == lhs.infinity || lhs == -lhs.infinity)
+ return false;
+ static if (is(typeof(rhs.infinity)))
+ if (rhs == rhs.infinity || rhs == -rhs.infinity)
+ return false;
import std.math.algebraic : abs;
@@ -1406,6 +1407,8 @@ bool isClose(T, U, V = CommonType!(FloatingPointBaseType!T,FloatingPointBaseType
assert(!isClose(1,real.nan));
assert(!isClose(real.nan,real.max));
assert(!isClose(real.nan,real.nan));
+
+ assert(!isClose(-double.infinity, 1));
}
@safe pure nothrow @nogc unittest
@@ -1950,7 +1953,7 @@ if (isFloatingPoint!T)
// log2 is broken for x87-reals on some computers in CTFE
// the following test excludes these computers from the test
- // (issue 21757)
+ // (https://issues.dlang.org/show_bug.cgi?id=21757)
enum test = cast(int) log2(3.05e2312L);
static if (F.realFormat == RealFormat.ieeeExtended && test == 7681)
{
diff --git a/libphobos/src/std/path.d b/libphobos/src/std/path.d
index e81f2b6..449235a 100644
--- a/libphobos/src/std/path.d
+++ b/libphobos/src/std/path.d
@@ -1595,7 +1595,7 @@ if (isSomeChar!C)
@safe unittest
{
- // Test for issue 7397
+ // Test for https://issues.dlang.org/show_bug.cgi?id=7397
string[] ary = ["a", "b"];
version (Posix)
{
@@ -1875,7 +1875,7 @@ if (isSomeChar!C)
@safe unittest
{
- // Test for issue 7397
+ // Test for https://issues.dlang.org/show_bug.cgi?id=7397
string[] ary = ["a", "b"];
version (Posix)
{
@@ -2745,7 +2745,7 @@ else version (Posix)
See_Also:
$(LREF asAbsolutePath) which does not allocate
*/
-string absolutePath(string path, lazy string base = getcwd())
+string absolutePath(return scope const string path, lazy string base = getcwd())
@safe pure
{
import std.array : array;
@@ -2792,6 +2792,19 @@ string absolutePath(string path, lazy string base = getcwd())
assertThrown(absolutePath("bar", "foo"));
}
+// Ensure that we can call absolute path with scope paramaters
+@safe unittest
+{
+ string testAbsPath(scope const string path, scope const string base) {
+ return absolutePath(path, base);
+ }
+
+ version (Posix)
+ assert(testAbsPath("some/file", "/foo/bar") == "/foo/bar/some/file");
+ version (Windows)
+ assert(testAbsPath(`some\file`, `c:\foo\bar`) == `c:\foo\bar\some\file`);
+}
+
/** Transforms `path` into an absolute path.
The following algorithm is used:
@@ -3559,7 +3572,8 @@ if (isConvertibleToString!Range)
assert(!globMatch("foo.bar", "[gh]???bar"));
assert(!globMatch("foo.bar"w, "[!fg]*bar"w));
assert(!globMatch("foo.bar"d, "[fg]???baz"d));
- assert(!globMatch("foo.di", "*.d")); // test issue 6634: triggered bad assertion
+ // https://issues.dlang.org/show_bug.cgi?id=6634
+ assert(!globMatch("foo.di", "*.d")); // triggered bad assertion
assert(globMatch("foo.bar", "{foo,bif}.bar"));
assert(globMatch("bif.bar"w, "{foo,bif}.bar"w));
diff --git a/libphobos/src/std/random.d b/libphobos/src/std/random.d
index 066ed17..87e63f3 100644
--- a/libphobos/src/std/random.d
+++ b/libphobos/src/std/random.d
@@ -2842,7 +2842,7 @@ auto ref choice(Range)(ref Range range)
"Choice did not return a valid element from the given Range");
}
-@safe unittest // issue 18631
+@safe unittest // https://issues.dlang.org/show_bug.cgi?id=18631
{
auto rng = MinstdRand0(42);
const a = [0,1,2];
@@ -2855,7 +2855,7 @@ auto ref choice(Range)(ref Range range)
auto z1 = choice(cast(const)[1, 2, 3], rng);
}
-@safe unittest // Ref range (issue 18631 PR)
+@safe unittest // Ref range (https://issues.dlang.org/show_bug.cgi?id=18631 PR)
{
struct TestRange
{
diff --git a/libphobos/src/std/range/package.d b/libphobos/src/std/range/package.d
index d37c641..191ec32 100644
--- a/libphobos/src/std/range/package.d
+++ b/libphobos/src/std/range/package.d
@@ -3902,24 +3902,17 @@ Returns:
struct Repeat(T)
{
private:
- //Store a non-qualified T when possible: This is to make Repeat assignable
- static if ((is(T == class) || is(T == interface)) && (is(T == const) || is(T == immutable)))
- {
- import std.typecons : Rebindable;
- alias UT = Rebindable!T;
- }
- else static if (is(T : Unqual!T) && is(Unqual!T : T))
- alias UT = Unqual!T;
- else
- alias UT = T;
- UT _value;
+ import std.typecons : Rebindable2;
+
+ // Store a rebindable T to make Repeat assignable.
+ Rebindable2!T _value;
public:
/// Range primitives
- @property inout(T) front() inout { return _value; }
+ @property inout(T) front() inout { return _value.get; }
/// ditto
- @property inout(T) back() inout { return _value; }
+ @property inout(T) back() inout { return _value.get; }
/// ditto
enum bool empty = false;
@@ -3934,7 +3927,7 @@ public:
@property auto save() inout { return this; }
/// ditto
- inout(T) opIndex(size_t) inout { return _value; }
+ inout(T) opIndex(size_t) inout { return _value.get; }
/// ditto
auto opSlice(size_t i, size_t j)
@@ -3959,7 +3952,12 @@ public:
}
/// Ditto
-Repeat!T repeat(T)(T value) { return Repeat!T(value); }
+Repeat!T repeat(T)(T value)
+{
+ import std.typecons : Rebindable2;
+
+ return Repeat!T(Rebindable2!T(value));
+}
///
pure @safe nothrow unittest
@@ -9144,7 +9142,7 @@ public:
{
static if (needsEndTracker)
{
- if (poppedElems < windowSize)
+ if (nextSource.empty)
hasShownPartialBefore = true;
}
else
@@ -10124,6 +10122,15 @@ public:
assert("ab cd".splitter(' ').slide!(No.withPartial)(2).equal!equal([["ab", "cd"]]));
}
+// https://issues.dlang.org/show_bug.cgi?id=23976
+@safe unittest
+{
+ import std.algorithm.comparison : equal;
+ import std.algorithm.iteration : splitter;
+
+ assert("1<2".splitter('<').slide(2).equal!equal([["1", "2"]]));
+}
+
private struct OnlyResult(Values...)
if (Values.length > 1)
{
@@ -10339,7 +10346,7 @@ if (!is(CommonType!Values == void))
/// ditto
auto only()()
{
- // cannot use noreturn due to issue 22383
+ // cannot use noreturn due to https://issues.dlang.org/show_bug.cgi?id=22383
struct EmptyElementType {}
EmptyElementType[] result;
return result;
diff --git a/libphobos/src/std/regex/internal/ir.d b/libphobos/src/std/regex/internal/ir.d
index ec0cb66..3b38f9c 100644
--- a/libphobos/src/std/regex/internal/ir.d
+++ b/libphobos/src/std/regex/internal/ir.d
@@ -49,10 +49,29 @@ CharMatcher[CodepointSet] matcherCache;
}
}
-@property ref wordMatcher()()
+// Force pure because that is needed
+// Templated so that we don't pull in std.uni wordCharacter unnecessarily.
+@property ref wordMatcher()() pure
{
- static immutable CharMatcher matcher = CharMatcher(wordCharacter);
- return matcher;
+ static auto actual()
+ {
+ static CharMatcher matcher;
+ static bool haveMatcher;
+
+ if (!haveMatcher)
+ {
+ matcher = CharMatcher(wordCharacter);
+ haveMatcher = true;
+ }
+
+ return &matcher;
+ }
+
+ // WORKAROUND: if the compiler won't memoize the output of the function for us,
+ // we'll do it with pure and there will be casts and it'll be happy about it.
+ // This is unfortunately needed to make std.regex as a whole faster to import & use
+ // in build times ~500ms.
+ return *(cast(immutable(CharMatcher)* function() @safe nothrow @nogc pure)&actual)();
}
// some special Unicode white space characters
diff --git a/libphobos/src/std/signals.d b/libphobos/src/std/signals.d
index e5dc67e..97004d5 100644
--- a/libphobos/src/std/signals.d
+++ b/libphobos/src/std/signals.d
@@ -624,7 +624,7 @@ void linkin() { }
a.value6 = 46;
}
-// Triggers bug from issue 15341
+// Triggers bug from https://issues.dlang.org/show_bug.cgi?id=15341
@system unittest
{
class Observer
@@ -666,7 +666,7 @@ version (none) // Disabled because of https://issues.dlang.org/show_bug.cgi?id=5
}
}
-// Triggers bug from issue 16249
+// Triggers bug from https://issues.dlang.org/show_bug.cgi?id=16249
@system unittest
{
class myLINE
diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d
index 5ed685f..19ce988 100644
--- a/libphobos/src/std/stdio.d
+++ b/libphobos/src/std/stdio.d
@@ -34,9 +34,17 @@ $(TR $(TD Misc) $(TD
))
))
-Standard I/O functions that extend $(B core.stdc.stdio). $(B core.stdc.stdio)
+Standard I/O functions that extend $(LINK2 https://dlang.org/phobos/core_stdc_stdio.html, core.stdc.stdio). $(B core.stdc.stdio)
is $(D_PARAM public)ally imported when importing $(B std.stdio).
+There are three layers of I/O:
+$(OL
+$(LI The lowest layer is the operating system layer. The two main schemes are Windows and Posix.)
+$(LI C's $(TT stdio.h) which unifies the two operating system schemes.)
+$(LI $(TT std.stdio), this module, unifies the various $(TT stdio.h) implementations into
+a high level package for D programs.)
+)
+
Source: $(PHOBOSSRC std/stdio.d)
Copyright: Copyright The D Language Foundation 2007-.
License: $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
@@ -48,6 +56,55 @@ CSTDIO=$(HTTP cplusplus.com/reference/cstdio/$1/, $1)
*/
module std.stdio;
+/*
+# Glossary
+
+The three layers have many terms for their data structures and types.
+Here we try to bring some sanity to them for the intrepid code spelunker.
+
+## Windows
+
+Handle
+
+ A Windows handle is an opaque object of type HANDLE.
+ The `HANDLE` for standard devices can be retrieved with
+ Windows `GetStdHandle()`.
+
+## Posix
+
+file descriptor, aka fileno, aka fildes
+
+ An int from 0..`FOPEN_MAX`, which is an index into some internal data
+ structure.
+ 0 is for `stdin`, 1 for `stdout`, 2 for `stderr`.
+ Negative values usually indicate an error.
+
+## stdio.h
+
+`FILE`
+
+ A struct that encapsulates the C library's view of the operating system
+ files. A `FILE` should only be referred to via a pointer.
+
+`fileno`
+
+ A field of `FILE` which is the Posix file descriptor for Posix systems, and
+ and an index into an array of file `HANDLE`s for Windows.
+ This array is how Posix behavior is emulated on Windows.
+ For Digital Mars C, that array is `__osfhnd[]`, and is initialized
+ at program start by the C runtime library.
+ In this module, they are typed as `fileno_t`.
+
+`stdin`, `stdout`, `stderr`
+
+ Global pointers to `FILE` representing standard input, output, and error streams.
+ Being global means there are synchronization issues when multiple threads
+ are doing I/O on the same streams.
+
+## std.stdio
+
+*/
+
import core.stdc.stddef : wchar_t;
public import core.stdc.stdio;
import std.algorithm.mutation : copy;
@@ -129,6 +186,10 @@ else version (Solaris)
{
version = GENERIC_IO;
}
+else
+{
+ static assert(0, "unsupported operating system");
+}
// Character type used for operating system filesystem APIs
version (Windows)
@@ -140,6 +201,7 @@ else
private alias FSChar = char;
}
+private alias fileno_t = int; // file descriptor, fildes, fileno
version (Windows)
{
@@ -203,7 +265,7 @@ version (DIGITAL_MARS_STDIO)
// @@@DEPRECATED_2.107@@@
deprecated("internal function _fileno was unintentionally available from "
~ "std.stdio and will be removed afer 2.107")
- int _fileno(FILE* f) { return f._file; }
+ fileno_t _fileno(FILE* f) { return f._file; }
}
else version (MICROSOFT_STDIO)
{
@@ -550,7 +612,7 @@ Throws: `ErrnoException` if the file could not be opened.
stdioOpenmode, "'")),
name);
- // MSVCRT workaround (issue 14422)
+ // MSVCRT workaround (https://issues.dlang.org/show_bug.cgi?id=14422)
version (MICROSOFT_STDIO)
{
setAppendWin(stdioOpenmode);
@@ -708,7 +770,7 @@ Throws: `ErrnoException` in case of error.
{
auto handle = _p.handle;
_p.handle = null;
- // fclose disassociates the FILE* even in case of error (issue 19751)
+ // fclose disassociates the FILE* even in case of error (https://issues.dlang.org/show_bug.cgi?id=19751)
errnoEnforce(.fclose(handle) == 0,
"Could not close file `"~_name~"'");
}
@@ -1140,7 +1202,7 @@ Throws: `ErrnoException` if the file is not opened or the call to `fread` fails.
enforce(isOpen, "Attempting to read from an unopened file");
version (Windows)
{
- immutable fd = .fileno(_p.handle);
+ immutable fileno_t fd = .fileno(_p.handle);
immutable mode = .__setmode(fd, _O_BINARY);
scope(exit) .__setmode(fd, mode);
version (DIGITAL_MARS_STDIO)
@@ -1230,7 +1292,7 @@ Throws: `ErrnoException` if the file is not opened or if the call to `fwrite` fa
version (Windows)
{
- immutable fd = .fileno(_p.handle);
+ immutable fileno_t fd = .fileno(_p.handle);
immutable oldMode = .__setmode(fd, _O_BINARY);
if (oldMode != _O_BINARY)
@@ -2287,7 +2349,7 @@ Returns the `FILE*` corresponding to this object.
/**
Returns the file number corresponding to this object.
*/
- @property int fileno() const @trusted
+ @property fileno_t fileno() const @trusted
{
import std.exception : enforce;
@@ -3108,10 +3170,13 @@ is empty, throws an `Exception`. In case of an I/O error throws
// "wide-oriented" for us.
immutable int mode = __setmode(f.fileno, _O_TEXT);
// Set some arbitrary mode to obtain the previous one.
- __setmode(f.fileno, mode); // Restore previous mode.
- if (mode & (_O_WTEXT | _O_U16TEXT | _O_U8TEXT))
+ if (mode != -1) // __setmode() succeeded
{
- orientation_ = 1; // wide
+ __setmode(f.fileno, mode); // Restore previous mode.
+ if (mode & (_O_WTEXT | _O_U16TEXT | _O_U8TEXT))
+ {
+ orientation_ = 1; // wide
+ }
}
}
else
@@ -3336,7 +3401,8 @@ is empty, throws an `Exception`. In case of an I/O error throws
version (Windows)
{
- int fd, oldMode;
+ fileno_t fd;
+ int oldMode;
version (DIGITAL_MARS_STDIO)
ubyte oldInfo;
}
@@ -3795,7 +3861,7 @@ void main()
assert(std.file.readText!string(deleteme) == "y");
}
-@safe unittest // issue 18801
+@safe unittest // https://issues.dlang.org/show_bug.cgi?id=18801
{
static import std.file;
import std.string : stripLeft;
diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d
index 689f0ae..4dc569d 100644
--- a/libphobos/src/std/traits.d
+++ b/libphobos/src/std/traits.d
@@ -5337,7 +5337,7 @@ package template isBlitAssignable(T)
enum isBlitAssignable = isBlitAssignable!(OriginalType!T);
}
else static if (isStaticArray!T && is(T == E[n], E, size_t n))
- // Workaround for issue 11499 : isStaticArray!T should not be necessary.
+ // Workaround for https://issues.dlang.org/show_bug.cgi?id=11499 : isStaticArray!T should not be necessary.
{
enum isBlitAssignable = isBlitAssignable!E;
}
@@ -8877,7 +8877,9 @@ template getSymbolsByUDA(alias symbol, alias attribute)
@Attr void c();
}
- static assert(getSymbolsByUDA!(A, Attr).stringof == "tuple(a, a, c)");
+ alias ola = __traits(getOverloads, A, "a");
+ static assert(__traits(isSame, getSymbolsByUDA!(A, Attr),
+ AliasSeq!(ola[0], ola[1], A.c)));
}
// getSymbolsByUDA no longer works on modules
diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d
index 0748d52..67a1ede 100644
--- a/libphobos/src/std/typecons.d
+++ b/libphobos/src/std/typecons.d
@@ -2955,6 +2955,140 @@ Rebindable!T rebindable(T)(Rebindable!T obj)
assert(rebindable(pr3341_aa)[321] == 543);
}
+package(std) struct Rebindable2(T)
+{
+private:
+ static if (isAssignable!(typeof(cast() T.init)))
+ {
+ enum useQualifierCast = true;
+
+ typeof(cast() T.init) data;
+ }
+ else
+ {
+ enum useQualifierCast = false;
+
+ align(T.alignof)
+ static struct Payload
+ {
+ static if (hasIndirections!T)
+ {
+ void[T.sizeof] data;
+ }
+ else
+ {
+ ubyte[T.sizeof] data;
+ }
+ }
+
+ Payload data;
+ }
+
+public:
+
+ static if (!__traits(compiles, { T value; }))
+ {
+ @disable this();
+ }
+
+ /**
+ * Constructs a `Rebindable2` from a given value.
+ */
+ this(T value) @trusted
+ {
+ static if (useQualifierCast)
+ {
+ this.data = cast() value;
+ }
+ else
+ {
+ set(value);
+ }
+ }
+
+ /**
+ * Overwrites the currently stored value with `value`.
+ */
+ void opAssign(this This)(T value) @trusted
+ {
+ clear;
+ set(value);
+ }
+
+ /**
+ * Returns the value currently stored in the `Rebindable2`.
+ */
+ T get(this This)() @property @trusted
+ {
+ static if (useQualifierCast)
+ {
+ return cast(T) this.data;
+ }
+ else
+ {
+ return *cast(T*) &this.data;
+ }
+ }
+
+ /// Ditto
+ inout(T) get() inout @property @trusted
+ {
+ static if (useQualifierCast)
+ {
+ return cast(inout(T)) this.data;
+ }
+ else
+ {
+ return *cast(inout(T)*) &this.data;
+ }
+ }
+
+ static if (!useQualifierCast)
+ {
+ ~this() @trusted
+ {
+ clear;
+ }
+ }
+
+private:
+
+ void set(this This)(T value)
+ {
+ static if (useQualifierCast)
+ {
+ this.data = cast() value;
+ }
+ else
+ {
+ // As we're escaping a copy of `value`, deliberately leak a copy:
+ static union DontCallDestructor
+ {
+ T value;
+ }
+ DontCallDestructor copy = DontCallDestructor(value);
+ this.data = *cast(Payload*) &copy;
+ }
+ }
+
+ void clear(this This)()
+ {
+ // work around reinterpreting cast being impossible in CTFE
+ if (__ctfe)
+ {
+ return;
+ }
+
+ // call possible struct destructors
+ .destroy!(No.initialize)(*cast(T*) &this.data);
+ }
+}
+
+package(std) Rebindable2!T rebindable2(T)(T value)
+{
+ return Rebindable2!T(value);
+}
+
/**
Similar to `Rebindable!(T)` but strips all qualifiers from the reference as
opposed to just constness / immutability. Primary intended use case is with
diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d
index e2a0de7..6ab6ba0 100644
--- a/libphobos/src/std/uni/package.d
+++ b/libphobos/src/std/uni/package.d
@@ -8592,7 +8592,7 @@ public:
Decomposes a Hangul syllable. If `ch` is not a composed syllable
then this function returns $(LREF Grapheme) containing only `ch` as is.
*/
-Grapheme decomposeHangul(dchar ch) @safe
+Grapheme decomposeHangul(dchar ch) nothrow pure @safe
{
immutable idxS = cast(int) ch - jamoSBase;
if (idxS < 0 || idxS >= jamoSCount) return Grapheme(ch);
@@ -8709,7 +8709,15 @@ enum {
In cases where the string in question is already normalized,
it is returned unmodified and no memory allocation happens.
+/
-inout(C)[] normalize(NormalizationForm norm=NFC, C)(return scope inout(C)[] input)
+/*
+ WARNING: @trusted lambda inside - handle with same care as @trusted
+ functions
+
+ Despite being a template, the attributes do no harm since this doesn't work
+ with user-defined range or character types anyway.
+*/
+pure @safe inout(C)[] normalize(NormalizationForm norm=NFC, C)
+ (return scope inout(C)[] input)
{
import std.algorithm.mutation : SwapStrategy;
import std.algorithm.sorting : sort;
@@ -8790,20 +8798,24 @@ inout(C)[] normalize(NormalizationForm norm=NFC, C)(return scope inout(C)[] inpu
// reset variables
decomposed.length = 0;
() @trusted {
- decomposed.assumeSafeAppend();
+ // assumeSafeAppend isn't considered pure as of writing, hence the
+ // cast. It isn't pure in the sense that the elements after
+ // the array in question are affected, but we don't use those
+ // making the call pure for our purposes.
+ (cast(void delegate() pure nothrow) {decomposed.assumeSafeAppend();})();
ccc.length = 0;
- ccc.assumeSafeAppend();
+ (cast(void delegate() pure nothrow) {ccc.assumeSafeAppend();})();
} ();
input = input[anchors[1]..$];
// and move on
anchors = splitNormalized!norm(input);
- }while (anchors[0] != input.length);
+ } while (anchors[0] != input.length);
app.put(input[0 .. anchors[0]]);
return () @trusted inout { return cast(inout(C)[]) app.data; } ();
}
///
-@safe unittest
+@safe pure unittest
{
// any encoding works
wstring greet = "Hello world";
@@ -8817,7 +8829,7 @@ inout(C)[] normalize(NormalizationForm norm=NFC, C)(return scope inout(C)[] inpu
assert(normalize!NFKD("ϓ") == "\u03A5\u0301");
}
-@safe unittest
+@safe pure unittest
{
import std.conv : text;
@@ -8825,18 +8837,9 @@ inout(C)[] normalize(NormalizationForm norm=NFC, C)(return scope inout(C)[] inpu
assert(normalize!NFKD("2¹⁰") == "210", normalize!NFKD("2¹⁰"));
assert(normalize!NFD("Äffin") == "A\u0308ffin");
- // check example
-
- // any encoding works
- wstring greet = "Hello world";
+ // test with dstring
+ dstring greet = "Hello world";
assert(normalize(greet) is greet); // the same exact slice
-
- // An example of a character with all 4 forms being different:
- // Greek upsilon with acute and hook symbol (code point 0x03D3)
- assert(normalize!NFC("ϓ") == "\u03D3");
- assert(normalize!NFD("ϓ") == "\u03D2\u0301");
- assert(normalize!NFKC("ϓ") == "\u038E");
- assert(normalize!NFKD("ϓ") == "\u03A5\u0301");
}
// canonically recompose given slice of code points, works in-place and mutates data