diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-07-10 17:16:17 +0200 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-07-10 23:31:29 +0200 |
commit | e9251fea2debebfebe1f762a4a8d5b3b1d4c75ef (patch) | |
tree | 09b47f4d760019131aa27d19bfb8e5ee0f1ed31f /libphobos | |
parent | 2d7c95e31431a297060c94697af84f498abf97a2 (diff) | |
download | gcc-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')
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*) © + } + } + + 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 |