From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id 67F533858C52; Sat, 29 Oct 2022 11:03:01 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 67F533858C52 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1667041381; bh=9izeeSWy0p9DyY/dKOtxRSreTmzxI1aamh05vT9/res=; h=From:To:Subject:Date:From; b=HLTi3bDVIODqirzG4xXdYBSDVco9Yis7QEq4ujsI5qTuRxi0f0GtndxCuJaT5Kvuq h/cnUJcfQMUEhkmfTirZDnk6AAzvwCRXugP5f5HQGahxf23a6Bkjr0ZSOyP3flOMxo FZMQy2dYJ0E0YFw2eUuCSNWfEFHwJoPK4uGunm0s= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-3560] d: Merge upstream dmd, druntime e4f8919591, phobos 3ad507b51. X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/master X-Git-Oldrev: cfd85418051e8413e84ae7011cb5cb99cd8e337c X-Git-Newrev: 7e7ebe3e350fde90fe49ab41ce3b92a811bb6370 Message-Id: <20221029110301.67F533858C52@sourceware.org> Date: Sat, 29 Oct 2022 11:03:01 +0000 (GMT) List-Id: https://gcc.gnu.org/g:7e7ebe3e350fde90fe49ab41ce3b92a811bb6370 commit r13-3560-g7e7ebe3e350fde90fe49ab41ce3b92a811bb6370 Author: Iain Buclaw Date: Sat Oct 29 09:05:54 2022 +0200 d: Merge upstream dmd, druntime e4f8919591, phobos 3ad507b51. D front-end changes: - Import dmd v2.101.0-beta.1. - Add predefined version `D_Optimized' when compiling with `-O'. - Shortened method syntax (DIP1043) is now enabled by default. - Array literals assigned to `scope' array variables are now allocated on the stack. - Implement `@system' variables (DIP1035), available behind the preview feature flag `-fpreview=systemvariables'. D runtime changes: - Import druntime v2.101.0-beta.1. Phobos changes: - Import phobos v2.101.0-beta.1. - Added `std.typecons.SafeRefCounted', that can be used in `@safe' code with `-fpreview=dip1000'. gcc/d/ChangeLog: * d-attribs.cc (apply_user_attributes): Update for new front-end interface. * d-builtins.cc (d_init_versions): Predefine `D_Optimized' with compiling with optimizations enabled. * d-lang.cc (d_handle_option): Update for new front-end interface. Handle new option `-fpreview=systemvariables'. * dmd/MERGE: Merge upstream dmd e4f8919591. * dmd/VERSION: Bump version to v2.101.0-beta.1. * expr.cc (ExprVisitor::visit (AssignExp *)): Treat construction of static arrays from a call expression as a simple assignment. (ExprVisitor::visit (ArrayLiteralExp *)): Handle array literals with `scope' storage. * gdc.texi: Update documentation of `-fpreview=' options. * lang.opt (fpreview=shortenedmethods): Remove. (fpreview=systemvariables): New option. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime e4f8919591. * src/MERGE: Merge upstream phobos 3ad507b51. gcc/testsuite/ChangeLog: * gdc.dg/simd19630.d: Move tests with errors to ... * gdc.dg/simd19630b.d: ... here. New test. * gdc.dg/simd19630c.d: New test. * gdc.dg/simd_ctfe.d: Removed. * gdc.dg/simd18867.d: New test. * gdc.dg/simd19788.d: New test. * gdc.dg/simd21469.d: New test. * gdc.dg/simd21672.d: New test. * gdc.dg/simd23077.d: New test. * gdc.dg/simd23084.d: New test. * gdc.dg/simd23085.d: New test. * gdc.dg/torture/simd19632.d: New test. * gdc.dg/torture/simd20041.d: New test. * gdc.dg/torture/simd21673.d: New test. * gdc.dg/torture/simd21676.d: New test. * gdc.dg/torture/simd22438.d: New test. * gdc.dg/torture/simd23009.d: New test. * gdc.dg/torture/simd23077.d: New test. * gdc.dg/torture/simd8.d: New test. * gdc.dg/torture/simd9.d: New test. * gdc.dg/torture/simd_prefetch.d: New test. Diff: --- gcc/d/d-attribs.cc | 5 +- gcc/d/d-builtins.cc | 3 + gcc/d/d-lang.cc | 10 +- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/VERSION | 2 +- gcc/d/dmd/aggregate.d | 2 +- gcc/d/dmd/aggregate.h | 4 +- gcc/d/dmd/attrib.d | 41 -- gcc/d/dmd/attrib.h | 1 - gcc/d/dmd/clone.d | 22 +- gcc/d/dmd/common/bitfields.d | 9 +- gcc/d/dmd/common/file.d | 11 +- gcc/d/dmd/cparse.d | 39 +- gcc/d/dmd/cppmangle.d | 10 +- gcc/d/dmd/dcast.d | 114 ++- gcc/d/dmd/declaration.d | 59 +- gcc/d/dmd/declaration.h | 66 +- gcc/d/dmd/dinterpret.d | 6 + gcc/d/dmd/dmodule.d | 435 ++++++------ gcc/d/dmd/dscope.d | 6 +- gcc/d/dmd/dstruct.d | 33 +- gcc/d/dmd/dsymbol.d | 54 +- gcc/d/dmd/dsymbol.h | 16 +- gcc/d/dmd/dsymbolsem.d | 204 ++++-- gcc/d/dmd/dtemplate.d | 4 +- gcc/d/dmd/entity.d | 236 +++--- gcc/d/dmd/escape.d | 369 ++++------ gcc/d/dmd/expression.d | 2 +- gcc/d/dmd/expression.h | 1 + gcc/d/dmd/expressionsem.d | 173 +++-- gcc/d/dmd/func.d | 276 +++---- gcc/d/dmd/globals.d | 5 +- gcc/d/dmd/globals.h | 6 +- gcc/d/dmd/hdrgen.d | 27 +- gcc/d/dmd/lexer.d | 48 +- gcc/d/dmd/module.h | 2 +- gcc/d/dmd/mtype.d | 69 +- gcc/d/dmd/mtype.h | 5 + gcc/d/dmd/nogc.d | 4 +- gcc/d/dmd/parse.d | 6 +- gcc/d/dmd/printast.d | 7 + gcc/d/dmd/root/utf.d | 2 +- gcc/d/dmd/safe.d | 10 +- gcc/d/dmd/semantic3.d | 44 +- gcc/d/dmd/statementsem.d | 188 +++-- gcc/d/dmd/templateparamsem.d | 9 + gcc/d/dmd/transitivevisitor.d | 9 + gcc/d/expr.cc | 9 + gcc/d/gdc.texi | 8 +- gcc/d/lang.opt | 4 +- gcc/testsuite/gdc.dg/simd18867.d | 11 + gcc/testsuite/gdc.dg/simd19630.d | 10 - gcc/testsuite/gdc.dg/simd19630b.d | 17 + gcc/testsuite/gdc.dg/simd19630c.d | 15 + gcc/testsuite/gdc.dg/simd19788.d | 11 + gcc/testsuite/gdc.dg/simd21469.d | 9 + gcc/testsuite/gdc.dg/simd21672.d | 17 + gcc/testsuite/gdc.dg/simd23077.d | 11 + gcc/testsuite/gdc.dg/simd23084.d | 17 + gcc/testsuite/gdc.dg/simd23085.d | 11 + gcc/testsuite/gdc.dg/simd_ctfe.d | 88 --- gcc/testsuite/gdc.dg/torture/simd19632.d | 15 + gcc/testsuite/gdc.dg/torture/simd20041.d | 22 + gcc/testsuite/gdc.dg/torture/simd21673.d | 20 + gcc/testsuite/gdc.dg/torture/simd21676.d | 36 + gcc/testsuite/gdc.dg/torture/simd22438.d | 18 + gcc/testsuite/gdc.dg/torture/simd23009.d | 22 + gcc/testsuite/gdc.dg/torture/simd23077.d | 11 + gcc/testsuite/gdc.dg/torture/simd8.d | 26 + gcc/testsuite/gdc.dg/torture/simd9.d | 46 ++ gcc/testsuite/gdc.dg/torture/simd_prefetch.d | 21 + gcc/testsuite/gdc.test/compilable/cdcmp.d | 14 - .../gdc.test/compilable/extra-files/header2.d | 19 + .../gdc.test/compilable/imports/cimports2a.i | 7 + .../gdc.test/compilable/imports/cimports2b.i | 8 + .../gdc.test/compilable/imports/pkg22952/package.d | 1 + gcc/testsuite/gdc.test/compilable/noreturn3.d | 257 +++++++ .../gdc.test/compilable/scope_tuple_expansion.d | 21 + .../gdc.test/compilable/shortened_methods.d | 2 +- gcc/testsuite/gdc.test/compilable/test11980.d | 5 +- gcc/testsuite/gdc.test/compilable/test22674.d | 7 + gcc/testsuite/gdc.test/compilable/test22784.d | 10 + gcc/testsuite/gdc.test/compilable/test22952.d | 10 + gcc/testsuite/gdc.test/compilable/test23380.d | 9 + gcc/testsuite/gdc.test/compilable/test23386.d | 12 + .../gdc.test/fail_compilation/diag23384.d | 29 + .../gdc.test/fail_compilation/fail10905.d | 22 - .../gdc.test/fail_compilation/fail19898a.d | 2 +- .../gdc.test/fail_compilation/fail19898b.d | 2 +- .../gdc.test/fail_compilation/fail22366.d | 2 +- .../gdc.test/fail_compilation/fail23406.d | 40 ++ .../gdc.test/fail_compilation/issue21378.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/lexer1.d | 3 +- .../gdc.test/fail_compilation/pragmainline.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/pragmas.d | 4 +- .../gdc.test/fail_compilation/previewin.d | 6 +- .../gdc.test/fail_compilation/reserved_version.d | 3 + .../fail_compilation/reserved_version_switch.d | 3 + gcc/testsuite/gdc.test/fail_compilation/retscope.d | 6 +- .../gdc.test/fail_compilation/retscope2.d | 2 +- .../gdc.test/fail_compilation/retscope6.d | 2 +- .../gdc.test/fail_compilation/systemvariables.d | 48 ++ .../fail_compilation/systemvariables_deprecation.d | 28 + .../fail_compilation/systemvariables_struct.d | 60 ++ .../fail_compilation/systemvariables_void_init.d | 32 + .../gdc.test/fail_compilation/templatethis.d | 37 + .../gdc.test/fail_compilation/test14496.d | 3 +- .../gdc.test/fail_compilation/test17764.d | 2 +- .../gdc.test/fail_compilation/test19097.d | 2 +- .../gdc.test/fail_compilation/test22145.d | 2 +- .../gdc.test/fail_compilation/test22680.d | 2 +- .../gdc.test/fail_compilation/warn14905.d | 23 + gcc/testsuite/gdc.test/fail_compilation/xmmslice.d | 22 + gcc/testsuite/gdc.test/runnable/cdcmp.d | 146 ++++ gcc/testsuite/gdc.test/runnable/lexer.d | 4 + gcc/testsuite/gdc.test/runnable/test20734.d | 8 + gcc/testsuite/gdc.test/runnable/test23337.d | 182 +++++ libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/core/stdc/fenv.d | 1 - libphobos/libdruntime/core/stdc/signal.d | 1 - libphobos/libdruntime/core/stdc/stdarg.d | 1 - libphobos/libdruntime/core/stdc/stdio.d | 1 - libphobos/libdruntime/core/stdc/stdlib.d | 1 - libphobos/libdruntime/core/stdc/string.d | 1 - libphobos/libdruntime/core/stdc/wchar_.d | 1 - libphobos/libdruntime/core/sys/darwin/fcntl.d | 1 - libphobos/libdruntime/core/sys/darwin/ifaddrs.d | 1 - libphobos/libdruntime/core/sys/elf/package.d | 1 - libphobos/libdruntime/core/sys/linux/dlfcn.d | 1 - libphobos/libdruntime/core/sys/linux/elf.d | 1 - libphobos/libdruntime/core/sys/linux/epoll.d | 2 - libphobos/libdruntime/core/sys/linux/err.d | 1 - libphobos/libdruntime/core/sys/linux/errno.d | 1 - libphobos/libdruntime/core/sys/linux/execinfo.d | 1 - libphobos/libdruntime/core/sys/linux/fcntl.d | 1 - libphobos/libdruntime/core/sys/linux/fs.d | 1 - libphobos/libdruntime/core/sys/linux/ifaddrs.d | 1 - libphobos/libdruntime/core/sys/linux/io_uring.d | 2 - libphobos/libdruntime/core/sys/linux/link.d | 1 - libphobos/libdruntime/core/sys/linux/perf_event.d | 1 - libphobos/libdruntime/core/sys/linux/sched.d | 1 - libphobos/libdruntime/core/sys/linux/stdio.d | 3 +- libphobos/libdruntime/core/sys/linux/string.d | 1 - libphobos/libdruntime/core/sys/linux/sys/eventfd.d | 1 - libphobos/libdruntime/core/sys/linux/sys/inotify.d | 1 - libphobos/libdruntime/core/sys/linux/sys/mman.d | 1 - libphobos/libdruntime/core/sys/linux/sys/prctl.d | 1 - .../libdruntime/core/sys/linux/sys/signalfd.d | 1 - libphobos/libdruntime/core/sys/linux/sys/sysinfo.d | 1 - libphobos/libdruntime/core/sys/linux/sys/xattr.d | 1 - libphobos/libdruntime/core/sys/linux/timerfd.d | 1 - libphobos/libdruntime/core/sys/linux/tipc.d | 1 - libphobos/libdruntime/core/sys/linux/unistd.d | 1 - libphobos/libdruntime/core/sys/openbsd/sys/mman.d | 1 + libphobos/libdruntime/core/sys/posix/aio.d | 1 - libphobos/libdruntime/core/sys/posix/config.d | 1 - libphobos/libdruntime/core/sys/posix/dirent.d | 1 - libphobos/libdruntime/core/sys/posix/dlfcn.d | 1 - libphobos/libdruntime/core/sys/posix/fcntl.d | 1 - libphobos/libdruntime/core/sys/posix/grp.d | 1 - libphobos/libdruntime/core/sys/posix/iconv.d | 1 - libphobos/libdruntime/core/sys/posix/inttypes.d | 1 - libphobos/libdruntime/core/sys/posix/libgen.d | 1 - libphobos/libdruntime/core/sys/posix/locale.d | 1 - libphobos/libdruntime/core/sys/posix/mqueue.d | 1 - libphobos/libdruntime/core/sys/posix/netdb.d | 1 - libphobos/libdruntime/core/sys/posix/poll.d | 1 - libphobos/libdruntime/core/sys/posix/pthread.d | 1 - libphobos/libdruntime/core/sys/posix/pwd.d | 1 - libphobos/libdruntime/core/sys/posix/sched.d | 1 - libphobos/libdruntime/core/sys/posix/semaphore.d | 1 - libphobos/libdruntime/core/sys/posix/setjmp.d | 1 - libphobos/libdruntime/core/sys/posix/spawn.d | 1 - libphobos/libdruntime/core/sys/posix/stdio.d | 1 - libphobos/libdruntime/core/sys/posix/stdlib.d | 1 - libphobos/libdruntime/core/sys/posix/string.d | 1 - libphobos/libdruntime/core/sys/posix/strings.d | 1 - libphobos/libdruntime/core/sys/posix/sys/filio.d | 1 - libphobos/libdruntime/core/sys/posix/sys/ioccom.d | 1 - libphobos/libdruntime/core/sys/posix/sys/ioctl.d | 1 - libphobos/libdruntime/core/sys/posix/sys/ipc.d | 1 - libphobos/libdruntime/core/sys/posix/sys/mman.d | 1 - libphobos/libdruntime/core/sys/posix/sys/msg.d | 1 - .../libdruntime/core/sys/posix/sys/resource.d | 1 - libphobos/libdruntime/core/sys/posix/sys/select.d | 1 - libphobos/libdruntime/core/sys/posix/sys/shm.d | 1 - libphobos/libdruntime/core/sys/posix/sys/socket.d | 1 - libphobos/libdruntime/core/sys/posix/sys/stat.d | 1 - libphobos/libdruntime/core/sys/posix/sys/statvfs.d | 1 - libphobos/libdruntime/core/sys/posix/sys/time.d | 1 - libphobos/libdruntime/core/sys/posix/sys/ttycom.d | 1 - libphobos/libdruntime/core/sys/posix/sys/types.d | 1 - libphobos/libdruntime/core/sys/posix/sys/uio.d | 1 - libphobos/libdruntime/core/sys/posix/sys/un.d | 1 - libphobos/libdruntime/core/sys/posix/sys/utsname.d | 1 - libphobos/libdruntime/core/sys/posix/sys/wait.d | 1 - libphobos/libdruntime/core/sys/posix/syslog.d | 1 - libphobos/libdruntime/core/sys/posix/termios.d | 1 - libphobos/libdruntime/core/sys/posix/time.d | 1 - libphobos/libdruntime/core/sys/posix/ucontext.d | 1 - libphobos/libdruntime/core/sys/posix/unistd.d | 1 - libphobos/libdruntime/core/sys/posix/utime.d | 1 - libphobos/libdruntime/core/sys/windows/aclapi.d | 1 - libphobos/libdruntime/core/sys/windows/aclui.d | 1 - libphobos/libdruntime/core/sys/windows/basetsd.d | 1 - libphobos/libdruntime/core/sys/windows/basetyps.d | 1 - libphobos/libdruntime/core/sys/windows/com.d | 1 - libphobos/libdruntime/core/sys/windows/comcat.d | 1 - libphobos/libdruntime/core/sys/windows/commctrl.d | 1 - libphobos/libdruntime/core/sys/windows/commdlg.d | 1 - libphobos/libdruntime/core/sys/windows/cpl.d | 1 - libphobos/libdruntime/core/sys/windows/cplext.d | 1 - libphobos/libdruntime/core/sys/windows/custcntl.d | 1 - libphobos/libdruntime/core/sys/windows/dbghelp.d | 1 - .../libdruntime/core/sys/windows/dbghelp_types.d | 1 - libphobos/libdruntime/core/sys/windows/dbt.d | 1 - libphobos/libdruntime/core/sys/windows/dde.d | 1 - libphobos/libdruntime/core/sys/windows/ddeml.d | 1 - libphobos/libdruntime/core/sys/windows/dhcpcsdk.d | 1 - libphobos/libdruntime/core/sys/windows/dlgs.d | 1 - libphobos/libdruntime/core/sys/windows/dll.d | 1 - libphobos/libdruntime/core/sys/windows/docobj.d | 1 - libphobos/libdruntime/core/sys/windows/errorrep.d | 1 - libphobos/libdruntime/core/sys/windows/exdisp.d | 1 - libphobos/libdruntime/core/sys/windows/httpext.d | 1 - libphobos/libdruntime/core/sys/windows/imagehlp.d | 1 - libphobos/libdruntime/core/sys/windows/imm.d | 1 - libphobos/libdruntime/core/sys/windows/intshcut.d | 1 - libphobos/libdruntime/core/sys/windows/ipexport.d | 1 - libphobos/libdruntime/core/sys/windows/iphlpapi.d | 1 - libphobos/libdruntime/core/sys/windows/iprtrmib.d | 1 - libphobos/libdruntime/core/sys/windows/iptypes.d | 1 - libphobos/libdruntime/core/sys/windows/lm.d | 1 - libphobos/libdruntime/core/sys/windows/lmaccess.d | 1 - libphobos/libdruntime/core/sys/windows/lmalert.d | 1 - libphobos/libdruntime/core/sys/windows/lmat.d | 1 - libphobos/libdruntime/core/sys/windows/lmaudit.d | 1 - libphobos/libdruntime/core/sys/windows/lmbrowsr.d | 1 - libphobos/libdruntime/core/sys/windows/lmchdev.d | 1 - libphobos/libdruntime/core/sys/windows/lmconfig.d | 1 - libphobos/libdruntime/core/sys/windows/lmcons.d | 1 - libphobos/libdruntime/core/sys/windows/lmerr.d | 1 - libphobos/libdruntime/core/sys/windows/lmerrlog.d | 1 - libphobos/libdruntime/core/sys/windows/lmmsg.d | 1 - libphobos/libdruntime/core/sys/windows/lmremutl.d | 1 - libphobos/libdruntime/core/sys/windows/lmrepl.d | 1 - libphobos/libdruntime/core/sys/windows/lmserver.d | 1 - libphobos/libdruntime/core/sys/windows/lmshare.d | 1 - libphobos/libdruntime/core/sys/windows/lmsname.d | 1 - libphobos/libdruntime/core/sys/windows/lmstats.d | 1 - libphobos/libdruntime/core/sys/windows/lmsvc.d | 1 - libphobos/libdruntime/core/sys/windows/lmuse.d | 1 - libphobos/libdruntime/core/sys/windows/lmwksta.d | 1 - libphobos/libdruntime/core/sys/windows/lzexpand.d | 1 - libphobos/libdruntime/core/sys/windows/mapi.d | 1 - libphobos/libdruntime/core/sys/windows/mciavi.d | 1 - libphobos/libdruntime/core/sys/windows/mcx.d | 1 - libphobos/libdruntime/core/sys/windows/mgmtapi.d | 1 - libphobos/libdruntime/core/sys/windows/mmsystem.d | 1 - libphobos/libdruntime/core/sys/windows/msacm.d | 1 - libphobos/libdruntime/core/sys/windows/mshtml.d | 1 - libphobos/libdruntime/core/sys/windows/mswsock.d | 1 - libphobos/libdruntime/core/sys/windows/nb30.d | 1 - libphobos/libdruntime/core/sys/windows/nddeapi.d | 1 - libphobos/libdruntime/core/sys/windows/nspapi.d | 1 - libphobos/libdruntime/core/sys/windows/ntdef.d | 1 - libphobos/libdruntime/core/sys/windows/ntdll.d | 1 - libphobos/libdruntime/core/sys/windows/ntldap.d | 1 - libphobos/libdruntime/core/sys/windows/ntsecapi.d | 1 - libphobos/libdruntime/core/sys/windows/ntsecpkg.d | 1 - libphobos/libdruntime/core/sys/windows/oaidl.d | 1 - libphobos/libdruntime/core/sys/windows/objbase.d | 1 - libphobos/libdruntime/core/sys/windows/objfwd.d | 1 - libphobos/libdruntime/core/sys/windows/objidl.d | 1 - libphobos/libdruntime/core/sys/windows/objsafe.d | 1 - libphobos/libdruntime/core/sys/windows/ocidl.d | 1 - libphobos/libdruntime/core/sys/windows/odbcinst.d | 1 - libphobos/libdruntime/core/sys/windows/ole.d | 1 - libphobos/libdruntime/core/sys/windows/ole2.d | 1 - libphobos/libdruntime/core/sys/windows/oleacc.d | 1 - libphobos/libdruntime/core/sys/windows/oleauto.d | 1 - libphobos/libdruntime/core/sys/windows/olectl.d | 1 - libphobos/libdruntime/core/sys/windows/oledlg.d | 1 - libphobos/libdruntime/core/sys/windows/oleidl.d | 1 - libphobos/libdruntime/core/sys/windows/pbt.d | 1 - libphobos/libdruntime/core/sys/windows/powrprof.d | 1 - libphobos/libdruntime/core/sys/windows/prsht.d | 1 - libphobos/libdruntime/core/sys/windows/psapi.d | 1 - libphobos/libdruntime/core/sys/windows/rapi.d | 1 - libphobos/libdruntime/core/sys/windows/ras.d | 1 - libphobos/libdruntime/core/sys/windows/rasdlg.d | 1 - libphobos/libdruntime/core/sys/windows/raserror.d | 1 - libphobos/libdruntime/core/sys/windows/rassapi.d | 1 - libphobos/libdruntime/core/sys/windows/reason.d | 1 - libphobos/libdruntime/core/sys/windows/regstr.d | 1 - libphobos/libdruntime/core/sys/windows/richedit.d | 1 - libphobos/libdruntime/core/sys/windows/richole.d | 1 - libphobos/libdruntime/core/sys/windows/rpc.d | 1 - libphobos/libdruntime/core/sys/windows/rpcdce.d | 1 - libphobos/libdruntime/core/sys/windows/rpcdce2.d | 1 - libphobos/libdruntime/core/sys/windows/rpcdcep.d | 1 - libphobos/libdruntime/core/sys/windows/rpcndr.d | 1 - libphobos/libdruntime/core/sys/windows/rpcnsi.d | 1 - libphobos/libdruntime/core/sys/windows/rpcnsip.d | 1 - libphobos/libdruntime/core/sys/windows/rpcnterr.d | 1 - libphobos/libdruntime/core/sys/windows/schannel.d | 1 - libphobos/libdruntime/core/sys/windows/sdkddkver.d | 1 - libphobos/libdruntime/core/sys/windows/secext.d | 1 - libphobos/libdruntime/core/sys/windows/security.d | 1 - libphobos/libdruntime/core/sys/windows/servprov.d | 1 - libphobos/libdruntime/core/sys/windows/setupapi.d | 1 - libphobos/libdruntime/core/sys/windows/shellapi.d | 1 - libphobos/libdruntime/core/sys/windows/shldisp.d | 1 - libphobos/libdruntime/core/sys/windows/shlguid.d | 1 - libphobos/libdruntime/core/sys/windows/shlobj.d | 1 - libphobos/libdruntime/core/sys/windows/shlwapi.d | 1 - libphobos/libdruntime/core/sys/windows/snmp.d | 1 - libphobos/libdruntime/core/sys/windows/sql.d | 1 - libphobos/libdruntime/core/sys/windows/sqlext.d | 1 - libphobos/libdruntime/core/sys/windows/sqltypes.d | 1 - libphobos/libdruntime/core/sys/windows/sqlucode.d | 1 - libphobos/libdruntime/core/sys/windows/sspi.d | 1 - .../libdruntime/core/sys/windows/stacktrace.d | 1 - libphobos/libdruntime/core/sys/windows/stat.d | 1 - .../libdruntime/core/sys/windows/stdc/malloc.d | 1 - libphobos/libdruntime/core/sys/windows/subauth.d | 1 - libphobos/libdruntime/core/sys/windows/threadaux.d | 1 - libphobos/libdruntime/core/sys/windows/tlhelp32.d | 1 - libphobos/libdruntime/core/sys/windows/tmschema.d | 1 - libphobos/libdruntime/core/sys/windows/unknwn.d | 1 - libphobos/libdruntime/core/sys/windows/uuid.d | 1 - libphobos/libdruntime/core/sys/windows/vfw.d | 1 - libphobos/libdruntime/core/sys/windows/w32api.d | 1 - libphobos/libdruntime/core/sys/windows/winbase.d | 1 - libphobos/libdruntime/core/sys/windows/winber.d | 1 - libphobos/libdruntime/core/sys/windows/wincon.d | 1 - libphobos/libdruntime/core/sys/windows/wincrypt.d | 1 - libphobos/libdruntime/core/sys/windows/windef.d | 1 - libphobos/libdruntime/core/sys/windows/windows.d | 1 - libphobos/libdruntime/core/sys/windows/winerror.d | 1 - libphobos/libdruntime/core/sys/windows/wingdi.d | 1 - libphobos/libdruntime/core/sys/windows/winhttp.d | 1 - libphobos/libdruntime/core/sys/windows/wininet.d | 1 - libphobos/libdruntime/core/sys/windows/winioctl.d | 1 - libphobos/libdruntime/core/sys/windows/winldap.d | 1 - libphobos/libdruntime/core/sys/windows/winnetwk.d | 1 - libphobos/libdruntime/core/sys/windows/winnls.d | 1 - libphobos/libdruntime/core/sys/windows/winnt.d | 1 - libphobos/libdruntime/core/sys/windows/winperf.d | 1 - libphobos/libdruntime/core/sys/windows/winreg.d | 1 - libphobos/libdruntime/core/sys/windows/winsock2.d | 1 - libphobos/libdruntime/core/sys/windows/winspool.d | 1 - libphobos/libdruntime/core/sys/windows/winsvc.d | 1 - libphobos/libdruntime/core/sys/windows/winuser.d | 1 - libphobos/libdruntime/core/sys/windows/winver.d | 1 - libphobos/libdruntime/core/sys/windows/wtsapi32.d | 1 - libphobos/libdruntime/core/sys/windows/wtypes.d | 1 - libphobos/libdruntime/rt/dmain2.d | 2 +- libphobos/src/MERGE | 2 +- libphobos/src/std/algorithm/iteration.d | 25 +- libphobos/src/std/algorithm/mutation.d | 1 + libphobos/src/std/array.d | 3 +- libphobos/src/std/ascii.d | 6 +- libphobos/src/std/base64.d | 4 +- libphobos/src/std/bitmanip.d | 98 +-- libphobos/src/std/container/binaryheap.d | 2 + libphobos/src/std/digest/murmurhash.d | 10 +- libphobos/src/std/exception.d | 203 +++--- libphobos/src/std/experimental/allocator/common.d | 20 + libphobos/src/std/file.d | 55 +- libphobos/src/std/format/internal/write.d | 40 +- libphobos/src/std/internal/windows/advapi32.d | 4 +- libphobos/src/std/json.d | 3 + libphobos/src/std/net/curl.d | 2 +- libphobos/src/std/random.d | 24 +- libphobos/src/std/stdio.d | 6 +- libphobos/src/std/string.d | 1 + libphobos/src/std/traits.d | 8 + libphobos/src/std/typecons.d | 790 +++++++++++++++++---- libphobos/src/std/uni/package.d | 11 +- 380 files changed, 3826 insertions(+), 1983 deletions(-) diff --git a/gcc/d/d-attribs.cc b/gcc/d/d-attribs.cc index 04f7f1686a2..90e72e311ce 100644 --- a/gcc/d/d-attribs.cc +++ b/gcc/d/d-attribs.cc @@ -426,7 +426,8 @@ build_attributes (Expressions *eattrs) void apply_user_attributes (Dsymbol *sym, tree node) { - if (!sym->userAttribDecl) + UserAttributeDeclaration *uda = sym->userAttribDecl (); + if (uda == NULL) return; location_t saved_location = input_location; @@ -436,7 +437,7 @@ apply_user_attributes (Dsymbol *sym, tree node) if (TYPE_P (node) && !COMPLETE_TYPE_P (node)) attr_flags |= ATTR_FLAG_TYPE_IN_PLACE; - Expressions *attrs = sym->userAttribDecl->getAttributes (); + Expressions *attrs = uda->getAttributes (); decl_attributes (&node, build_attributes (attrs), attr_flags); input_location = saved_location; diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc index 5997e5dcaf4..51e562a96c1 100644 --- a/gcc/d/d-builtins.cc +++ b/gcc/d/d-builtins.cc @@ -505,6 +505,9 @@ d_init_versions (void) VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo"); } + if (optimize) + VersionCondition::addPredefinedGlobalIdent ("D_Optimized"); + VersionCondition::addPredefinedGlobalIdent ("all"); /* Emit all target-specific version identifiers. */ diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index dcc465f299b..3b61301645f 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -567,10 +567,10 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, global.params.fixAliasThis = value; global.params.previewIn = value; global.params.fix16997 = value; - global.params.noSharedAccess = value; + global.params.noSharedAccess = FeatureState::enabled; global.params.rvalueRefParam = FeatureState::enabled; global.params.inclusiveInContracts = value; - global.params.shortenedMethods = value; + global.params.systemVariables = FeatureState::enabled; global.params.fixImmutableConv = value; break; @@ -619,15 +619,15 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, break; case OPT_fpreview_nosharedaccess: - global.params.noSharedAccess = value; + global.params.noSharedAccess = FeatureState::enabled; break; case OPT_fpreview_rvaluerefparam: global.params.rvalueRefParam = FeatureState::enabled; break; - case OPT_fpreview_shortenedmethods: - global.params.shortenedMethods = value; + case OPT_fpreview_systemvariables: + global.params.systemVariables = FeatureState::enabled; break; case OPT_frelease: diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index a4c46f3306e..2398875bce7 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -4219ba670ce9ff92f3e874f0f048f2c28134c008 +e4f89195913be1dc638707b1abb24c4f3ae7e0bf The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION index 83a14f57e16..50adf9c67bd 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.100.1 +v2.101.0-beta.1 diff --git a/gcc/d/dmd/aggregate.d b/gcc/d/dmd/aggregate.d index edca17fbad1..e9e8bbe4e27 100644 --- a/gcc/d/dmd/aggregate.d +++ b/gcc/d/dmd/aggregate.d @@ -109,7 +109,7 @@ extern (C++) abstract class AggregateDeclaration : ScopeDsymbol CPPMANGLE cppmangle; /// overridden symbol with pragma(mangle, "...") if not null - MangleOverride* mangleOverride; + MangleOverride* pMangleOverride; /** * !=null if is nested diff --git a/gcc/d/dmd/aggregate.h b/gcc/d/dmd/aggregate.h index f0909e3dc02..d4432b513c4 100644 --- a/gcc/d/dmd/aggregate.h +++ b/gcc/d/dmd/aggregate.h @@ -82,7 +82,7 @@ public: CPPMANGLE cppmangle; // overridden symbol with pragma(mangle, "...") - MangleOverride *mangleOverride; + MangleOverride *pMangleOverride; /* !=NULL if is nested * pointing to the dsymbol that directly enclosing it. * 1. The function that enclosing it (nested struct and class) @@ -174,7 +174,7 @@ public: structalign_t alignment; // alignment applied outside of the struct ThreeState ispod; // if struct is POD private: - uint8_t bitFields; + uint16_t bitFields; public: static StructDeclaration *create(const Loc &loc, Identifier *id, bool inObject); StructDeclaration *syntaxCopy(Dsymbol *s) override; diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d index 3472d1ce478..3f27cb990b0 100644 --- a/gcc/d/dmd/attrib.d +++ b/gcc/d/dmd/attrib.d @@ -894,50 +894,9 @@ extern (C++) final class PragmaDeclaration : AttribDeclaration // then it's evaluated on demand in function semantic return createNewScope(sc, sc.stc, sc.linkage, sc.cppmangle, sc.visibility, sc.explicitVisibility, sc.aligndecl, this); } - if (ident == Id.printf || ident == Id.scanf) - { - auto sc2 = sc.push(); - - if (ident == Id.printf) - // Override previous setting, never let both be set - sc2.flags = (sc2.flags & ~SCOPE.scanf) | SCOPE.printf; - else - sc2.flags = (sc2.flags & ~SCOPE.printf) | SCOPE.scanf; - - return sc2; - } return sc; } - PINLINE evalPragmaInline(Scope* sc) - { - if (!args || args.dim == 0) - return PINLINE.default_; - - Expression e = (*args)[0]; - if (!e.type) - { - - sc = sc.startCTFE(); - e = e.expressionSemantic(sc); - e = resolveProperties(sc, e); - sc = sc.endCTFE(); - e = e.ctfeInterpret(); - e = e.toBoolean(sc); - if (e.isErrorExp()) - error("pragma(`inline`, `true` or `false`) expected, not `%s`", (*args)[0].toChars()); - (*args)[0] = e; - } - - const opt = e.toBool(); - if (opt.isEmpty()) - return PINLINE.default_; - else if (opt.get()) - return PINLINE.always; - else - return PINLINE.never; - } - override const(char)* kind() const { return "pragma"; diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h index 1fe33a6ba51..b153229ccaa 100644 --- a/gcc/d/dmd/attrib.h +++ b/gcc/d/dmd/attrib.h @@ -154,7 +154,6 @@ public: PragmaDeclaration *syntaxCopy(Dsymbol *s) override; Scope *newScope(Scope *sc) override; - PINLINE evalPragmaInline(Scope* sc); const char *kind() const override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index ba7d590b553..c999048dc49 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -300,7 +300,7 @@ FuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc) auto tf = new TypeFunction(ParameterList(fparams), sd.handleType(), LINK.d, stc | STC.ref_); auto fop = new FuncDeclaration(declLoc, Loc.initial, Id.assign, stc, tf); fop.storage_class |= STC.inference; - fop.flags |= FUNCFLAG.generated; + fop.isGenerated = true; Expression e; if (stc & STC.disable) { @@ -581,7 +581,7 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc) tf = tf.addSTC(STC.const_).toTypeFunction(); Identifier id = Id.xopEquals; auto fop = new FuncDeclaration(declLoc, Loc.initial, id, 0, tf); - fop.flags |= FUNCFLAG.generated; + fop.isGenerated = true; fop.parent = sd; Expression e1 = new IdentifierExp(loc, Id.This); Expression e2 = new IdentifierExp(loc, Id.p); @@ -705,7 +705,7 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc) tf = tf.addSTC(STC.const_).toTypeFunction(); Identifier id = Id.xopCmp; auto fop = new FuncDeclaration(declLoc, Loc.initial, id, 0, tf); - fop.flags |= FUNCFLAG.generated; + fop.isGenerated = true; fop.parent = sd; Expression e1 = new IdentifierExp(loc, Id.This); Expression e2 = new IdentifierExp(loc, Id.p); @@ -823,7 +823,7 @@ FuncDeclaration buildXtoHash(StructDeclaration sd, Scope* sc) auto tf = new TypeFunction(ParameterList(parameters), Type.thash_t, LINK.d, STC.nothrow_ | STC.trusted); Identifier id = Id.xtoHash; auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.static_, tf); - fop.flags |= FUNCFLAG.generated; + fop.isGenerated = true; /* Do memberwise hashing. * @@ -961,7 +961,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc) { //printf("Building __fieldDtor(), %s\n", e.toChars()); auto dd = new DtorDeclaration(declLoc, Loc.initial, stc, Id.__fieldDtor); - dd.flags |= FUNCFLAG.generated; + dd.isGenerated = true; dd.storage_class |= STC.inference; dd.fbody = new ExpStatement(loc, e); ad.members.push(dd); @@ -1017,7 +1017,7 @@ void buildDtors(AggregateDeclaration ad, Scope* sc) e = Expression.combine(e, ce); } auto dd = new DtorDeclaration(declLoc, Loc.initial, stc, Id.__aggrDtor); - dd.flags |= FUNCFLAG.generated; + dd.isGenerated = true; dd.storage_class |= STC.inference; dd.fbody = new ExpStatement(loc, e); ad.members.push(dd); @@ -1088,7 +1088,7 @@ private DtorDeclaration buildWindowsCppDtor(AggregateDeclaration ad, DtorDeclara stmts.push(new ExpStatement(loc, call)); stmts.push(new ReturnStatement(loc, new CastExp(loc, new ThisExp(loc), Type.tvoidptr))); func.fbody = new CompoundStatement(loc, stmts); - func.flags |= FUNCFLAG.generated; + func.isGenerated = true; auto sc2 = sc.push(); sc2.stc &= ~STC.static_; // not a static destructor @@ -1140,7 +1140,7 @@ private DtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc) auto call = new CallExp(dtor.loc, dtor, null); call.directcall = true; // non-virtual call Class.__dtor(); func.fbody = new ExpStatement(dtor.loc, call); - func.flags |= FUNCFLAG.generated; + func.isGenerated = true; func.storage_class |= STC.inference; auto sc2 = sc.push(); @@ -1416,7 +1416,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) //printf("Building __fieldPostBlit()\n"); checkShared(); auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__fieldPostblit); - dd.flags |= FUNCFLAG.generated; + dd.isGenerated = true; dd.storage_class |= STC.inference | STC.scope_; dd.fbody = (stc & STC.disable) ? null : new CompoundStatement(loc, postblitCalls); sd.postblits.shift(dd); @@ -1454,7 +1454,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) checkShared(); auto dd = new PostBlitDeclaration(declLoc, Loc.initial, stc, Id.__aggrPostblit); - dd.flags |= FUNCFLAG.generated; + dd.isGenerated = true; dd.storage_class |= STC.inference; dd.fbody = new ExpStatement(loc, e); sd.members.push(dd); @@ -1517,7 +1517,7 @@ private CtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const auto ccd = new CtorDeclaration(sd.loc, Loc.initial, STC.ref_, tf, true); ccd.storage_class |= funcStc; ccd.storage_class |= STC.inference; - ccd.flags |= FUNCFLAG.generated; + ccd.isGenerated = true; return ccd; } diff --git a/gcc/d/dmd/common/bitfields.d b/gcc/d/dmd/common/bitfields.d index cccaabd6d67..bba61ad3715 100644 --- a/gcc/d/dmd/common/bitfields.d +++ b/gcc/d/dmd/common/bitfields.d @@ -23,6 +23,7 @@ if (__traits(isUnsigned, T)) string result = "extern (C++) pure nothrow @nogc @safe final {"; enum structName = __traits(identifier, S); + string initialValue = ""; foreach (size_t i, mem; __traits(allMembers, S)) { static assert(is(typeof(__traits(getMember, S, mem)) == bool)); @@ -37,8 +38,10 @@ if (__traits(isUnsigned, T)) v ? (bitFields |= "~mask~") : (bitFields &= ~"~mask~"); return v; }"; + + initialValue = (__traits(getMember, S.init, mem) ? "1" : "0") ~ initialValue; } - return result ~ "}\n private "~T.stringof~" bitFields;\n"; + return result ~ "}\n private "~T.stringof~" bitFields = 0b" ~ initialValue ~ ";\n"; } /// @@ -48,7 +51,7 @@ unittest { bool x; bool y; - bool z; + bool z = 1; } static struct S @@ -66,5 +69,5 @@ unittest s.y = true; assert(s.y); assert(!s.x); - assert(!s.z); + assert(s.z); } diff --git a/gcc/d/dmd/common/file.d b/gcc/d/dmd/common/file.d index 8f34b5319a9..89e702703e6 100644 --- a/gcc/d/dmd/common/file.d +++ b/gcc/d/dmd/common/file.d @@ -144,9 +144,14 @@ struct FileMapping(Datum) import core.stdc.string : strlen; import core.stdc.stdlib : malloc; import core.stdc.string : memcpy; - auto totalNameLength = filename.strlen() + 1; - name = cast(char*) memcpy(malloc(totalNameLength), filename, totalNameLength); - name || assert(0, "FileMapping: Out of memory."); + const totalNameLength = filename.strlen() + 1; + auto namex = cast(char*) malloc(totalNameLength); + if (!namex) + { + fprintf(stderr, "FileMapping: Out of memory."); + exit(1); + } + name = cast(char*) memcpy(namex, filename, totalNameLength); } /** diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index 2c5a4f0e76d..ad1ad6791c5 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -1906,6 +1906,8 @@ final class CParser(AST) : Parser!AST { auto str = asmName.peekString(); p.mangleOverride = str; +// p.adFlags |= AST.VarDeclaration.nounderscore; + p.adFlags |= 4; // cannot get above line to compile on Ubuntu } } s = applySpecifier(s, specifier); @@ -5164,18 +5166,40 @@ final class CParser(AST) : Parser!AST if (n.value == TOK.identifier && n.ident == Id.pop) { scan(&n); - while (n.value == TOK.comma) + size_t len = this.records.length; + if (n.value == TOK.rightParenthesis) // #pragma pack ( pop ) + { + if (len == 0) // nothing to pop + return closingParen(); + + this.records.setDim(len - 1); + this.packs.setDim(len - 1); + if (len == 1) // stack is now empty + packalign.setDefault(); + else + packalign = (*this.packs)[len - 1]; + return closingParen(); + } + while (n.value == TOK.comma) // #pragma pack ( pop , { scan(&n); if (n.value == TOK.identifier) { - for (size_t len = this.records.length; len; --len) + /* pragma pack(pop, identifier + * Pop until identifier is found, pop that one too, and set + * alignment to the new top of the stack. + * If identifier is not found, do nothing. + */ + for ( ; len; --len) { if ((*this.records)[len - 1] == n.ident) { - packalign = (*this.packs)[len - 1]; this.records.setDim(len - 1); this.packs.setDim(len - 1); + if (len > 1) + packalign = (*this.packs)[len - 2]; + else + packalign.setDefault(); // stack empty, use default break; } } @@ -5184,14 +5208,18 @@ final class CParser(AST) : Parser!AST else if (n.value == TOK.int32Literal) { setPackAlign(n); - this.records.push(null); - this.packs.push(packalign); + scan(&n); + } + else + { + error(loc, "identifier or alignment value expected following `#pragma pack(pop,` not `%s`", n.toChars()); scan(&n); } } return closingParen(); } /* # pragma pack ( integer ) + * Sets alignment to integer */ if (n.value == TOK.int32Literal) { @@ -5200,6 +5228,7 @@ final class CParser(AST) : Parser!AST return closingParen(); } /* # pragma pack ( ) + * Sets alignment to default */ if (n.value == TOK.rightParenthesis) { diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d index fed83b8f403..7c130e94862 100644 --- a/gcc/d/dmd/cppmangle.d +++ b/gcc/d/dmd/cppmangle.d @@ -615,7 +615,7 @@ private final class CppMangleVisitor : Visitor if (!ti) { auto ag = s.isAggregateDeclaration(); - const ident = (ag && ag.mangleOverride) ? ag.mangleOverride.id : s.ident; + const ident = (ag && ag.pMangleOverride) ? ag.pMangleOverride.id : s.ident; this.writeNamespace(s.cppnamespace, () { this.writeIdentifier(ident); this.abiTags.writeSymbol(s, this); @@ -654,14 +654,14 @@ private final class CppMangleVisitor : Visitor } auto ag = ti.aliasdecl ? ti.aliasdecl.isAggregateDeclaration() : null; - if (ag && ag.mangleOverride) + if (ag && ag.pMangleOverride) { this.writeNamespace( ti.toAlias().cppnamespace, () { - this.writeIdentifier(ag.mangleOverride.id); - if (ag.mangleOverride.agg && ag.mangleOverride.agg.isInstantiated()) + this.writeIdentifier(ag.pMangleOverride.id); + if (ag.pMangleOverride.agg && ag.pMangleOverride.agg.isInstantiated()) { - auto to = ag.mangleOverride.agg.isInstantiated(); + auto to = ag.pMangleOverride.agg.isInstantiated(); append(to); this.abiTags.writeSymbol(to.tempdecl, this); template_args(to); diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index 8ab3873aa33..ba3afb7716d 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -327,6 +327,45 @@ MATCH implicitConvTo(Expression e, Type t) return MATCH.nomatch; } + // Apply mod bits to each function parameter, + // and see if we can convert the function argument to the modded type + static bool parametersModMatch(Expressions* args, TypeFunction tf, MOD mod) + { + const size_t nparams = tf.parameterList.length; + const size_t j = tf.isDstyleVariadic(); // if TypeInfoArray was prepended + foreach (const i; j .. args.dim) + { + Expression earg = (*args)[i]; + Type targ = earg.type.toBasetype(); + static if (LOG) + { + printf("[%d] earg: %s, targ: %s\n", cast(int)i, earg.toChars(), targ.toChars()); + } + if (i - j < nparams) + { + Parameter fparam = tf.parameterList[i - j]; + if (fparam.isLazy()) + return false; // not sure what to do with this + Type tparam = fparam.type; + if (!tparam) + continue; + if (fparam.isReference()) + { + if (targ.constConv(tparam.castMod(mod)) == MATCH.nomatch) + return false; + continue; + } + } + static if (LOG) + { + printf("[%d] earg: %s, targm: %s\n", cast(int)i, earg.toChars(), targ.addMod(mod).toChars()); + } + if (implicitMod(earg, targ, mod) == MATCH.nomatch) + return false; + } + return true; + } + MATCH visitAdd(AddExp e) { version (none) @@ -894,9 +933,6 @@ MATCH implicitConvTo(Expression e, Type t) /* Apply mod bits to each function parameter, * and see if we can convert the function argument to the modded type */ - - size_t nparams = tf.parameterList.length; - size_t j = tf.isDstyleVariadic(); // if TypeInfoArray was prepended if (auto dve = e.e1.isDotVarExp()) { /* Treat 'this' as just another function argument @@ -905,36 +941,9 @@ MATCH implicitConvTo(Expression e, Type t) if (targ.constConv(targ.castMod(mod)) == MATCH.nomatch) return result; } - foreach (const i; j .. e.arguments.dim) - { - Expression earg = (*e.arguments)[i]; - Type targ = earg.type.toBasetype(); - static if (LOG) - { - printf("[%d] earg: %s, targ: %s\n", cast(int)i, earg.toChars(), targ.toChars()); - } - if (i - j < nparams) - { - Parameter fparam = tf.parameterList[i - j]; - if (fparam.isLazy()) - return result; // not sure what to do with this - Type tparam = fparam.type; - if (!tparam) - continue; - if (fparam.isReference()) - { - if (targ.constConv(tparam.castMod(mod)) == MATCH.nomatch) - return result; - continue; - } - } - static if (LOG) - { - printf("[%d] earg: %s, targm: %s\n", cast(int)i, earg.toChars(), targ.addMod(mod).toChars()); - } - if (implicitMod(earg, targ, mod) == MATCH.nomatch) - return result; - } + + if (!parametersModMatch(e.arguments, tf, mod)) + return result; /* Success */ @@ -1206,47 +1215,16 @@ MATCH implicitConvTo(Expression e, Type t) if (tf.purity == PURE.impure) return MATCH.nomatch; // impure + // Allow a conversion to immutable type, or + // conversions of mutable types between thread-local and shared. if (e.type.immutableOf().implicitConvTo(t) < MATCH.constant && e.type.addMod(MODFlags.shared_).implicitConvTo(t) < MATCH.constant && e.type.implicitConvTo(t.addMod(MODFlags.shared_)) < MATCH.constant) { return MATCH.nomatch; } - // Allow a conversion to immutable type, or - // conversions of mutable types between thread-local and shared. - - Expressions* args = e.arguments; - size_t nparams = tf.parameterList.length; - // if TypeInfoArray was prepended - size_t j = tf.isDstyleVariadic(); - for (size_t i = j; i < e.arguments.dim; ++i) + if (!parametersModMatch(e.arguments, tf, mod)) { - Expression earg = (*args)[i]; - Type targ = earg.type.toBasetype(); - static if (LOG) - { - printf("[%d] earg: %s, targ: %s\n", cast(int)i, earg.toChars(), targ.toChars()); - } - if (i - j < nparams) - { - Parameter fparam = tf.parameterList[i - j]; - if (fparam.isLazy()) - return MATCH.nomatch; // not sure what to do with this - Type tparam = fparam.type; - if (!tparam) - continue; - if (fparam.isReference()) - { - if (targ.constConv(tparam.castMod(mod)) == MATCH.nomatch) - return MATCH.nomatch; - continue; - } - } - static if (LOG) - { - printf("[%d] earg: %s, targm: %s\n", cast(int)i, earg.toChars(), targ.addMod(mod).toChars()); - } - if (implicitMod(earg, targ, mod) == MATCH.nomatch) - return MATCH.nomatch; + return MATCH.nomatch; } } diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d index ff27e37c7dc..07d58f047c3 100644 --- a/gcc/d/dmd/declaration.d +++ b/gcc/d/dmd/declaration.d @@ -227,6 +227,7 @@ extern (C++) abstract class Declaration : Dsymbol ubyte adFlags; // control re-assignment of AliasDeclaration (put here for packing reasons) enum wasRead = 1; // set if AliasDeclaration was read enum ignoreRead = 2; // ignore any reads of AliasDeclaration + enum nounderscore = 4; // don't prepend _ to mangled name Symbol* isym; // import version of csym @@ -481,6 +482,11 @@ extern (C++) abstract class Declaration : Dsymbol return (storage_class & STC.scope_) != 0; } + final bool isReturn() const pure nothrow @nogc @safe + { + return (storage_class & STC.return_) != 0; + } + final bool isSynchronized() const pure nothrow @nogc @safe { return (storage_class & STC.synchronized_) != 0; @@ -542,6 +548,11 @@ extern (C++) abstract class Declaration : Dsymbol return (storage_class & STC.future) != 0; } + final extern(D) bool isSystem() const pure nothrow @nogc @safe + { + return (storage_class & STC.system) != 0; + } + override final Visibility visible() pure nothrow @nogc @safe { return visibility; @@ -780,7 +791,17 @@ extern (C++) final class AliasDeclaration : Declaration * is not overloadable. */ if (type) - return false; + { + /* + If type has been resolved already we could + still be inserting an alias from an import. + + If we are handling an alias then pretend + it was inserting and return true, if not then + false since we didn't even pretend to insert something. + */ + return this._import && this.equals(s); + } /* When s is added in member scope by static if, mixin("code") or others, * aliassym is determined already. See the case in: test/compilable/test61.d @@ -1634,7 +1655,7 @@ extern (C++) class VarDeclaration : Declaration // Add this VarDeclaration to fdv.closureVars[] if not already there if (!sc.intypeof && !(sc.flags & SCOPE.compile) && // https://issues.dlang.org/show_bug.cgi?id=17605 - (fdv.flags & FUNCFLAG.compileTimeOnly || !(fdthis.flags & FUNCFLAG.compileTimeOnly)) + (fdv.isCompileTimeOnly || !fdthis.isCompileTimeOnly) ) { if (!fdv.closureVars.contains(this)) @@ -1754,16 +1775,21 @@ extern (C++) class BitFieldDeclaration : VarDeclaration override final void setFieldOffset(AggregateDeclaration ad, ref FieldState fieldState, bool isunion) { - //printf("BitFieldDeclaration::setFieldOffset(ad: %s, field: %s)\n", ad.toChars(), toChars()); - static void print(const ref FieldState fieldState) + enum log = false; + static if (log) { - printf("FieldState.offset = %d bytes\n", fieldState.offset); - printf(" .fieldOffset = %d bytes\n", fieldState.fieldOffset); - printf(" .bitOffset = %d bits\n", fieldState.bitOffset); - printf(" .fieldSize = %d bytes\n", fieldState.fieldSize); - printf(" .inFlight = %d\n\n", fieldState.inFlight); + printf("BitFieldDeclaration::setFieldOffset(ad: %s, field: %s)\n", ad.toChars(), toChars()); + void print(const ref FieldState fieldState) + { + printf("FieldState.offset = %d bytes\n", fieldState.offset); + printf(" .fieldOffset = %d bytes\n", fieldState.fieldOffset); + printf(" .bitOffset = %d bits\n", fieldState.bitOffset); + printf(" .fieldSize = %d bytes\n", fieldState.fieldSize); + printf(" .inFlight = %d\n", fieldState.inFlight); + printf(" fieldWidth = %d bits\n", fieldWidth); + } + print(fieldState); } - //print(fieldState); Type t = type.toBasetype(); const bool anon = isAnonymous(); @@ -1780,6 +1806,7 @@ extern (C++) class BitFieldDeclaration : VarDeclaration assert(sz != SIZE_INVALID && sz < uint.max); uint memsize = cast(uint)sz; // size of member uint memalignsize = target.fieldalign(t); // size of member for alignment purposes + if (log) printf(" memsize: %u memalignsize: %u\n", memsize, memalignsize); if (fieldWidth == 0 && !anon) error(loc, "named bit fields cannot have 0 width"); @@ -1790,6 +1817,7 @@ extern (C++) class BitFieldDeclaration : VarDeclaration void startNewField() { + if (log) printf("startNewField()\n"); uint alignsize; if (style == TargetC.BitFieldStyle.Gcc_Clang) { @@ -1881,15 +1909,15 @@ extern (C++) class BitFieldDeclaration : VarDeclaration if (!fieldState.inFlight) { + //printf("not in flight\n"); startNewField(); } else if (style == TargetC.BitFieldStyle.Gcc_Clang) { - if (fieldState.bitOffset + fieldWidth > memsize * 8) - { - //printf("start1 fieldState.bitOffset:%u fieldWidth:%u memsize:%u\n", fieldState.bitOffset, fieldWidth, memsize); - startNewField(); - } + // If the bit-field spans more units of alignment than its type, + // start a new field at the next alignment boundary. + if (fieldState.bitOffset == fieldState.fieldSize * 8) + startNewField(); // the bit field is full else { // if alignment boundary is crossed @@ -1909,6 +1937,7 @@ extern (C++) class BitFieldDeclaration : VarDeclaration if (memsize != fieldState.fieldSize || fieldState.bitOffset + fieldWidth > fieldState.fieldSize * 8) { + //printf("new field\n"); startNewField(); } } diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h index 5bce6b0060b..2668b6ec05e 100644 --- a/gcc/d/dmd/declaration.h +++ b/gcc/d/dmd/declaration.h @@ -139,6 +139,7 @@ public: bool isWild() const { return (storage_class & STCwild) != 0; } bool isAuto() const { return (storage_class & STCauto) != 0; } bool isScope() const { return (storage_class & STCscope) != 0; } + bool isReturn() const { return (storage_class & STCreturn) != 0; } bool isSynchronized() const { return (storage_class & STCsynchronized) != 0; } bool isParameter() const { return (storage_class & STCparameter) != 0; } bool isDeprecated() const override final { return (storage_class & STCdeprecated) != 0; } @@ -615,7 +616,54 @@ public: AttributeViolation* safetyViolation; - unsigned flags; // FUNCFLAGxxxxx + // Formerly FUNCFLAGS + uint32_t flags; + bool purityInprocess() const; + bool purityInprocess(bool v); + bool safetyInprocess() const; + bool safetyInprocess(bool v); + bool nothrowInprocess() const; + bool nothrowInprocess(bool v); + bool nogcInprocess() const; + bool nogcInprocess(bool v); + bool returnInprocess() const; + bool returnInprocess(bool v); + bool inlineScanned() const; + bool inlineScanned(bool v); + bool inferScope() const; + bool inferScope(bool v); + bool hasCatches() const; + bool hasCatches(bool v); + bool isCompileTimeOnly() const; + bool isCompileTimeOnly(bool v); + bool printf() const; + bool printf(bool v); + bool scanf() const; + bool scanf(bool v); + bool noreturn() const; + bool noreturn(bool v); + bool isNRVO() const; + bool isNRVO(bool v); + bool isNaked() const; + bool isNaked(bool v); + bool isGenerated() const; + bool isGenerated(bool v); + bool isIntroducing() const; + bool isIntroducing(bool v); + bool hasSemantic3Errors() const; + bool hasSemantic3Errors(bool v); + bool hasNoEH() const; + bool hasNoEH(bool v); + bool inferRetType() const; + bool inferRetType(bool v); + bool hasDualContext() const; + bool hasDualContext(bool v); + bool hasAlwaysInlines() const; + bool hasAlwaysInlines(bool v); + bool isCrtCtor() const; + bool isCrtCtor(bool v); + bool isCrtDtor() const; + bool isCrtDtor(bool v); // Data for a function declaration that is needed for the Objective-C // integration. @@ -655,22 +703,6 @@ public: bool isNogc(); bool isNogcBypassingInference(); - bool isNRVO() const; - void isNRVO(bool v); - bool isNaked() const; - void isNaked(bool v); - bool isGenerated() const; - void isGenerated(bool v); - bool isIntroducing() const; - bool hasSemantic3Errors() const; - bool hasNoEH() const; - bool inferRetType() const; - bool hasDualContext() const; - bool hasAlwaysInlines() const; - bool isCrtCtor() const; - void isCrtCtor(bool v); - bool isCrtDtor() const; - void isCrtDtor(bool v); virtual bool isNested() const; AggregateDeclaration *isThis() override; diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index a95d9dee88d..63b700096e5 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -2872,6 +2872,12 @@ public: else m = v.getConstInitializer(true); } + else if (v.type.isTypeNoreturn()) + { + // Noreturn field with default initializer + (*elems)[fieldsSoFar + i] = null; + continue; + } else m = v.type.defaultInitLiteral(e.loc); if (exceptionOrCant(m)) diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d index 2cb1cc7482e..b2908ce02b0 100644 --- a/gcc/d/dmd/dmodule.d +++ b/gcc/d/dmd/dmodule.d @@ -98,13 +98,13 @@ private const(char)[] getFilename(Identifier[] packages, Identifier ident) nothr { const(char)[] filename = ident.toString(); - if (packages.length == 0) - return filename; - OutBuffer buf; OutBuffer dotmods; auto modAliases = &global.params.modFileAliasStrings; + if (packages.length == 0 && modAliases.length == 0) + return filename; + void checkModFileAlias(const(char)[] p) { /* Check and replace the contents of buf[] with @@ -308,7 +308,7 @@ extern (C++) class Package : ScopeDsymbol packages ~= s.ident; reverse(packages); - if (FileManager.lookForSourceFile(getFilename(packages, ident), global.path ? (*global.path)[] : null)) + if (Module.find(getFilename(packages, ident))) Module.load(Loc.initial, packages, this.ident); else isPkgMod = PKG.package_; @@ -492,6 +492,16 @@ extern (C++) final class Module : Package return new Module(Loc.initial, filename, ident, doDocComment, doHdrGen); } + static const(char)* find(const(char)* filename) + { + return find(filename.toDString).ptr; + } + + extern (D) static const(char)[] find(const(char)[] filename) + { + return FileManager.lookForSourceFile(filename, global.path ? (*global.path)[] : null); + } + extern (C++) static Module load(const ref Loc loc, Identifiers* packages, Identifier ident) { return load(loc, packages ? (*packages)[] : null, ident); @@ -506,7 +516,7 @@ extern (C++) final class Module : Package // foo\bar\baz const(char)[] filename = getFilename(packages, ident); // Look for the source file - if (const result = FileManager.lookForSourceFile(filename, global.path ? (*global.path)[] : null)) + if (const result = find(filename)) filename = result; // leaks auto m = new Module(loc, filename, ident, 0, 0); @@ -703,232 +713,12 @@ extern (C++) final class Module : Package /// ditto extern (D) Module parseModule(AST)() { - enum Endian { little, big} - enum SourceEncoding { utf16, utf32} - - /* - * Convert a buffer from UTF32 to UTF8 - * Params: - * Endian = is the buffer big/little endian - * buf = buffer of UTF32 data - * Returns: - * input buffer reencoded as UTF8 - */ - - char[] UTF32ToUTF8(Endian endian)(const(char)[] buf) - { - static if (endian == Endian.little) - alias readNext = Port.readlongLE; - else - alias readNext = Port.readlongBE; - - if (buf.length & 3) - { - error("odd length of UTF-32 char source %llu", cast(ulong) buf.length); - return null; - } - - const (uint)[] eBuf = cast(const(uint)[])buf; - - OutBuffer dbuf; - dbuf.reserve(eBuf.length); - - foreach (i; 0 .. eBuf.length) - { - const u = readNext(&eBuf[i]); - if (u & ~0x7F) - { - if (u > 0x10FFFF) - { - error("UTF-32 value %08x greater than 0x10FFFF", u); - return null; - } - dbuf.writeUTF8(u); - } - else - dbuf.writeByte(u); - } - dbuf.writeByte(0); //add null terminator - return dbuf.extractSlice(); - } - - /* - * Convert a buffer from UTF16 to UTF8 - * Params: - * Endian = is the buffer big/little endian - * buf = buffer of UTF16 data - * Returns: - * input buffer reencoded as UTF8 - */ - - char[] UTF16ToUTF8(Endian endian)(const(char)[] buf) - { - static if (endian == Endian.little) - alias readNext = Port.readwordLE; - else - alias readNext = Port.readwordBE; - - if (buf.length & 1) - { - error("odd length of UTF-16 char source %llu", cast(ulong) buf.length); - return null; - } - - const (ushort)[] eBuf = cast(const(ushort)[])buf; - - OutBuffer dbuf; - dbuf.reserve(eBuf.length); - - //i will be incremented in the loop for high codepoints - foreach (ref i; 0 .. eBuf.length) - { - uint u = readNext(&eBuf[i]); - if (u & ~0x7F) - { - if (0xD800 <= u && u < 0xDC00) - { - i++; - if (i >= eBuf.length) - { - error("surrogate UTF-16 high value %04x at end of file", u); - return null; - } - const u2 = readNext(&eBuf[i]); - if (u2 < 0xDC00 || 0xE000 <= u2) - { - error("surrogate UTF-16 low value %04x out of range", u2); - return null; - } - u = (u - 0xD7C0) << 10; - u |= (u2 - 0xDC00); - } - else if (u >= 0xDC00 && u <= 0xDFFF) - { - error("unpaired surrogate UTF-16 value %04x", u); - return null; - } - else if (u == 0xFFFE || u == 0xFFFF) - { - error("illegal UTF-16 value %04x", u); - return null; - } - dbuf.writeUTF8(u); - } - else - dbuf.writeByte(u); - } - dbuf.writeByte(0); //add a terminating null byte - return dbuf.extractSlice(); - } - const(char)* srcname = srcfile.toChars(); //printf("Module::parse(srcname = '%s')\n", srcname); isPackageFile = isPackageFileName(srcfile); - const(char)[] buf = cast(const(char)[]) this.src; - - bool needsReencoding = true; - bool hasBOM = true; //assume there's a BOM - Endian endian; - SourceEncoding sourceEncoding; - - if (buf.length >= 2) - { - /* Convert all non-UTF-8 formats to UTF-8. - * BOM : https://www.unicode.org/faq/utf_bom.html - * 00 00 FE FF UTF-32BE, big-endian - * FF FE 00 00 UTF-32LE, little-endian - * FE FF UTF-16BE, big-endian - * FF FE UTF-16LE, little-endian - * EF BB BF UTF-8 - */ - if (buf[0] == 0xFF && buf[1] == 0xFE) - { - endian = Endian.little; - - sourceEncoding = buf.length >= 4 && buf[2] == 0 && buf[3] == 0 - ? SourceEncoding.utf32 - : SourceEncoding.utf16; - } - else if (buf[0] == 0xFE && buf[1] == 0xFF) - { - endian = Endian.big; - sourceEncoding = SourceEncoding.utf16; - } - else if (buf.length >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0xFE && buf[3] == 0xFF) - { - endian = Endian.big; - sourceEncoding = SourceEncoding.utf32; - } - else if (buf.length >= 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF) - { - needsReencoding = false;//utf8 with BOM - } - else - { - /* There is no BOM. Make use of Arcane Jill's insight that - * the first char of D source must be ASCII to - * figure out the encoding. - */ - hasBOM = false; - if (buf.length >= 4 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0) - { - endian = Endian.little; - sourceEncoding = SourceEncoding.utf32; - } - else if (buf.length >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0) - { - endian = Endian.big; - sourceEncoding = SourceEncoding.utf32; - } - else if (buf.length >= 2 && buf[1] == 0) //try to check for UTF-16 - { - endian = Endian.little; - sourceEncoding = SourceEncoding.utf16; - } - else if (buf[0] == 0) - { - endian = Endian.big; - sourceEncoding = SourceEncoding.utf16; - } - else { - // It's UTF-8 - needsReencoding = false; - if (buf[0] >= 0x80) - { - error("source file must start with BOM or ASCII character, not \\x%02X", buf[0]); - return null; - } - } - } - //throw away BOM - if (hasBOM) - { - if (!needsReencoding) buf = buf[3..$];// utf-8 already - else if (sourceEncoding == SourceEncoding.utf32) buf = buf[4..$]; - else buf = buf[2..$]; //utf 16 - } - } - // Assume the buffer is from memory and has not be read from disk. Assume UTF-8. - else if (buf.length >= 1 && (buf[0] == '\0' || buf[0] == 0x1A)) - needsReencoding = false; - //printf("%s, %d, %d, %d\n", srcfile.name.toChars(), needsReencoding, endian == Endian.little, sourceEncoding == SourceEncoding.utf16); - if (needsReencoding) - { - if (sourceEncoding == SourceEncoding.utf16) - { - buf = endian == Endian.little - ? UTF16ToUTF8!(Endian.little)(buf) - : UTF16ToUTF8!(Endian.big)(buf); - } - else - { - buf = endian == Endian.little - ? UTF32ToUTF8!(Endian.little)(buf) - : UTF32ToUTF8!(Endian.big)(buf); - } - // an error happened on UTF conversion - if (buf is null) return null; - } + const(char)[] buf = processSource(src, this); + // an error happened on UTF conversion + if (buf is null) return null; /* If it starts with the string "Ddoc", then it's a documentation * source file. @@ -1533,3 +1323,192 @@ extern (C++) struct ModuleDeclaration return this.toChars().toDString; } } + +/** + * Process the content of a source file + * + * Attempts to find which encoding it is using, if it has BOM, + * and then normalize the source to UTF-8. If no encoding is required, + * a slice of `src` will be returned without extra allocation. + * + * Params: + * src = Content of the source file to process + * mod = Module matching `src`, used for error handling + * + * Returns: + * UTF-8 encoded variant of `src`, stripped of any BOM, + * or `null` if an error happened. + */ +private const(char)[] processSource (const(ubyte)[] src, Module mod) +{ + enum SourceEncoding { utf16, utf32} + enum Endian { little, big} + + /* + * Convert a buffer from UTF32 to UTF8 + * Params: + * Endian = is the buffer big/little endian + * buf = buffer of UTF32 data + * Returns: + * input buffer reencoded as UTF8 + */ + + char[] UTF32ToUTF8(Endian endian)(const(char)[] buf) + { + static if (endian == Endian.little) + alias readNext = Port.readlongLE; + else + alias readNext = Port.readlongBE; + + if (buf.length & 3) + { + mod.error("odd length of UTF-32 char source %llu", cast(ulong) buf.length); + return null; + } + + const (uint)[] eBuf = cast(const(uint)[])buf; + + OutBuffer dbuf; + dbuf.reserve(eBuf.length); + + foreach (i; 0 .. eBuf.length) + { + const u = readNext(&eBuf[i]); + if (u & ~0x7F) + { + if (u > 0x10FFFF) + { + mod.error("UTF-32 value %08x greater than 0x10FFFF", u); + return null; + } + dbuf.writeUTF8(u); + } + else + dbuf.writeByte(u); + } + dbuf.writeByte(0); //add null terminator + return dbuf.extractSlice(); + } + + /* + * Convert a buffer from UTF16 to UTF8 + * Params: + * Endian = is the buffer big/little endian + * buf = buffer of UTF16 data + * Returns: + * input buffer reencoded as UTF8 + */ + + char[] UTF16ToUTF8(Endian endian)(const(char)[] buf) + { + static if (endian == Endian.little) + alias readNext = Port.readwordLE; + else + alias readNext = Port.readwordBE; + + if (buf.length & 1) + { + mod.error("odd length of UTF-16 char source %llu", cast(ulong) buf.length); + return null; + } + + const (ushort)[] eBuf = cast(const(ushort)[])buf; + + OutBuffer dbuf; + dbuf.reserve(eBuf.length); + + //i will be incremented in the loop for high codepoints + foreach (ref i; 0 .. eBuf.length) + { + uint u = readNext(&eBuf[i]); + if (u & ~0x7F) + { + if (0xD800 <= u && u < 0xDC00) + { + i++; + if (i >= eBuf.length) + { + mod.error("surrogate UTF-16 high value %04x at end of file", u); + return null; + } + const u2 = readNext(&eBuf[i]); + if (u2 < 0xDC00 || 0xE000 <= u2) + { + mod.error("surrogate UTF-16 low value %04x out of range", u2); + return null; + } + u = (u - 0xD7C0) << 10; + u |= (u2 - 0xDC00); + } + else if (u >= 0xDC00 && u <= 0xDFFF) + { + mod.error("unpaired surrogate UTF-16 value %04x", u); + return null; + } + else if (u == 0xFFFE || u == 0xFFFF) + { + mod.error("illegal UTF-16 value %04x", u); + return null; + } + dbuf.writeUTF8(u); + } + else + dbuf.writeByte(u); + } + dbuf.writeByte(0); //add a terminating null byte + return dbuf.extractSlice(); + } + + const(char)[] buf = cast(const(char)[]) src; + + // Assume the buffer is from memory and has not be read from disk. Assume UTF-8. + if (buf.length < 2) + return buf; + + /* Convert all non-UTF-8 formats to UTF-8. + * BOM : https://www.unicode.org/faq/utf_bom.html + * 00 00 FE FF UTF-32BE, big-endian + * FF FE 00 00 UTF-32LE, little-endian + * FE FF UTF-16BE, big-endian + * FF FE UTF-16LE, little-endian + * EF BB BF UTF-8 + */ + if (buf[0] == 0xFF && buf[1] == 0xFE) + { + if (buf.length >= 4 && buf[2] == 0 && buf[3] == 0) + return UTF32ToUTF8!(Endian.little)(buf[4 .. $]); + return UTF16ToUTF8!(Endian.little)(buf[2 .. $]); + } + + if (buf[0] == 0xFE && buf[1] == 0xFF) + return UTF16ToUTF8!(Endian.big)(buf[2 .. $]); + + if (buf.length >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0xFE && buf[3] == 0xFF) + return UTF32ToUTF8!(Endian.big)(buf[4 .. $]); + + if (buf.length >= 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF) + return buf[3 .. $]; + + /* There is no BOM. Make use of Arcane Jill's insight that + * the first char of D source must be ASCII to + * figure out the encoding. + */ + if (buf.length >= 4 && buf[1] == 0 && buf[2] == 0 && buf[3] == 0) + return UTF32ToUTF8!(Endian.little)(buf); + if (buf.length >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0) + return UTF32ToUTF8!(Endian.big)(buf); + // try to check for UTF-16 + if (buf.length >= 2 && buf[1] == 0) + return UTF16ToUTF8!(Endian.little)(buf); + if (buf[0] == 0) + return UTF16ToUTF8!(Endian.big)(buf); + + // It's UTF-8 + if (buf[0] >= 0x80) + { + mod.error("source file must start with BOM or ASCII character, not \\x%02X", buf[0]); + return null; + } + + return buf; +} diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d index 9c30978551b..c8167595708 100644 --- a/gcc/d/dmd/dscope.d +++ b/gcc/d/dmd/dscope.d @@ -63,17 +63,13 @@ enum SCOPE free = 0x8000, /// is on free list fullinst = 0x10000, /// fully instantiate templates - - // The following are mutually exclusive - printf = 0x4_0000, /// printf-style function - scanf = 0x8_0000, /// scanf-style function } /// Flags that are carried along with a scope push() private enum PersistentFlags = SCOPE.contract | SCOPE.debug_ | SCOPE.ctfe | SCOPE.compile | SCOPE.constraint | SCOPE.noaccesscheck | SCOPE.ignoresymbolvisibility | - SCOPE.printf | SCOPE.scanf | SCOPE.Cfile; + SCOPE.Cfile; struct Scope { diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d index 4126a8adc68..1c2f2265328 100644 --- a/gcc/d/dmd/dstruct.d +++ b/gcc/d/dmd/dstruct.d @@ -216,6 +216,11 @@ extern (C++) class StructDeclaration : AggregateDeclaration bool hasIdentityEquals; // true if has identity opEquals bool hasNoFields; // has no fields bool hasCopyCtor; // copy constructor + bool hasPointerField; // members with indirections + bool hasVoidInitPointers; // void-initialized unsafe fields + bool hasSystemFields; // @system members + bool hasFieldWithInvariant; // invariants + bool computedTypeProperties;// the above 3 fields are computed // Even if struct is defined as non-root symbol, some built-in operations // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo. // For those, today TypeInfo_Struct is generated in COMDAT. @@ -223,7 +228,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration } import dmd.common.bitfields : generateBitFields; - mixin(generateBitFields!(BitFields, ubyte)); + mixin(generateBitFields!(BitFields, ushort)); extern (D) this(const ref Loc loc, Identifier id, bool inObject) { @@ -391,9 +396,35 @@ extern (C++) class StructDeclaration : AggregateDeclaration } } + argTypes = target.toArgTypes(type); } + /// Compute cached type properties for `TypeStruct` + extern(D) final void determineTypeProperties() + { + if (computedTypeProperties) + return; + foreach (vd; fields) + { + if (vd.storage_class & STC.ref_ || vd.hasPointers()) + hasPointerField = true; + + if (vd._init && vd._init.isVoidInitializer() && vd.type.hasPointers()) + hasVoidInitPointers = true; + + if (vd.storage_class & STC.system || vd.type.hasSystemFields()) + hasSystemFields = true; + + if (!vd._init && vd.type.hasVoidInitPointers()) + hasVoidInitPointers = true; + + if (vd.type.hasInvariant()) + hasFieldWithInvariant = true; + } + computedTypeProperties = true; + } + /*************************************** * Determine if struct is POD (Plain Old Data). * diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d index 7e2d02f06bf..2f10e834d9d 100644 --- a/gcc/d/dmd/dsymbol.d +++ b/gcc/d/dmd/dsymbol.d @@ -236,25 +236,33 @@ struct FieldState bool inFlight; /// bit field is in flight } +// 99.9% of Dsymbols don't have attributes (at least in druntime and Phobos), +// so save memory by grouping them into a separate struct +private struct DsymbolAttributes +{ + /// C++ namespace this symbol belongs to + CPPNamespaceDeclaration cppnamespace; + /// customized deprecation message + DeprecatedDeclaration depdecl_; + /// user defined attributes + UserAttributeDeclaration userAttribDecl; +} + /*********************************************************** */ extern (C++) class Dsymbol : ASTNode { Identifier ident; Dsymbol parent; - /// C++ namespace this symbol belongs to - CPPNamespaceDeclaration cppnamespace; Symbol* csym; // symbol for code generator const Loc loc; // where defined Scope* _scope; // !=null means context to use for semantic() const(char)* prettystring; // cached value of toPrettyChars() + private DsymbolAttributes* atts; /// attached attribute declarations bool errors; // this symbol failed to pass semantic() PASS semanticRun = PASS.initial; ushort localNum; /// perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab - DeprecatedDeclaration depdecl; // customized deprecation message - UserAttributeDeclaration userAttribDecl; // user defined attributes - final extern (D) this() nothrow { //printf("Dsymbol::Dsymbol(%p)\n", this); @@ -285,6 +293,42 @@ extern (C++) class Dsymbol : ASTNode return ident ? ident.toChars() : "__anonymous"; } + // Getters / setters for fields stored in `DsymbolAttributes` + final nothrow pure @safe + { + private ref DsymbolAttributes getAtts() + { + if (!atts) + atts = new DsymbolAttributes(); + return *atts; + } + + inout(DeprecatedDeclaration) depdecl() inout { return atts ? atts.depdecl_ : null; } + inout(CPPNamespaceDeclaration) cppnamespace() inout { return atts ? atts.cppnamespace : null; } + inout(UserAttributeDeclaration) userAttribDecl() inout { return atts ? atts.userAttribDecl : null; } + + DeprecatedDeclaration depdecl(DeprecatedDeclaration dd) + { + if (!dd && !atts) + return null; + return getAtts().depdecl_ = dd; + } + + CPPNamespaceDeclaration cppnamespace(CPPNamespaceDeclaration ns) + { + if (!ns && !atts) + return null; + return getAtts().cppnamespace = ns; + } + + UserAttributeDeclaration userAttribDecl(UserAttributeDeclaration uad) + { + if (!uad && !atts) + return null; + return getAtts().userAttribDecl = uad; + } + } + // helper to print fully qualified (template) arguments const(char)* toPrettyCharsHelper() { diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h index acf0004eb80..3e9b634307f 100644 --- a/gcc/d/dmd/dsymbol.h +++ b/gcc/d/dmd/dsymbol.h @@ -167,25 +167,31 @@ struct FieldState bool inFlight; }; +struct DsymbolAttributes; + class Dsymbol : public ASTNode { public: Identifier *ident; Dsymbol *parent; - /// C++ namespace this symbol belongs to - CPPNamespaceDeclaration *namespace_; Symbol *csym; // symbol for code generator Loc loc; // where defined Scope *_scope; // !=NULL means context to use for semantic() const utf8_t *prettystring; +private: + DsymbolAttributes* atts; +public: bool errors; // this symbol failed to pass semantic() PASS semanticRun; unsigned short localNum; // perturb mangled name to avoid collisions with those in FuncDeclaration.localsymtab - DeprecatedDeclaration *depdecl; // customized deprecation message - UserAttributeDeclaration *userAttribDecl; // user defined attributes - static Dsymbol *create(Identifier *); const char *toChars() const override; + DeprecatedDeclaration* depdecl(); + CPPNamespaceDeclaration* cppnamespace(); + UserAttributeDeclaration* userAttribDecl(); + DeprecatedDeclaration* depdecl(DeprecatedDeclaration* dd); + CPPNamespaceDeclaration* cppnamespace(CPPNamespaceDeclaration* ns); + UserAttributeDeclaration* userAttribDecl(UserAttributeDeclaration* uad); virtual const char *toPrettyCharsHelper(); // helper to print fully qualified (template) arguments Loc getLoc(); const char *locToChars(); diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 701f06aadee..b877828ffe5 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -98,6 +98,29 @@ private uint setMangleOverride(Dsymbol s, const(char)[] sym) return 0; } +/** + * Apply pragma printf/scanf to FuncDeclarations under `s`, + * poking through attribute declarations such as `extern(C)` + * but not through aggregates or function bodies. + * + * Params: + * s = symbol to apply + * printf = `true` for printf, `false` for scanf + */ +private void setPragmaPrintf(Dsymbol s, bool printf) +{ + if (auto fd = s.isFuncDeclaration()) + { + fd.printf = printf; + fd.scanf = !printf; + } + + if (auto ad = s.isAttribDeclaration()) + { + ad.include(null).foreachDsymbol( (s) { setPragmaPrintf(s, printf); } ); + } +} + /************************************* * Does semantic analysis on the public face of declarations. */ @@ -855,17 +878,20 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } // Calculate type size + safety checks - if (1) + if (sc && sc.func) { - if (dsym._init && dsym._init.isVoidInitializer() && - (dsym.type.hasPointers() || dsym.type.hasInvariant())) // also computes type size + if (dsym._init && dsym._init.isVoidInitializer()) { - if (dsym.type.hasPointers()) + + if (dsym.type.hasPointers()) // also computes type size sc.setUnsafe(false, dsym.loc, "`void` initializers for pointers not allowed in safe functions"); - else + else if (dsym.type.hasInvariant()) sc.setUnsafe(false, dsym.loc, "`void` initializers for structs with invariants are not allowed in safe functions"); + else if (dsym.type.hasSystemFields()) + sc.setUnsafePreview(global.params.systemVariables, false, dsym.loc, + "`void` initializers for `@system` variables not allowed in safe functions"); } else if (!dsym._init && !(dsym.storage_class & (STC.static_ | STC.extern_ | STC.gshared | STC.manifest | STC.field | STC.parameter)) && @@ -1036,6 +1062,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (f.tookAddressOf) f.tookAddressOf--; } + else if (auto ale = ex.isArrayLiteralExp()) + { + // or an array literal assigned to a `scope` variable + if (!dsym.type.nextOf().needsDestruction()) + ale.onstack = true; + } } Expression exp = ei.exp; @@ -1200,7 +1232,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor override void visit(BitFieldDeclaration dsym) { - //printf("BitField::semantic('%s') %s\n", toPrettyChars(), id.toChars()); + //printf("BitField::semantic('%s')\n", dsym.toChars()); if (dsym.semanticRun >= PASS.semanticdone) return; @@ -1558,6 +1590,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor foreach (s; (*pd.decl)[]) { + if (pd.ident == Id.printf || pd.ident == Id.scanf) + { + s.setPragmaPrintf(pd.ident == Id.printf); + continue; + } + s.dsymbolSemantic(sc2); if (pd.ident != Id.mangle) continue; @@ -1574,13 +1612,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor agg = tc.sym; else if (auto ts = e.type.isTypeStruct()) agg = ts.sym; - ad.mangleOverride = new MangleOverride; + ad.pMangleOverride = new MangleOverride; void setString(ref Expression e) { if (auto se = verifyMangleString(e)) { const name = (cast(const(char)[])se.peekData()).xarraydup; - ad.mangleOverride.id = Identifier.idPool(name); + ad.pMangleOverride.id = Identifier.idPool(name); e = se; } else @@ -1588,13 +1626,13 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } if (agg) { - ad.mangleOverride.agg = agg; + ad.pMangleOverride.agg = agg; if (pd.args.dim == 2) { setString((*pd.args)[1]); } else - ad.mangleOverride.id = agg.ident; + ad.pMangleOverride.id = agg.ident; } else setString((*pd.args)[0]); @@ -1649,29 +1687,8 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!pd.args) return noDeclarations(); - for (size_t i = 0; i < pd.args.dim; i++) - { - Expression e = (*pd.args)[i]; - sc = sc.startCTFE(); - e = e.expressionSemantic(sc); - e = resolveProperties(sc, e); - sc = sc.endCTFE(); - e = ctfeInterpretForPragmaMsg(e); - if (e.op == EXP.error) - { - errorSupplemental(pd.loc, "while evaluating `pragma(msg, %s)`", (*pd.args)[i].toChars()); - return; - } - StringExp se = e.toStringExp(); - if (se) - { - se = se.toUTF8(sc); - fprintf(stderr, "%.*s", cast(int)se.len, se.peekString().ptr); - } - else - fprintf(stderr, "%s", e.toChars()); - } - fprintf(stderr, "\n"); + if (!pragmaMsgSemantic(pd.loc, sc, pd.args)) + return; return noDeclarations(); } @@ -1707,33 +1724,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } else if (pd.ident == Id.startaddress) { - if (!pd.args || pd.args.dim != 1) - pd.error("function name expected for start address"); - else - { - /* https://issues.dlang.org/show_bug.cgi?id=11980 - * resolveProperties and ctfeInterpret call are not necessary. - */ - Expression e = (*pd.args)[0]; - sc = sc.startCTFE(); - e = e.expressionSemantic(sc); - sc = sc.endCTFE(); - (*pd.args)[0] = e; - Dsymbol sa = getDsymbol(e); - if (!sa || !sa.isFuncDeclaration()) - pd.error("function name expected for start address, not `%s`", e.toChars()); - } + pragmaStartAddressSemantic(pd.loc, sc, pd.args); return noDeclarations(); } else if (pd.ident == Id.Pinline) { - if (pd.args && pd.args.dim > 1) - { - pd.error("one boolean expression expected for `pragma(inline)`, not %llu", cast(ulong) pd.args.dim); - pd.args.setDim(1); - (*pd.args)[0] = ErrorExp.get(); - } - // this pragma now gets evaluated on demand in function semantic return declarations(); @@ -1774,7 +1769,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } else if (auto f = s.isFuncDeclaration()) { - f.flags |= isCtor ? FUNCFLAG.CRTCtor : FUNCFLAG.CRTDtor; + if (isCtor) + f.isCrtCtor = true; + else + f.isCrtDtor = true; + return 1; } else @@ -3048,7 +3047,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor //printf("function storage_class = x%llx, sc.stc = x%llx, %x\n", storage_class, sc.stc, Declaration.isFinal()); if (sc.flags & SCOPE.compile) - funcdecl.flags |= FUNCFLAG.compileTimeOnly; // don't emit code for this function + funcdecl.isCompileTimeOnly = true; // don't emit code for this function funcdecl._linkage = sc.linkage; if (auto fld = funcdecl.isFuncLiteralDeclaration()) @@ -3069,7 +3068,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor // evaluate pragma(inline) if (auto pragmadecl = sc.inlining) - funcdecl.inlining = pragmadecl.evalPragmaInline(sc); + funcdecl.inlining = evalPragmaInline(pragmadecl.loc, sc, pragmadecl.args); funcdecl.visibility = sc.visibility; funcdecl.userAttribDecl = sc.userAttribDecl; @@ -3269,9 +3268,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } // check pragma(crt_constructor) signature - if (funcdecl.flags & (FUNCFLAG.CRTCtor | FUNCFLAG.CRTDtor)) + if (funcdecl.isCrtCtor || funcdecl.isCrtDtor) { - const idStr = (funcdecl.flags & FUNCFLAG.CRTCtor) ? "crt_constructor" : "crt_destructor"; + const idStr = funcdecl.isCrtCtor ? "crt_constructor" : "crt_destructor"; if (f.nextOf().ty != Tvoid) funcdecl.error("must return `void` for `pragma(%s)`", idStr.ptr); if (funcdecl._linkage != LINK.c && f.parameterList.length != 0) @@ -3351,7 +3350,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } } - if (const pors = sc.flags & (SCOPE.printf | SCOPE.scanf)) + if (funcdecl.printf || funcdecl.scanf) { /* printf/scanf-like functions must be of the form: * extern (C/C++) T printf([parameters...], const(char)* format, ...); @@ -3387,11 +3386,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor ) ) { - funcdecl.flags |= (pors == SCOPE.printf) ? FUNCFLAG.printf : FUNCFLAG.scanf; + // the signature is valid for printf/scanf, no error } else { - const p = (pors == SCOPE.printf ? Id.printf : Id.scanf).toChars(); + const p = (funcdecl.printf ? Id.printf : Id.scanf).toChars(); if (f.parameterList.varargs == VarArg.variadic) { funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, ...)`" @@ -3538,7 +3537,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor else { //printf("\tintroducing function %s\n", funcdecl.toChars()); - funcdecl.flags |= FUNCFLAG.introducing; + funcdecl.isIntroducing = true; if (cd.classKind == ClassKind.cpp && target.cpp.reverseOverloads) { /* Overloaded functions with same name are grouped and in reverse order. @@ -4555,13 +4554,16 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (sd.semanticRun == PASS.initial) sd.type = sd.type.addSTC(sc.stc | sd.storage_class); sd.type = sd.type.typeSemantic(sd.loc, sc); - if (auto ts = sd.type.isTypeStruct()) + auto ts = sd.type.isTypeStruct(); + if (ts) + { if (ts.sym != sd) { auto ti = ts.sym.isInstantiated(); if (ti && isError(ti)) ts.sym = sd; } + } // Ungag errors when not speculative Ungag ungag = sd.ungagSpeculative(); @@ -4699,16 +4701,26 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } } - if (sd.type.ty == Tstruct && (cast(TypeStruct)sd.type).sym != sd) + if (ts && ts.sym != sd) { - // https://issues.dlang.org/show_bug.cgi?id=19024 - StructDeclaration sym = (cast(TypeStruct)sd.type).sym; - version (none) + StructDeclaration sym = ts.sym; + if (sd.isCsymbol() && sym.isCsymbol()) + { + /* This is two structs imported from different C files. + * Just ignore sd, the second one. The first one will always + * be found when going through the type. + */ + } + else { - printf("this = %p %s\n", sd, sd.toChars()); - printf("type = %d sym = %p, %s\n", sd.type.ty, sym, sym.toPrettyChars()); + version (none) + { + printf("this = %p %s\n", sd, sd.toChars()); + printf("type = %d sym = %p, %s\n", sd.type.ty, sym, sym.toPrettyChars()); + } + // https://issues.dlang.org/show_bug.cgi?id=19024 + sd.error("already exists at %s. Perhaps in another function with the same name?", sym.loc.toChars()); } - sd.error("already exists at %s. Perhaps in another function with the same name?", sym.loc.toChars()); } if (global.errors != errors) @@ -5291,7 +5303,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor auto ctor = new CtorDeclaration(cldec.loc, Loc.initial, 0, tf); ctor.storage_class |= STC.inference; - ctor.flags |= FUNCFLAG.generated; + ctor.isGenerated = true; ctor.fbody = new CompoundStatement(Loc.initial, new Statements()); cldec.members.push(ctor); @@ -7099,3 +7111,47 @@ private CallExp doAtomicOp (string op, Identifier var, Expression arg) return CallExp.create(loc, dti, args); } + +/*************************************** + * Interpret a `pragma(inline, x)` + * + * Params: + * loc = location for error messages + * sc = scope for evaluation of argument + * args = pragma arguments + * Returns: corresponding `PINLINE` state + */ +PINLINE evalPragmaInline(Loc loc, Scope* sc, Expressions* args) +{ + if (!args || args.dim == 0) + return PINLINE.default_; + + if (args && args.dim > 1) + { + .error(loc, "one boolean expression expected for `pragma(inline)`, not %llu", cast(ulong) args.dim); + args.setDim(1); + (*args)[0] = ErrorExp.get(); + } + + Expression e = (*args)[0]; + if (!e.type) + { + sc = sc.startCTFE(); + e = e.expressionSemantic(sc); + e = resolveProperties(sc, e); + sc = sc.endCTFE(); + e = e.ctfeInterpret(); + e = e.toBoolean(sc); + if (e.isErrorExp()) + .error(loc, "pragma(`inline`, `true` or `false`) expected, not `%s`", (*args)[0].toChars()); + (*args)[0] = e; + } + + const opt = e.toBool(); + if (opt.isEmpty()) + return PINLINE.default_; + else if (opt.get()) + return PINLINE.always; + else + return PINLINE.never; +} diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index 13efc1cba3f..1f99c58decd 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -1173,7 +1173,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol fd = new FuncDeclaration(fd.loc, fd.endloc, fd.ident, fd.storage_class, tf); fd.parent = ti; - fd.flags |= FUNCFLAG.inferRetType; + fd.inferRetType = true; // Shouldn't run semantic on default arguments and return type. foreach (ref param; *tf.parameterList.parameters) @@ -3901,7 +3901,7 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param // https://issues.dlang.org/show_bug.cgi?id=2579 // Apply function parameter storage classes to parameter types fparam.type = fparam.type.addStorageClass(fparam.storageClass); - fparam.storageClass &= ~(STC.TYPECTOR | STC.in_); + fparam.storageClass &= ~STC.TYPECTOR; // https://issues.dlang.org/show_bug.cgi?id=15243 // Resolve parameter type if it's not related with template parameters diff --git a/gcc/d/dmd/entity.d b/gcc/d/dmd/entity.d index c29d4999f26..2b499c14fcc 100644 --- a/gcc/d/dmd/entity.d +++ b/gcc/d/dmd/entity.d @@ -25,7 +25,7 @@ nothrow: * code point corresponding to the named entity * ~0 for not recognized as a named entity */ -public uint HtmlNamedEntity(scope const char[] name) pure @nogc @safe +public uint[2] HtmlNamedEntity(scope const char[] name) pure @nogc @safe { const firstC = tolower(name[0]); if (firstC >= 'a' && firstC <= 'z') @@ -34,10 +34,10 @@ public uint HtmlNamedEntity(scope const char[] name) pure @nogc @safe foreach (entity; namesTable[firstC - 'a']) { if (entity.name == name) - return entity.value; + return [entity.value, entity.value2]; } } - return ~0; + return [0, 0]; } private: @@ -52,6 +52,7 @@ struct NameId { string name; uint value; + uint value2; } // @todo@ order namesTable and names? by frequency @@ -72,7 +73,7 @@ immutable NameId[] namesA = {"abreve", 0x00103}, // LATIN SMALL LETTER A WITH BREVE {"ac", 0x0223E}, // INVERTED LAZY S {"acd", 0x0223F}, // SINE WAVE -// {"acE", 0x0223E;0x00333}, // INVERTED LAZY S with double underline + {"acE", 0x0223E, 0x00333}, // INVERTED LAZY S with double underline {"Acirc", 0x000C2}, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX {"acirc", 0x000E2}, // LATIN SMALL LETTER A WITH CIRCUMFLEX {"acute", 0x000B4}, // ACUTE ACCENT @@ -157,42 +158,30 @@ immutable NameId[] namesB = {"backsim", 0x0223D}, // REVERSED TILDE {"backsimeq", 0x022CD}, // REVERSED TILDE EQUALS {"Backslash", 0x02216}, // SET MINUS -// "b.alpha", 0x1D6C2}, // MATHEMATICAL BOLD SMALL ALPHA {"Barv", 0x02AE7}, // SHORT DOWN TACK WITH OVERBAR {"barvee", 0x022BD}, // NOR {"barwed", 0x02305}, // PROJECTIVE {"Barwed", 0x02306}, // PERSPECTIVE {"barwedge", 0x02305}, // PROJECTIVE -// "b.beta", 0x1D6C3}, // MATHEMATICAL BOLD SMALL BETA {"bbrk", 0x023B5}, // BOTTOM SQUARE BRACKET {"bbrktbrk", 0x023B6}, // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET -// "b.chi", 0x1D6D8}, // MATHEMATICAL BOLD SMALL CHI {"bcong", 0x0224C}, // ALL EQUAL TO {"Bcy", 0x00411}, // CYRILLIC CAPITAL LETTER BE {"bcy", 0x00431}, // CYRILLIC SMALL LETTER BE -// "b.Delta", 0x1D6AB}, // MATHEMATICAL BOLD CAPITAL DELTA -// "b.delta", 0x1D6C5}, // MATHEMATICAL BOLD SMALL DELTA {"bdquo", 0x0201E}, // DOUBLE LOW-9 QUOTATION MARK {"becaus", 0x02235}, // BECAUSE {"because", 0x02235}, // BECAUSE {"Because", 0x02235}, // BECAUSE {"bemptyv", 0x029B0}, // REVERSED EMPTY SET {"bepsi", 0x003F6}, // GREEK REVERSED LUNATE EPSILON SYMBOL -// "b.epsi", 0x1D6C6}, // MATHEMATICAL BOLD SMALL EPSILON -// "b.epsiv", 0x1D6DC}, // MATHEMATICAL BOLD EPSILON SYMBOL {"bernou", 0x0212C}, // SCRIPT CAPITAL B {"Bernoullis", 0x0212C}, // SCRIPT CAPITAL B {"Beta", 0x00392}, // GREEK CAPITAL LETTER BETA {"beta", 0x003B2}, // GREEK SMALL LETTER BETA -// "b.eta", 0x1D6C8}, // MATHEMATICAL BOLD SMALL ETA {"beth", 0x02136}, // BET SYMBOL {"between", 0x0226C}, // BETWEEN {"Bfr", 0x1D505}, // MATHEMATICAL FRAKTUR CAPITAL B {"bfr", 0x1D51F}, // MATHEMATICAL FRAKTUR SMALL B -// "b.Gamma", 0x1D6AA}, // MATHEMATICAL BOLD CAPITAL GAMMA -// "b.gamma", 0x1D6C4}, // MATHEMATICAL BOLD SMALL GAMMA -// "b.Gammad", 0x1D7CA}, // MATHEMATICAL BOLD CAPITAL DIGAMMA -// "b.gammad", 0x1D7CB}, // MATHEMATICAL BOLD SMALL DIGAMMA {"Bgr", 0x00392}, // GREEK CAPITAL LETTER BETA {"bgr", 0x003B2}, // GREEK SMALL LETTER BETA {"bigcap", 0x022C2}, // N-ARY INTERSECTION @@ -208,9 +197,6 @@ immutable NameId[] namesB = {"biguplus", 0x02A04}, // N-ARY UNION OPERATOR WITH PLUS {"bigvee", 0x022C1}, // N-ARY LOGICAL OR {"bigwedge", 0x022C0}, // N-ARY LOGICAL AND -// "b.iota", 0x1D6CA}, // MATHEMATICAL BOLD SMALL IOTA -// "b.kappa", 0x1D6CB}, // MATHEMATICAL BOLD SMALL KAPPA -// "b.kappav", 0x1D6DE}, // MATHEMATICAL BOLD KAPPA SYMBOL {"bkarow", 0x0290D}, // RIGHTWARDS DOUBLE DASH ARROW {"blacklozenge", 0x029EB}, // BLACK LOZENGE {"blacksquare", 0x025AA}, // BLACK SMALL SQUARE @@ -218,21 +204,15 @@ immutable NameId[] namesB = {"blacktriangledown", 0x025BE}, // BLACK DOWN-POINTING SMALL TRIANGLE {"blacktriangleleft", 0x025C2}, // BLACK LEFT-POINTING SMALL TRIANGLE {"blacktriangleright", 0x025B8}, // BLACK RIGHT-POINTING SMALL TRIANGLE -// "b.Lambda", 0x1D6B2}, // MATHEMATICAL BOLD CAPITAL LAMDA -// "b.lambda", 0x1D6CC}, // MATHEMATICAL BOLD SMALL LAMDA {"blank", 0x02423}, // OPEN BOX {"blk12", 0x02592}, // MEDIUM SHADE {"blk14", 0x02591}, // LIGHT SHADE {"blk34", 0x02593}, // DARK SHADE {"block", 0x02588}, // FULL BLOCK -// "b.mu", 0x1D6CD}, // MATHEMATICAL BOLD SMALL MU -// "bne", 0x0003D;0x020E5}, // EQUALS SIGN with reverse slash -// "bnequiv", 0x02261;0x020E5}, // IDENTICAL TO with reverse slash + {"bne", 0x0003D, 0x020E5}, // EQUALS SIGN with reverse slash + {"bnequiv", 0x02261, 0x020E5}, // IDENTICAL TO with reverse slash {"bnot", 0x02310}, // REVERSED NOT SIGN {"bNot", 0x02AED}, // REVERSED DOUBLE STROKE NOT SIGN -// "b.nu", 0x1D6CE}, // MATHEMATICAL BOLD SMALL NU -// "b.Omega", 0x1D6C0}, // MATHEMATICAL BOLD CAPITAL OMEGA -// "b.omega", 0x1D6DA}, // MATHEMATICAL BOLD SMALL OMEGA {"Bopf", 0x1D539}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL B {"bopf", 0x1D553}, // MATHEMATICAL DOUBLE-STRUCK SMALL B {"bot", 0x022A5}, // UP TACK @@ -282,35 +262,18 @@ immutable NameId[] namesB = {"boxvR", 0x0255E}, // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE {"boxVr", 0x0255F}, // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE {"boxVR", 0x02560}, // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT -// "b.Phi", 0x1D6BD}, // MATHEMATICAL BOLD CAPITAL PHI -// "b.phi", 0x1D6D7}, // MATHEMATICAL BOLD SMALL PHI -// "b.phiv", 0x1D6DF}, // MATHEMATICAL BOLD PHI SYMBOL -// "b.Pi", 0x1D6B7}, // MATHEMATICAL BOLD CAPITAL PI -// "b.pi", 0x1D6D1}, // MATHEMATICAL BOLD SMALL PI -// "b.piv", 0x1D6E1}, // MATHEMATICAL BOLD PI SYMBOL {"bprime", 0x02035}, // REVERSED PRIME -// "b.Psi", 0x1D6BF}, // MATHEMATICAL BOLD CAPITAL PSI -// "b.psi", 0x1D6D9}, // MATHEMATICAL BOLD SMALL PSI {"breve", 0x002D8}, // BREVE {"Breve", 0x002D8}, // BREVE -// "b.rho", 0x1D6D2}, // MATHEMATICAL BOLD SMALL RHO -// "b.rhov", 0x1D6E0}, // MATHEMATICAL BOLD RHO SYMBOL {"brvbar", 0x000A6}, // BROKEN BAR {"Bscr", 0x0212C}, // SCRIPT CAPITAL B {"bscr", 0x1D4B7}, // MATHEMATICAL SCRIPT SMALL B {"bsemi", 0x0204F}, // REVERSED SEMICOLON -// "b.Sigma", 0x1D6BA}, // MATHEMATICAL BOLD CAPITAL SIGMA -// "b.sigma", 0x1D6D4}, // MATHEMATICAL BOLD SMALL SIGMA -// "b.sigmav", 0x1D6D3}, // MATHEMATICAL BOLD SMALL FINAL SIGMA {"bsim", 0x0223D}, // REVERSED TILDE {"bsime", 0x022CD}, // REVERSED TILDE EQUALS {"bsol", 0x0005C}, // REVERSE SOLIDUS {"bsolb", 0x029C5}, // SQUARED FALLING DIAGONAL SLASH {"bsolhsub", 0x027C8}, // REVERSE SOLIDUS PRECEDING SUBSET -// "b.tau", 0x1D6D5}, // MATHEMATICAL BOLD SMALL TAU -// "b.Theta", 0x1D6AF}, // MATHEMATICAL BOLD CAPITAL THETA -// "b.thetas", 0x1D6C9}, // MATHEMATICAL BOLD SMALL THETA -// "b.thetav", 0x1D6DD}, // MATHEMATICAL BOLD THETA SYMBOL {"bull", 0x02022}, // BULLET {"bullet", 0x02022}, // BULLET {"bump", 0x0224E}, // GEOMETRICALLY EQUIVALENT TO @@ -318,11 +281,6 @@ immutable NameId[] namesB = {"bumpE", 0x02AAE}, // EQUALS SIGN WITH BUMPY ABOVE {"Bumpeq", 0x0224E}, // GEOMETRICALLY EQUIVALENT TO {"bumpeq", 0x0224F}, // DIFFERENCE BETWEEN -// "b.Upsi", 0x1D6BC}, // MATHEMATICAL BOLD CAPITAL UPSILON -// "b.upsi", 0x1D6D6}, // MATHEMATICAL BOLD SMALL UPSILON -// "b.Xi", 0x1D6B5}, // MATHEMATICAL BOLD CAPITAL XI -// "b.xi", 0x1D6CF}, // MATHEMATICAL BOLD SMALL XI -// "b.zeta", 0x1D6C7}, // MATHEMATICAL BOLD SMALL ZETA ]; immutable NameId[] namesC = @@ -337,7 +295,7 @@ immutable NameId[] namesC = {"capcup", 0x02A47}, // INTERSECTION ABOVE UNION {"capdot", 0x02A40}, // INTERSECTION WITH DOT {"CapitalDifferentialD", 0x02145}, // DOUBLE-STRUCK ITALIC CAPITAL D -// "caps", 0x02229;0x0FE00}, // INTERSECTION with serifs + {"caps", 0x02229, 0x0FE00}, // INTERSECTION with serifs {"caret", 0x02041}, // CARET INSERTION POINT {"caron", 0x002C7}, // CARON {"Cayleys", 0x0212D}, // BLACK-LETTER CAPITAL C @@ -440,7 +398,7 @@ immutable NameId[] namesC = {"cupcup", 0x02A4A}, // UNION BESIDE AND JOINED WITH UNION {"cupdot", 0x0228D}, // MULTISET MULTIPLICATION {"cupor", 0x02A45}, // UNION WITH LOGICAL OR -// "cups", 0x0222A;0x0FE00}, // UNION with serifs + {"cups", 0x0222A, 0x0FE00}, // UNION with serifs {"curarr", 0x021B7}, // CLOCKWISE TOP SEMICIRCLE ARROW {"curarrm", 0x0293C}, // TOP ARC CLOCKWISE ARROW WITH MINUS {"curlyeqprec", 0x022DE}, // EQUAL TO OR PRECEDES @@ -694,7 +652,7 @@ immutable NameId[] namesF = {"filig", 0x0FB01}, // LATIN SMALL LIGATURE FI {"FilledSmallSquare", 0x025FC}, // BLACK MEDIUM SQUARE {"FilledVerySmallSquare", 0x025AA}, // BLACK SMALL SQUARE -// "fjlig", 0x00066;0x0006A}, // fj ligature + {"fjlig", 0x00066, 0x0006A}, // fj ligature {"flat", 0x0266D}, // MUSIC FLAT SIGN {"fllig", 0x0FB02}, // LATIN SMALL LIGATURE FL {"fltns", 0x025B1}, // WHITE PARALLELOGRAM @@ -757,7 +715,7 @@ immutable NameId[] namesG = {"gesdot", 0x02A80}, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE {"gesdoto", 0x02A82}, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE {"gesdotol", 0x02A84}, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT -// "gesl", 0x022DB;0x0FE00}, // GREATER-THAN slanted EQUAL TO OR LESS-THAN + {"gesl", 0x022DB, 0x0FE00}, // GREATER-THAN slanted EQUAL TO OR LESS-THAN {"gesles", 0x02A94}, // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL {"Gfr", 0x1D50A}, // MATHEMATICAL FRAKTUR CAPITAL G {"gfr", 0x1D524}, // MATHEMATICAL FRAKTUR SMALL G @@ -810,8 +768,8 @@ immutable NameId[] namesG = {"gtreqqless", 0x02A8C}, // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN {"gtrless", 0x02277}, // GREATER-THAN OR LESS-THAN {"gtrsim", 0x02273}, // GREATER-THAN OR EQUIVALENT TO -// "gvertneqq", 0x02269;0x0FE00}, // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke -// "gvnE", 0x02269;0x0FE00}, // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke + {"gvertneqq", 0x02269, 0x0FE00}, // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke + {"gvnE", 0x02269, 0x0FE00}, // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke ]; immutable NameId[] namesH = @@ -1020,7 +978,7 @@ immutable NameId[] namesL = {"latail", 0x02919}, // LEFTWARDS ARROW-TAIL {"lAtail", 0x0291B}, // LEFTWARDS DOUBLE ARROW-TAIL {"late", 0x02AAD}, // LARGER THAN OR EQUAL TO -// "lates", 0x02AAD;0x0FE00}, // LARGER THAN OR slanted EQUAL + {"lates", 0x02AAD, 0x0FE00}, // LARGER THAN OR slanted EQUAL {"lbarr", 0x0290C}, // LEFTWARDS DOUBLE DASH ARROW {"lBarr", 0x0290E}, // LEFTWARDS TRIPLE DASH ARROW {"lbbrk", 0x02772}, // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT @@ -1091,7 +1049,7 @@ immutable NameId[] namesL = {"lesdot", 0x02A7F}, // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE {"lesdoto", 0x02A81}, // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE {"lesdotor", 0x02A83}, // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT -// "lesg", 0x022DA;0x0FE00}, // LESS-THAN slanted EQUAL TO OR GREATER-THAN + {"lesg", 0x022DA, 0x0FE00}, // LESS-THAN slanted EQUAL TO OR GREATER-THAN {"lesges", 0x02A93}, // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL {"lessapprox", 0x02A85}, // LESS-THAN OR APPROXIMATE {"lessdot", 0x022D6}, // LESS-THAN WITH DOT @@ -1202,8 +1160,8 @@ immutable NameId[] namesL = {"ltrPar", 0x02996}, // DOUBLE RIGHT ARC LESS-THAN BRACKET {"lurdshar", 0x0294A}, // LEFT BARB UP RIGHT BARB DOWN HARPOON {"luruhar", 0x02966}, // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP -// "lvertneqq", 0x02268;0x0FE00}, // LESS-THAN BUT NOT EQUAL TO - with vertical stroke -// "lvnE", 0x02268;0x0FE00}, // LESS-THAN BUT NOT EQUAL TO - with vertical stroke + {"lvertneqq", 0x02268, 0x0FE00}, // LESS-THAN BUT NOT EQUAL TO - with vertical stroke + {"lvnE", 0x02268, 0x0FE00}, // LESS-THAN BUT NOT EQUAL TO - with vertical stroke ]; immutable NameId[] namesM = @@ -1263,25 +1221,25 @@ immutable NameId[] namesN = {"nabla", 0x02207}, // NABLA {"Nacute", 0x00143}, // LATIN CAPITAL LETTER N WITH ACUTE {"nacute", 0x00144}, // LATIN SMALL LETTER N WITH ACUTE -// "nang", 0x02220;0x020D2}, // ANGLE with vertical line + {"nang", 0x02220, 0x020D2}, // ANGLE with vertical line {"nap", 0x02249}, // NOT ALMOST EQUAL TO -// "napE", 0x02A70;0x00338}, // APPROXIMATELY EQUAL OR EQUAL TO with slash -// "napid", 0x0224B;0x00338}, // TRIPLE TILDE with slash + {"napE", 0x02A70, 0x00338}, // APPROXIMATELY EQUAL OR EQUAL TO with slash + {"napid", 0x0224B, 0x00338}, // TRIPLE TILDE with slash {"napos", 0x00149}, // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE {"napprox", 0x02249}, // NOT ALMOST EQUAL TO {"natur", 0x0266E}, // MUSIC NATURAL SIGN {"natural", 0x0266E}, // MUSIC NATURAL SIGN {"naturals", 0x02115}, // DOUBLE-STRUCK CAPITAL N {"nbsp", 0x000A0}, // NO-BREAK SPACE -// "nbump", 0x0224E;0x00338}, // GEOMETRICALLY EQUIVALENT TO with slash -// "nbumpe", 0x0224F;0x00338}, // DIFFERENCE BETWEEN with slash + {"nbump", 0x0224E, 0x00338}, // GEOMETRICALLY EQUIVALENT TO with slash + {"nbumpe", 0x0224F, 0x00338}, // DIFFERENCE BETWEEN with slash {"ncap", 0x02A43}, // INTERSECTION WITH OVERBAR {"Ncaron", 0x00147}, // LATIN CAPITAL LETTER N WITH CARON {"ncaron", 0x00148}, // LATIN SMALL LETTER N WITH CARON {"Ncedil", 0x00145}, // LATIN CAPITAL LETTER N WITH CEDILLA {"ncedil", 0x00146}, // LATIN SMALL LETTER N WITH CEDILLA {"ncong", 0x02247}, // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO -// "ncongdot", 0x02A6D;0x00338}, // CONGRUENT WITH DOT ABOVE with slash + {"ncongdot", 0x02A6D, 0x00338}, // CONGRUENT WITH DOT ABOVE with slash {"ncup", 0x02A42}, // UNION WITH OVERBAR {"Ncy", 0x0041D}, // CYRILLIC CAPITAL LETTER EN {"ncy", 0x0043D}, // CYRILLIC SMALL LETTER EN @@ -1291,14 +1249,14 @@ immutable NameId[] namesN = {"nearr", 0x02197}, // NORTH EAST ARROW {"neArr", 0x021D7}, // NORTH EAST DOUBLE ARROW {"nearrow", 0x02197}, // NORTH EAST ARROW -// "nedot", 0x02250;0x00338}, // APPROACHES THE LIMIT with slash + {"nedot", 0x02250, 0x00338}, // APPROACHES THE LIMIT with slash {"NegativeMediumSpace", 0x0200B}, // ZERO WIDTH SPACE {"NegativeThickSpace", 0x0200B}, // ZERO WIDTH SPACE {"NegativeThinSpace", 0x0200B}, // ZERO WIDTH SPACE {"NegativeVeryThinSpace", 0x0200B}, // ZERO WIDTH SPACE {"nequiv", 0x02262}, // NOT IDENTICAL TO {"nesear", 0x02928}, // NORTH EAST ARROW AND SOUTH EAST ARROW -// "nesim", 0x02242;0x00338}, // MINUS TILDE with slash + {"nesim", 0x02242, 0x00338}, // MINUS TILDE with slash {"NestedGreaterGreater", 0x0226B}, // MUCH GREATER-THAN {"NestedLessLess", 0x0226A}, // MUCH LESS-THAN {"NewLine", 0x0000A}, // LINE FEED (LF) @@ -1306,20 +1264,20 @@ immutable NameId[] namesN = {"nexists", 0x02204}, // THERE DOES NOT EXIST {"Nfr", 0x1D511}, // MATHEMATICAL FRAKTUR CAPITAL N {"nfr", 0x1D52B}, // MATHEMATICAL FRAKTUR SMALL N -// "ngE", 0x02267;0x00338}, // GREATER-THAN OVER EQUAL TO with slash + {"ngE", 0x02267, 0x00338}, // GREATER-THAN OVER EQUAL TO with slash {"nge", 0x02271}, // NEITHER GREATER-THAN NOR EQUAL TO {"ngeq", 0x02271}, // NEITHER GREATER-THAN NOR EQUAL TO -// "ngeqq", 0x02267;0x00338}, // GREATER-THAN OVER EQUAL TO with slash -// "ngeqslant", 0x02A7E;0x00338}, // GREATER-THAN OR SLANTED EQUAL TO with slash -// "nges", 0x02A7E;0x00338}, // GREATER-THAN OR SLANTED EQUAL TO with slash -// "nGg", 0x022D9;0x00338}, // VERY MUCH GREATER-THAN with slash + {"ngeqq", 0x02267, 0x00338}, // GREATER-THAN OVER EQUAL TO with slash + {"ngeqslant", 0x02A7E, 0x00338}, // GREATER-THAN OR SLANTED EQUAL TO with slash + {"nges", 0x02A7E, 0x00338}, // GREATER-THAN OR SLANTED EQUAL TO with slash + {"nGg", 0x022D9, 0x00338}, // VERY MUCH GREATER-THAN with slash {"Ngr", 0x0039D}, // GREEK CAPITAL LETTER NU {"ngr", 0x003BD}, // GREEK SMALL LETTER NU {"ngsim", 0x02275}, // NEITHER GREATER-THAN NOR EQUIVALENT TO -// "nGt", 0x0226B;0x020D2}, // MUCH GREATER THAN with vertical line + {"nGt", 0x0226B, 0x020D2}, // MUCH GREATER THAN with vertical line {"ngt", 0x0226F}, // NOT GREATER-THAN {"ngtr", 0x0226F}, // NOT GREATER-THAN -// "nGtv", 0x0226B;0x00338}, // MUCH GREATER THAN with slash + {"nGtv", 0x0226B, 0x00338}, // MUCH GREATER THAN with slash {"nharr", 0x021AE}, // LEFT RIGHT ARROW WITH STROKE {"nhArr", 0x021CE}, // LEFT RIGHT DOUBLE ARROW WITH STROKE {"nhpar", 0x02AF2}, // PARALLEL WITH HORIZONTAL STROKE @@ -1332,24 +1290,24 @@ immutable NameId[] namesN = {"nlarr", 0x0219A}, // LEFTWARDS ARROW WITH STROKE {"nlArr", 0x021CD}, // LEFTWARDS DOUBLE ARROW WITH STROKE {"nldr", 0x02025}, // TWO DOT LEADER -// "nlE", 0x02266;0x00338}, // LESS-THAN OVER EQUAL TO with slash + {"nlE", 0x02266, 0x00338}, // LESS-THAN OVER EQUAL TO with slash {"nle", 0x02270}, // NEITHER LESS-THAN NOR EQUAL TO {"nleftarrow", 0x0219A}, // LEFTWARDS ARROW WITH STROKE {"nLeftarrow", 0x021CD}, // LEFTWARDS DOUBLE ARROW WITH STROKE {"nleftrightarrow", 0x021AE}, // LEFT RIGHT ARROW WITH STROKE {"nLeftrightarrow", 0x021CE}, // LEFT RIGHT DOUBLE ARROW WITH STROKE {"nleq", 0x02270}, // NEITHER LESS-THAN NOR EQUAL TO -// "nleqq", 0x02266;0x00338}, // LESS-THAN OVER EQUAL TO with slash -// "nleqslant", 0x02A7D;0x00338}, // LESS-THAN OR SLANTED EQUAL TO with slash -// "nles", 0x02A7D;0x00338}, // LESS-THAN OR SLANTED EQUAL TO with slash + {"nleqq", 0x02266, 0x00338}, // LESS-THAN OVER EQUAL TO with slash + {"nleqslant", 0x02A7D, 0x00338}, // LESS-THAN OR SLANTED EQUAL TO with slash + {"nles", 0x02A7D, 0x00338}, // LESS-THAN OR SLANTED EQUAL TO with slash {"nless", 0x0226E}, // NOT LESS-THAN -// "nLl", 0x022D8;0x00338}, // VERY MUCH LESS-THAN with slash + {"nLl", 0x022D8, 0x00338}, // VERY MUCH LESS-THAN with slash {"nlsim", 0x02274}, // NEITHER LESS-THAN NOR EQUIVALENT TO -// "nLt", 0x0226A;0x020D2}, // MUCH LESS THAN with vertical line + {"nLt", 0x0226A, 0x020D2}, // MUCH LESS THAN with vertical line {"nlt", 0x0226E}, // NOT LESS-THAN {"nltri", 0x022EA}, // NOT NORMAL SUBGROUP OF {"nltrie", 0x022EC}, // NOT NORMAL SUBGROUP OF OR EQUAL TO -// "nLtv", 0x0226A;0x00338}, // MUCH LESS THAN with slash + {"nLtv", 0x0226A, 0x00338}, // MUCH LESS THAN with slash {"nmid", 0x02224}, // DOES NOT DIVIDE {"NoBreak", 0x02060}, // WORD JOINER {"NonBreakingSpace", 0x000A0}, // NO-BREAK SPACE @@ -1362,56 +1320,56 @@ immutable NameId[] namesN = {"NotDoubleVerticalBar", 0x02226}, // NOT PARALLEL TO {"NotElement", 0x02209}, // NOT AN ELEMENT OF {"NotEqual", 0x02260}, // NOT EQUAL TO -// "NotEqualTilde", 0x02242;0x00338}, // MINUS TILDE with slash + {"NotEqualTilde", 0x02242, 0x00338}, // MINUS TILDE with slash {"NotExists", 0x02204}, // THERE DOES NOT EXIST {"NotGreater", 0x0226F}, // NOT GREATER-THAN {"NotGreaterEqual", 0x02271}, // NEITHER GREATER-THAN NOR EQUAL TO -// "NotGreaterFullEqual", 0x02267;0x00338}, // GREATER-THAN OVER EQUAL TO with slash -// "NotGreaterGreater", 0x0226B;0x00338}, // MUCH GREATER THAN with slash + {"NotGreaterFullEqual", 0x02267, 0x00338}, // GREATER-THAN OVER EQUAL TO with slash + {"NotGreaterGreater", 0x0226B, 0x00338}, // MUCH GREATER THAN with slash {"NotGreaterLess", 0x02279}, // NEITHER GREATER-THAN NOR LESS-THAN -// "NotGreaterSlantEqual", 0x02A7E;0x00338}, // GREATER-THAN OR SLANTED EQUAL TO with slash + {"NotGreaterSlantEqual", 0x02A7E, 0x00338}, // GREATER-THAN OR SLANTED EQUAL TO with slash {"NotGreaterTilde", 0x02275}, // NEITHER GREATER-THAN NOR EQUIVALENT TO -// "NotHumpDownHump", 0x0224E;0x00338}, // GEOMETRICALLY EQUIVALENT TO with slash -// "NotHumpEqual", 0x0224F;0x00338}, // DIFFERENCE BETWEEN with slash + {"NotHumpDownHump", 0x0224E, 0x00338}, // GEOMETRICALLY EQUIVALENT TO with slash + {"NotHumpEqual", 0x0224F, 0x00338}, // DIFFERENCE BETWEEN with slash {"notin", 0x02209}, // NOT AN ELEMENT OF -// "notindot", 0x022F5;0x00338}, // ELEMENT OF WITH DOT ABOVE with slash -// "notinE", 0x022F9;0x00338}, // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash + {"notindot", 0x022F5, 0x00338}, // ELEMENT OF WITH DOT ABOVE with slash + {"notinE", 0x022F9, 0x00338}, // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash {"notinva", 0x02209}, // NOT AN ELEMENT OF {"notinvb", 0x022F7}, // SMALL ELEMENT OF WITH OVERBAR {"notinvc", 0x022F6}, // ELEMENT OF WITH OVERBAR {"NotLeftTriangle", 0x022EA}, // NOT NORMAL SUBGROUP OF -// "NotLeftTriangleBar", 0x029CF;0x00338}, // LEFT TRIANGLE BESIDE VERTICAL BAR with slash + {"NotLeftTriangleBar", 0x029CF, 0x00338}, // LEFT TRIANGLE BESIDE VERTICAL BAR with slash {"NotLeftTriangleEqual", 0x022EC}, // NOT NORMAL SUBGROUP OF OR EQUAL TO {"NotLess", 0x0226E}, // NOT LESS-THAN {"NotLessEqual", 0x02270}, // NEITHER LESS-THAN NOR EQUAL TO {"NotLessGreater", 0x02278}, // NEITHER LESS-THAN NOR GREATER-THAN -// "NotLessLess", 0x0226A;0x00338}, // MUCH LESS THAN with slash -// "NotLessSlantEqual", 0x02A7D;0x00338}, // LESS-THAN OR SLANTED EQUAL TO with slash + {"NotLessLess", 0x0226A, 0x00338}, // MUCH LESS THAN with slash + {"NotLessSlantEqual", 0x02A7D, 0x00338}, // LESS-THAN OR SLANTED EQUAL TO with slash {"NotLessTilde", 0x02274}, // NEITHER LESS-THAN NOR EQUIVALENT TO -// "NotNestedGreaterGreater", 0x02AA2;0x00338}, // DOUBLE NESTED GREATER-THAN with slash -// "NotNestedLessLess", 0x02AA1;0x00338}, // DOUBLE NESTED LESS-THAN with slash + {"NotNestedGreaterGreater", 0x02AA2, 0x00338}, // DOUBLE NESTED GREATER-THAN with slash + {"NotNestedLessLess", 0x02AA1, 0x00338}, // DOUBLE NESTED LESS-THAN with slash {"notni", 0x0220C}, // DOES NOT CONTAIN AS MEMBER {"notniva", 0x0220C}, // DOES NOT CONTAIN AS MEMBER {"notnivb", 0x022FE}, // SMALL CONTAINS WITH OVERBAR {"notnivc", 0x022FD}, // CONTAINS WITH OVERBAR {"NotPrecedes", 0x02280}, // DOES NOT PRECEDE -// "NotPrecedesEqual", 0x02AAF;0x00338}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + {"NotPrecedesEqual", 0x02AAF, 0x00338}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash {"NotPrecedesSlantEqual", 0x022E0}, // DOES NOT PRECEDE OR EQUAL {"NotReverseElement", 0x0220C}, // DOES NOT CONTAIN AS MEMBER {"NotRightTriangle", 0x022EB}, // DOES NOT CONTAIN AS NORMAL SUBGROUP -// "NotRightTriangleBar", 0x029D0;0x00338}, // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash + {"NotRightTriangleBar", 0x029D0, 0x00338}, // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash {"NotRightTriangleEqual", 0x022ED}, // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL -// "NotSquareSubset", 0x0228F;0x00338}, // SQUARE IMAGE OF with slash + {"NotSquareSubset", 0x0228F, 0x00338}, // SQUARE IMAGE OF with slash {"NotSquareSubsetEqual", 0x022E2}, // NOT SQUARE IMAGE OF OR EQUAL TO -// "NotSquareSuperset", 0x02290;0x00338}, // SQUARE ORIGINAL OF with slash + {"NotSquareSuperset", 0x02290, 0x00338}, // SQUARE ORIGINAL OF with slash {"NotSquareSupersetEqual", 0x022E3}, // NOT SQUARE ORIGINAL OF OR EQUAL TO -// "NotSubset", 0x02282;0x020D2}, // SUBSET OF with vertical line + {"NotSubset", 0x02282, 0x020D2}, // SUBSET OF with vertical line {"NotSubsetEqual", 0x02288}, // NEITHER A SUBSET OF NOR EQUAL TO {"NotSucceeds", 0x02281}, // DOES NOT SUCCEED -// "NotSucceedsEqual", 0x02AB0;0x00338}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + {"NotSucceedsEqual", 0x02AB0, 0x00338}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash {"NotSucceedsSlantEqual", 0x022E1}, // DOES NOT SUCCEED OR EQUAL -// "NotSucceedsTilde", 0x0227F;0x00338}, // SUCCEEDS OR EQUIVALENT TO with slash -// "NotSuperset", 0x02283;0x020D2}, // SUPERSET OF with vertical line + {"NotSucceedsTilde", 0x0227F, 0x00338}, // SUCCEEDS OR EQUIVALENT TO with slash + {"NotSuperset", 0x02283, 0x020D2}, // SUPERSET OF with vertical line {"NotSupersetEqual", 0x02289}, // NEITHER A SUPERSET OF NOR EQUAL TO {"NotTilde", 0x02241}, // NOT TILDE {"NotTildeEqual", 0x02244}, // NOT ASYMPTOTICALLY EQUAL TO @@ -1420,25 +1378,25 @@ immutable NameId[] namesN = {"NotVerticalBar", 0x02224}, // DOES NOT DIVIDE {"npar", 0x02226}, // NOT PARALLEL TO {"nparallel", 0x02226}, // NOT PARALLEL TO -// "nparsl", 0x02AFD;0x020E5}, // DOUBLE SOLIDUS OPERATOR with reverse slash -// "npart", 0x02202;0x00338}, // PARTIAL DIFFERENTIAL with slash + {"nparsl", 0x02AFD, 0x020E5}, // DOUBLE SOLIDUS OPERATOR with reverse slash + {"npart", 0x02202, 0x00338}, // PARTIAL DIFFERENTIAL with slash {"npolint", 0x02A14}, // LINE INTEGRATION NOT INCLUDING THE POLE {"npr", 0x02280}, // DOES NOT PRECEDE {"nprcue", 0x022E0}, // DOES NOT PRECEDE OR EQUAL -// "npre", 0x02AAF;0x00338}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + {"npre", 0x02AAF, 0x00338}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash {"nprec", 0x02280}, // DOES NOT PRECEDE -// "npreceq", 0x02AAF;0x00338}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + {"npreceq", 0x02AAF, 0x00338}, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash {"nrarr", 0x0219B}, // RIGHTWARDS ARROW WITH STROKE {"nrArr", 0x021CF}, // RIGHTWARDS DOUBLE ARROW WITH STROKE -// "nrarrc", 0x02933;0x00338}, // WAVE ARROW POINTING DIRECTLY RIGHT with slash -// "nrarrw", 0x0219D;0x00338}, // RIGHTWARDS WAVE ARROW with slash + {"nrarrc", 0x02933, 0x00338}, // WAVE ARROW POINTING DIRECTLY RIGHT with slash + {"nrarrw", 0x0219D, 0x00338}, // RIGHTWARDS WAVE ARROW with slash {"nrightarrow", 0x0219B}, // RIGHTWARDS ARROW WITH STROKE {"nRightarrow", 0x021CF}, // RIGHTWARDS DOUBLE ARROW WITH STROKE {"nrtri", 0x022EB}, // DOES NOT CONTAIN AS NORMAL SUBGROUP {"nrtrie", 0x022ED}, // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL {"nsc", 0x02281}, // DOES NOT SUCCEED {"nsccue", 0x022E1}, // DOES NOT SUCCEED OR EQUAL -// "nsce", 0x02AB0;0x00338}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + {"nsce", 0x02AB0, 0x00338}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash {"Nscr", 0x1D4A9}, // MATHEMATICAL SCRIPT CAPITAL N {"nscr", 0x1D4C3}, // MATHEMATICAL SCRIPT SMALL N {"nshortmid", 0x02224}, // DOES NOT DIVIDE @@ -1452,18 +1410,18 @@ immutable NameId[] namesN = {"nsqsupe", 0x022E3}, // NOT SQUARE ORIGINAL OF OR EQUAL TO {"nsub", 0x02284}, // NOT A SUBSET OF {"nsube", 0x02288}, // NEITHER A SUBSET OF NOR EQUAL TO -// "nsubE", 0x02AC5;0x00338}, // SUBSET OF ABOVE EQUALS SIGN with slash -// "nsubset", 0x02282;0x020D2}, // SUBSET OF with vertical line + {"nsubE", 0x02AC5, 0x00338}, // SUBSET OF ABOVE EQUALS SIGN with slash + {"nsubset", 0x02282, 0x020D2}, // SUBSET OF with vertical line {"nsubseteq", 0x02288}, // NEITHER A SUBSET OF NOR EQUAL TO -// "nsubseteqq", 0x02AC5;0x00338}, // SUBSET OF ABOVE EQUALS SIGN with slash + {"nsubseteqq", 0x02AC5, 0x00338}, // SUBSET OF ABOVE EQUALS SIGN with slash {"nsucc", 0x02281}, // DOES NOT SUCCEED -// "nsucceq", 0x02AB0;0x00338}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + {"nsucceq", 0x02AB0, 0x00338}, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash {"nsup", 0x02285}, // NOT A SUPERSET OF {"nsupe", 0x02289}, // NEITHER A SUPERSET OF NOR EQUAL TO -// "nsupE", 0x02AC6;0x00338}, // SUPERSET OF ABOVE EQUALS SIGN with slash -// "nsupset", 0x02283;0x020D2}, // SUPERSET OF with vertical line + {"nsupE", 0x02AC6, 0x00338}, // SUPERSET OF ABOVE EQUALS SIGN with slash + {"nsupset", 0x02283, 0x020D2}, // SUPERSET OF with vertical line {"nsupseteq", 0x02289}, // NEITHER A SUPERSET OF NOR EQUAL TO -// "nsupseteqq", 0x02AC6;0x00338}, // SUPERSET OF ABOVE EQUALS SIGN with slash + {"nsupseteqq", 0x02AC6, 0x00338}, // SUPERSET OF ABOVE EQUALS SIGN with slash {"ntgl", 0x02279}, // NEITHER GREATER-THAN NOR LESS-THAN {"Ntilde", 0x000D1}, // LATIN CAPITAL LETTER N WITH TILDE {"ntilde", 0x000F1}, // LATIN SMALL LETTER N WITH TILDE @@ -1477,22 +1435,22 @@ immutable NameId[] namesN = {"num", 0x00023}, // NUMBER SIGN {"numero", 0x02116}, // NUMERO SIGN {"numsp", 0x02007}, // FIGURE SPACE -// "nvap", 0x0224D;0x020D2}, // EQUIVALENT TO with vertical line + {"nvap", 0x0224D, 0x020D2}, // EQUIVALENT TO with vertical line {"nvdash", 0x022AC}, // DOES NOT PROVE {"nvDash", 0x022AD}, // NOT TRUE {"nVdash", 0x022AE}, // DOES NOT FORCE {"nVDash", 0x022AF}, // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE -// "nvge", 0x02265;0x020D2}, // GREATER-THAN OR EQUAL TO with vertical line -// "nvgt", 0x0003E;0x020D2}, // GREATER-THAN SIGN with vertical line + {"nvge", 0x02265, 0x020D2}, // GREATER-THAN OR EQUAL TO with vertical line + {"nvgt", 0x0003E, 0x020D2}, // GREATER-THAN SIGN with vertical line {"nvHarr", 0x02904}, // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE {"nvinfin", 0x029DE}, // INFINITY NEGATED WITH VERTICAL BAR {"nvlArr", 0x02902}, // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE -// "nvle", 0x02264;0x020D2}, // LESS-THAN OR EQUAL TO with vertical line -// "nvlt", 0x0003C;0x020D2}, // LESS-THAN SIGN with vertical line -// "nvltrie", 0x022B4;0x020D2}, // NORMAL SUBGROUP OF OR EQUAL TO with vertical line + {"nvle", 0x02264, 0x020D2}, // LESS-THAN OR EQUAL TO with vertical line + {"nvlt", 0x0003C, 0x020D2}, // LESS-THAN SIGN with vertical line + {"nvltrie", 0x022B4, 0x020D2}, // NORMAL SUBGROUP OF OR EQUAL TO with vertical line {"nvrArr", 0x02903}, // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE -// "nvrtrie", 0x022B5;0x020D2}, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line -// "nvsim", 0x0223C;0x020D2}, // TILDE OPERATOR with vertical line + {"nvrtrie", 0x022B5, 0x020D2}, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line + {"nvsim", 0x0223C, 0x020D2}, // TILDE OPERATOR with vertical line {"nwarhk", 0x02923}, // NORTH WEST ARROW WITH HOOK {"nwarr", 0x02196}, // NORTH WEST ARROW {"nwArr", 0x021D6}, // NORTH WEST DOUBLE ARROW @@ -1704,7 +1662,7 @@ immutable NameId[] namesQ = immutable NameId[] namesR = [ {"rAarr", 0x021DB}, // RIGHTWARDS TRIPLE ARROW -// "race", 0x0223D;0x00331}, // REVERSED TILDE with underline + {"race", 0x0223D, 0x00331}, // REVERSED TILDE with underline {"Racute", 0x00154}, // LATIN CAPITAL LETTER R WITH ACUTE {"racute", 0x00155}, // LATIN SMALL LETTER R WITH ACUTE {"radic", 0x0221A}, // SQUARE ROOT @@ -1932,7 +1890,7 @@ immutable NameId[] namesS = {"smile", 0x02323}, // SMILE {"smt", 0x02AAA}, // SMALLER THAN {"smte", 0x02AAC}, // SMALLER THAN OR EQUAL TO -// "smtes", 0x02AAC;0x0FE00}, // SMALLER THAN OR slanted EQUAL + {"smtes", 0x02AAC, 0x0FE00}, // SMALLER THAN OR slanted EQUAL {"SOFTcy", 0x0042C}, // CYRILLIC CAPITAL LETTER SOFT SIGN {"softcy", 0x0044C}, // CYRILLIC SMALL LETTER SOFT SIGN {"sol", 0x0002F}, // SOLIDUS @@ -1944,9 +1902,9 @@ immutable NameId[] namesS = {"spadesuit", 0x02660}, // BLACK SPADE SUIT {"spar", 0x02225}, // PARALLEL TO {"sqcap", 0x02293}, // SQUARE CAP -// "sqcaps", 0x02293;0x0FE00}, // SQUARE CAP with serifs + {"sqcaps", 0x02293, 0x0FE00}, // SQUARE CAP with serifs {"sqcup", 0x02294}, // SQUARE CUP -// "sqcups", 0x02294;0x0FE00}, // SQUARE CUP with serifs + {"sqcups", 0x02294, 0x0FE00}, // SQUARE CUP with serifs {"Sqrt", 0x0221A}, // SQUARE ROOT {"sqsub", 0x0228F}, // SQUARE IMAGE OF {"sqsube", 0x02291}, // SQUARE IMAGE OF OR EQUAL TO @@ -2082,7 +2040,7 @@ immutable NameId[] namesT = {"thgr", 0x003B8}, // GREEK SMALL LETTER THETA {"thickapprox", 0x02248}, // ALMOST EQUAL TO {"thicksim", 0x0223C}, // TILDE OPERATOR -// "ThickSpace", 0x0205F;0x0200A}, // space of width 5/18 em + {"ThickSpace", 0x0205F, 0x0200A}, // space of width 5/18 em {"thinsp", 0x02009}, // THIN SPACE {"ThinSpace", 0x02009}, // THIN SPACE {"thkap", 0x02248}, // ALMOST EQUAL TO @@ -2245,10 +2203,10 @@ immutable NameId[] namesV = {"vArr", 0x021D5}, // UP DOWN DOUBLE ARROW {"varrho", 0x003F1}, // GREEK RHO SYMBOL {"varsigma", 0x003C2}, // GREEK SMALL LETTER FINAL SIGMA -// "varsubsetneq", 0x0228A;0x0FE00}, // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -// "varsubsetneqq", 0x02ACB;0x0FE00}, // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -// "varsupsetneq", 0x0228B;0x0FE00}, // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -// "varsupsetneqq", 0x02ACC;0x0FE00}, // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + {"varsubsetneq", 0x0228A, 0x0FE00}, // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + {"varsubsetneqq", 0x02ACB, 0x0FE00}, // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + {"varsupsetneq", 0x0228B, 0x0FE00}, // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + {"varsupsetneqq", 0x02ACC, 0x0FE00}, // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members {"vartheta", 0x003D1}, // GREEK THETA SYMBOL {"vartriangleleft", 0x022B2}, // NORMAL SUBGROUP OF {"vartriangleright", 0x022B3}, // CONTAINS AS NORMAL SUBGROUP @@ -2279,18 +2237,18 @@ immutable NameId[] namesV = {"Vfr", 0x1D519}, // MATHEMATICAL FRAKTUR CAPITAL V {"vfr", 0x1D533}, // MATHEMATICAL FRAKTUR SMALL V {"vltri", 0x022B2}, // NORMAL SUBGROUP OF -// "vnsub", 0x02282;0x020D2}, // SUBSET OF with vertical line -// "vnsup", 0x02283;0x020D2}, // SUPERSET OF with vertical line + {"vnsub", 0x02282, 0x020D2}, // SUBSET OF with vertical line + {"vnsup", 0x02283, 0x020D2}, // SUPERSET OF with vertical line {"Vopf", 0x1D54D}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL V {"vopf", 0x1D567}, // MATHEMATICAL DOUBLE-STRUCK SMALL V {"vprop", 0x0221D}, // PROPORTIONAL TO {"vrtri", 0x022B3}, // CONTAINS AS NORMAL SUBGROUP {"Vscr", 0x1D4B1}, // MATHEMATICAL SCRIPT CAPITAL V {"vscr", 0x1D4CB}, // MATHEMATICAL SCRIPT SMALL V -// "vsubne", 0x0228A;0x0FE00}, // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -// "vsubnE", 0x02ACB;0x0FE00}, // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members -// "vsupne", 0x0228B;0x0FE00}, // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members -// "vsupnE", 0x02ACC;0x0FE00}, // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + {"vsubne", 0x0228A, 0x0FE00}, // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + {"vsubnE", 0x02ACB, 0x0FE00}, // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + {"vsupne", 0x0228B, 0x0FE00}, // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + {"vsupnE", 0x02ACC, 0x0FE00}, // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members {"Vvdash", 0x022AA}, // TRIPLE VERTICAL BAR RIGHT TURNSTILE {"vzigzag", 0x0299A}, // VERTICAL ZIGZAG LINE ]; diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d index 7ba0a96aa0a..e7626b0b147 100644 --- a/gcc/d/dmd/escape.d +++ b/gcc/d/dmd/escape.d @@ -409,23 +409,9 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Parameter par, Var { unsafeAssign!"scope variable"(v); } - else if (v.isTypesafeVariadicParameter && p == sc.func) + else if (v.isTypesafeVariadicArray && p == sc.func) { - Type tb = v.type.toBasetype(); - if (tb.ty == Tarray || tb.ty == Tsarray) - { - unsafeAssign!"variadic variable"(v); - } - } - else - { - /* v is not 'scope', and is assigned to a parameter that may escape. - * Therefore, v can never be 'scope'. - */ - if (log) printf("no infer for %s in %s loc %s, fdc %s, %d\n", - v.toChars(), sc.func.ident.toChars(), sc.func.loc.toChars(), fdc.ident.toChars(), __LINE__); - - doNotInferScope(v, vPar); + unsafeAssign!"variadic variable"(v); } } @@ -673,9 +659,8 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef) FuncDeclaration fd = sc.func; - // Determine if va is a parameter that is an indirect reference - const bool vaIsRef = va && va.storage_class & STC.parameter && - (va.isReference() || va.type.toBasetype().isTypeClass()); // ref, out, or class + // Determine if va is a `ref` parameter, so it has a lifetime exceding the function scope + const bool vaIsRef = va && va.isParameter() && va.isReference(); if (log && vaIsRef) printf("va is ref `%s`\n", va.toChars()); /* Determine if va is the first parameter, through which other 'return' parameters @@ -717,7 +702,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef) Dsymbol p = v.toParent2(); if (va && !vaIsRef && !va.isScope() && !v.isScope() && - !v.isTypesafeVariadicParameter && !va.isTypesafeVariadicParameter && + !v.isTypesafeVariadicArray && !va.isTypesafeVariadicArray && (va.isParameter() && va.maybeScope && v.isParameter() && v.maybeScope) && p == fd) { @@ -727,16 +712,9 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef) continue; } - if (vaIsFirstRef && - (v.isScope() || v.maybeScope) && - !(v.storage_class & STC.return_) && - v.isParameter() && - fd.flags & FUNCFLAG.returnInprocess && - p == fd && - !v.isTypesafeVariadicParameter) + if (vaIsFirstRef && p == fd) { - if (log) printf("inferring 'return' for parameter %s in function %s\n", v.toChars(), fd.toChars()); - inferReturn(fd, v, /*returnScope:*/ true); // infer addition of 'return' to make `return scope` + inferReturn(fd, v, /*returnScope:*/ true); } if (!(va && va.isScope()) || vaIsRef) @@ -744,82 +722,66 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef) if (v.isScope()) { - if (vaIsFirstRef && v.isParameter() && v.storage_class & STC.return_) + if (vaIsFirstRef && v.isParameter() && v.isReturn()) { // va=v, where v is `return scope` - if (va.isScope()) + if (inferScope(va)) continue; - - if (va.maybeScope) - { - if (log) printf("inferring scope for lvalue %s\n", va.toChars()); - va.storage_class |= STC.scope_ | STC.scopeinferred; - continue; - } } - if (va && va.isScope() && va.storage_class & STC.return_ && !(v.storage_class & STC.return_)) + // If va's lifetime encloses v's, then error + if (EnclosedBy eb = va.enclosesLifetimeOf(v)) { - // va may return its value, but v does not allow that, so this is an error - if (sc.setUnsafeDIP1000(gag, ae.loc, "scope variable `%s` assigned to return scope `%s`", v, va)) + const(char)* msg; + final switch (eb) { - result = true; - continue; + case EnclosedBy.none: assert(0); + case EnclosedBy.returnScope: + msg = "scope variable `%s` assigned to return scope `%s`"; + break; + case EnclosedBy.longerScope: + if (v.storage_class & STC.temp) + continue; + msg = "scope variable `%s` assigned to `%s` with longer lifetime"; + break; + case EnclosedBy.refVar: + msg = "scope variable `%s` assigned to `ref` variable `%s` with longer lifetime"; + break; + case EnclosedBy.global: + msg = "scope variable `%s` assigned to global variable `%s`"; + break; } - } - // If va's lifetime encloses v's, then error - if (va && !va.isDataseg() && - ((va.enclosesLifetimeOf(v) && !(v.storage_class & STC.temp)) || vaIsRef)) - { - if (sc.setUnsafeDIP1000(gag, ae.loc, "scope variable `%s` assigned to `%s` with longer lifetime", v, va)) + if (sc.setUnsafeDIP1000(gag, ae.loc, msg, v, va)) { result = true; continue; } } - if (va && !va.isDataseg() && (va.isScope() || va.maybeScope)) + // v = scope, va should be scope as well + const vaWasScope = va && va.isScope(); + if (inferScope(va)) { - if (!va.isScope()) - { /* v is scope, and va is not scope, so va needs to - * infer scope - */ - if (log) printf("inferring scope for %s\n", va.toChars()); - va.storage_class |= STC.scope_ | STC.scopeinferred; - /* v returns, and va does not return, so va needs - * to infer return - */ - if (v.storage_class & STC.return_ && - !(va.storage_class & STC.return_)) - { - if (log) printf("infer return for %s\n", va.toChars()); - va.storage_class |= STC.return_ | STC.returninferred; + // In case of `scope local = returnScopeParam`, do not infer return scope for `x` + if (!vaWasScope && v.isReturn() && !va.isReturn()) + { + if (log) printf("infer return for %s\n", va.toChars()); + va.storage_class |= STC.return_ | STC.returninferred; - // Added "return scope" so don't confuse it with "return ref" - if (isRefReturnScope(va.storage_class)) - va.storage_class |= STC.returnScope; - } + // Added "return scope" so don't confuse it with "return ref" + if (isRefReturnScope(va.storage_class)) + va.storage_class |= STC.returnScope; } continue; } result |= sc.setUnsafeDIP1000(gag, ae.loc, "scope variable `%s` assigned to non-scope `%s`", v, e1); } - else if (v.isTypesafeVariadicParameter && p == fd) + else if (v.isTypesafeVariadicArray && p == fd) { - Type tb = v.type.toBasetype(); - if (tb.ty == Tarray || tb.ty == Tsarray) - { - if (va && !va.isDataseg() && (va.isScope() || va.maybeScope)) - { - if (!va.isScope()) - { //printf("inferring scope for %s\n", va.toChars()); - va.storage_class |= STC.scope_ | STC.scopeinferred; - } - continue; - } - result |= sc.setUnsafeDIP1000(gag, ae.loc, "variadic variable `%s` assigned to non-scope `%s`", v, e1); - } + if (inferScope(va)) + continue; + result |= sc.setUnsafeDIP1000(gag, ae.loc, "variadic variable `%s` assigned to non-scope `%s`", v, e1); } else { @@ -845,7 +807,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef) if (va && va.isScope() && !v.isReference()) { - if (!(va.storage_class & STC.return_)) + if (!va.isReturn()) { va.doNotInferReturn = true; } @@ -858,19 +820,14 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef) Dsymbol p = v.toParent2(); - if (vaIsFirstRef && v.isParameter() && - !(v.storage_class & STC.return_) && - fd.flags & FUNCFLAG.returnInprocess && - p == fd) + if (vaIsFirstRef && p == fd) { //if (log) printf("inferring 'return' for parameter %s in function %s\n", v.toChars(), fd.toChars()); inferReturn(fd, v, /*returnScope:*/ false); } // If va's lifetime encloses v's, then error - if (va && - !(vaIsFirstRef && (v.storage_class & STC.return_)) && - (va.enclosesLifetimeOf(v) || (va.isReference() && !(va.storage_class & STC.temp)) || va.isDataseg())) + if (va && !(vaIsFirstRef && v.isReturn()) && va.enclosesLifetimeOf(v)) { if (sc.setUnsafeDIP1000(gag, ae.loc, "address of variable `%s` assigned to `%s` with longer lifetime", v, va)) { @@ -885,13 +842,9 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef) if (p != sc.func) continue; - if (va && !va.isDataseg() && (va.isScope() || va.maybeScope)) + if (inferScope(va)) { - if (!va.isScope()) - { //printf("inferring scope for %s\n", va.toChars()); - va.storage_class |= STC.scope_ | STC.scopeinferred; - } - if (v.storage_class & STC.return_ && !(va.storage_class & STC.return_)) + if (v.isReturn() && !va.isReturn()) va.storage_class |= STC.return_ | STC.returninferred; continue; } @@ -912,7 +865,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef) * then uncount that address of. This is so it won't cause a * closure to be allocated. */ - if (va && va.isScope() && !(va.storage_class & STC.return_) && func.tookAddressOf) + if (va && va.isScope() && !va.isReturn() && func.tookAddressOf) --func.tookAddressOf; foreach (v; vars) @@ -978,14 +931,8 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef) } } - if (va && !va.isDataseg() && (va.isScope() || va.maybeScope)) - { - if (!va.isScope()) - { //printf("inferring scope for %s\n", va.toChars()); - va.storage_class |= STC.scope_ | STC.scopeinferred; - } + if (inferScope(va)) continue; - } result |= sc.setUnsafeDIP1000(gag, ee.loc, "reference to stack allocated value returned by `%s` assigned to non-scope `%s`", ee, e1); @@ -1091,14 +1038,10 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag) continue; } } - else if (v.isTypesafeVariadicParameter && p == sc.func) + else if (v.isTypesafeVariadicArray && p == sc.func) { - Type tb = v.type.toBasetype(); - if (tb.ty == Tarray || tb.ty == Tsarray) - { - result |= sc.setUnsafeDIP1000(gag, e.loc, - "copying `%s` into allocated memory escapes a reference to variadic parameter `%s`", e, v); - } + result |= sc.setUnsafeDIP1000(gag, e.loc, + "copying `%s` into allocated memory escapes a reference to variadic parameter `%s`", e, v); } else { @@ -1258,15 +1201,8 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag) Dsymbol p = v.toParent2(); - if ((v.isScope() || v.maybeScope) && - !(v.storage_class & STC.return_) && - v.isParameter() && - !v.doNotInferReturn && - sc.func.flags & FUNCFLAG.returnInprocess && - p == sc.func && - !v.isTypesafeVariadicParameter) + if (p == sc.func && inferReturn(sc.func, v, /*returnScope:*/ true)) { - inferReturn(sc.func, v, /*returnScope:*/ true); // infer addition of 'return' continue; } @@ -1300,7 +1236,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag) !(!refs && sc.func.isFuncDeclaration().getLevel(pfunc, sc.intypeof) > 0) ) { - if (v.isParameter() && !(v.storage_class & STC.return_)) + if (v.isParameter() && !v.isReturn()) { // https://issues.dlang.org/show_bug.cgi?id=23191 if (!gag) @@ -1320,15 +1256,11 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag) } } } - else if (v.isTypesafeVariadicParameter && p == sc.func) + else if (v.isTypesafeVariadicArray && p == sc.func) { - Type tb = v.type.toBasetype(); - if (tb.ty == Tarray || tb.ty == Tsarray) - { - if (!gag) - error(e.loc, "returning `%s` escapes a reference to variadic parameter `%s`", e.toChars(), v.toChars()); - result = false; - } + if (!gag) + error(e.loc, "returning `%s` escapes a reference to variadic parameter `%s`", e.toChars(), v.toChars()); + result = false; } else { @@ -1414,7 +1346,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag) continue; } FuncDeclaration fd = p.isFuncDeclaration(); - if (fd && sc.func.flags & FUNCFLAG.returnInprocess) + if (fd && sc.func.returnInprocess) { /* Code like: * int x; @@ -1435,10 +1367,10 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag) vsr == ScopeRef.Ref_ReturnScope) && !(v.storage_class & STC.foreach_)) { - if (sc.func.flags & FUNCFLAG.returnInprocess && p == sc.func && - (vsr == ScopeRef.Ref || vsr == ScopeRef.RefScope)) + if (p == sc.func && (vsr == ScopeRef.Ref || vsr == ScopeRef.RefScope) && + inferReturn(sc.func, v, /*returnScope:*/ false)) { - inferReturn(sc.func, v, /*returnScope:*/ false); // infer addition of 'return' + continue; } else { @@ -1488,6 +1420,26 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag) return result; } +/*********************************** + * Infer `scope` for a variable + * + * Params: + * va = variable to infer scope for + * Returns: `true` if succesful or already `scope` + */ +bool inferScope(VarDeclaration va) +{ + if (!va) + return false; + if (!va.isDataseg() && va.maybeScope && !va.isScope()) + { + //printf("inferring scope for %s\n", va.toChars()); + va.maybeScope = false; + va.storage_class |= STC.scope_ | STC.scopeinferred; + return true; + } + return va.isScope(); +} /************************************* * Variable v needs to have 'return' inferred for it. @@ -1495,10 +1447,22 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag) * fd = function that v is a parameter to * v = parameter that needs to be STC.return_ * returnScope = infer `return scope` instead of `return ref` + * + * Returns: whether the inference on `v` was successful or `v` already was `return` */ -private void inferReturn(FuncDeclaration fd, VarDeclaration v, bool returnScope) +private bool inferReturn(FuncDeclaration fd, VarDeclaration v, bool returnScope) { - // v is a local in the current function + if (v.isReturn()) + return !!(v.storage_class & STC.returnScope) == returnScope; + + if (!v.isParameter() || v.isTypesafeVariadicArray || (returnScope && v.doNotInferReturn)) + return false; + + if (!fd.returnInprocess) + return false; + + if (returnScope && !(v.isScope() || v.maybeScope)) + return false; //printf("for function '%s' inferring 'return' for variable '%s', returnScope: %d\n", fd.toChars(), v.toChars(), returnScope); auto newStcs = STC.return_ | STC.returninferred | (returnScope ? STC.returnScope : 0); @@ -1532,6 +1496,7 @@ private void inferReturn(FuncDeclaration fd, VarDeclaration v, bool returnScope) } } } + return true; } @@ -1694,7 +1659,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re { if (tb.ty == Tsarray) return; - if (v.isTypesafeVariadicParameter) + if (v.isTypesafeVariadicArray) { er.byvalue.push(v); return; @@ -2008,13 +1973,10 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR if (auto ve = e.e1.isVarExp()) { VarDeclaration v = ve.var.isVarDeclaration(); - if (tb.ty == Tarray || tb.ty == Tsarray) + if (v && v.isTypesafeVariadicArray) { - if (v && v.isTypesafeVariadicParameter) - { - er.pushRef(v, retRefTransition); - return; - } + er.pushRef(v, retRefTransition); + return; } } if (tb.ty == Tsarray) @@ -2339,9 +2301,9 @@ private void doNotInferScope(VarDeclaration v, RootObject o) void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f) { - if (funcdecl.flags & FUNCFLAG.returnInprocess) + if (funcdecl.returnInprocess) { - funcdecl.flags &= ~FUNCFLAG.returnInprocess; + funcdecl.returnInprocess = false; if (funcdecl.storage_class & STC.return_) { if (funcdecl.type == f) @@ -2353,9 +2315,9 @@ void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f) } } - if (!(funcdecl.flags & FUNCFLAG.inferScope)) + if (!funcdecl.inferScope) return; - funcdecl.flags &= ~FUNCFLAG.inferScope; + funcdecl.inferScope = false; // Eliminate maybescope's { @@ -2387,22 +2349,19 @@ void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f) foreach (u, p; f.parameterList) { auto v = (*funcdecl.parameters)[u]; - if (v.maybeScope) + if (!v.isScope() && inferScope(v)) { //printf("Inferring scope for %s\n", v.toChars()); - notMaybeScope(v, null); - v.storage_class |= STC.scope_ | STC.scopeinferred; p.storageClass |= STC.scope_ | STC.scopeinferred; } } } - if (funcdecl.vthis && funcdecl.vthis.maybeScope) + if (funcdecl.vthis) { - notMaybeScope(funcdecl.vthis, null); - funcdecl.vthis.storage_class |= STC.scope_ | STC.scopeinferred; - f.isScopeQual = true; - f.isscopeinferred = true; + inferScope(funcdecl.vthis); + f.isScopeQual = funcdecl.vthis.isScope(); + f.isscopeinferred = !!(funcdecl.vthis.storage_class & STC.scopeinferred); } } @@ -2542,20 +2501,45 @@ bool isReferenceToMutable(Parameter p, Type t) return isReferenceToMutable(p.type); } +/// When checking lifetime for assignment `va=v`, the way `va` encloses `v` +private enum EnclosedBy +{ + none = 0, + refVar, // `va` is a `ref` variable, which may link to a global variable + global, // `va` is a global variable + returnScope, // `va` is a scope variable that may be returned + longerScope, // `va` is another scope variable declared earlier than `v` +} + /********************************** -* Determine if `va` has a lifetime that lasts past -* the destruction of `v` -* Params: -* va = variable assigned to -* v = variable being assigned -* Returns: -* true if it does -*/ -private bool enclosesLifetimeOf(const VarDeclaration va, const VarDeclaration v) pure + * Determine if `va` has a lifetime that lasts past + * the destruction of `v` + * Params: + * va = variable assigned to + * v = variable being assigned + * Returns: + * The way `va` encloses `v` (if any) + */ +private EnclosedBy enclosesLifetimeOf(VarDeclaration va, VarDeclaration v) { + if (!va) + return EnclosedBy.none; + + if (va.isDataseg()) + return EnclosedBy.global; + + if (va.isScope() && va.isReturn() && !v.isReturn()) + return EnclosedBy.returnScope; + + if (va.isReference() && va.isParameter()) + return EnclosedBy.refVar; + assert(va.sequenceNumber != va.sequenceNumber.init); assert(v.sequenceNumber != v.sequenceNumber.init); - return va.sequenceNumber < v.sequenceNumber; + if (va.sequenceNumber < v.sequenceNumber) + return EnclosedBy.longerScope; + + return EnclosedBy.none; } /*************************************** @@ -2576,53 +2560,6 @@ private void addMaybe(VarDeclaration va, VarDeclaration v) va.maybes.push(v); } -/*************************************** - * Like `FuncDeclaration.setUnsafe`, but modified for dip25 / dip1000 by default transitions - * - * With `-preview=dip1000` it actually sets the function as unsafe / prints an error, while - * without it, it only prints a deprecation in a `@safe` function. - * With `-revert=preview=dip1000`, it doesn't do anything. - * - * Params: - * sc = used for checking whether we are in a deprecated scope - * fs = command line setting of dip1000 / dip25 - * gag = surpress error message - * loc = location of error - * fmt = printf-style format string - * arg0 = (optional) argument for first %s format specifier - * arg1 = (optional) argument for second %s format specifier - * arg2 = (optional) argument for third %s format specifier - * Returns: whether an actual safe error (not deprecation) occured - */ -private bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* msg, - RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null) -{ - if (fs == FeatureState.disabled) - { - return false; - } - else if (fs == FeatureState.enabled) - { - return sc.setUnsafe(gag, loc, msg, arg0, arg1, arg2); - } - else - { - if (sc.func.isSafeBypassingInference()) - { - if (!gag) - previewErrorFunc(sc.isDeprecated(), fs)( - loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "" - ); - } - else if (!sc.func.safetyViolation) - { - import dmd.func : AttributeViolation; - sc.func.safetyViolation = new AttributeViolation(loc, msg, arg0, arg1, arg2); - } - return false; - } -} - // `setUnsafePreview` partially evaluated for dip1000 private bool setUnsafeDIP1000(Scope* sc, bool gag, Loc loc, const(char)* msg, RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null) @@ -2671,13 +2608,19 @@ private bool checkScopeVarAddr(VarDeclaration v, Expression e, Scope* sc, bool g } /**************************** - * Determine if `v` is a typesafe variadic parameter. + * Determine if `v` is a typesafe variadic array, which is implicitly `scope` * Params: * v = variable to check * Returns: * true if `v` is a variadic parameter */ -bool isTypesafeVariadicParameter(VarDeclaration v) +private bool isTypesafeVariadicArray(VarDeclaration v) { - return !!(v.storage_class & STC.variadic); + if (v.storage_class & STC.variadic) + { + Type tb = v.type.toBasetype(); + if (tb.ty == Tarray || tb.ty == Tsarray) + return true; + } + return false; } diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 42b4dd45c09..21f5cc76a4b 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -2949,7 +2949,7 @@ extern (C++) final class ArrayLiteralExp : Expression Expressions* elements; OwnedBy ownedByCtfe = OwnedBy.code; - + bool onstack = false; extern (D) this(const ref Loc loc, Type type, Expressions* elements) { diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index c9e39787106..79bc5288577 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -419,6 +419,7 @@ public: Expression *basis; Expressions *elements; OwnedBy ownedByCtfe; + bool onstack; static ArrayLiteralExp *create(const Loc &loc, Expressions *elements); static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements); diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index 8a4a13ce133..f899bd79d20 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -353,6 +353,37 @@ extern(D) bool arrayExpressionSemantic( return err; } +/* +Checks if `exp` contains a direct access to a `noreturn` +variable. If that is the case, an `assert(0)` expression +is generated and returned. This function should be called +only after semantic analysis has been performed on `exp`. + +Params: + exp = expression that is checked + +Returns: + An `assert(0)` expression if `exp` contains a `noreturn` + variable access, `exp` otherwise. +*/ + +Expression checkNoreturnVarAccess(Expression exp) +{ + assert(exp.type); + + Expression result = exp; + if (exp.type.isTypeNoreturn() && !exp.isAssertExp() && + !exp.isThrowExp() && !exp.isCallExp()) + { + auto msg = new StringExp(exp.loc, "Accessed expression of type `noreturn`"); + msg.type = Type.tstring; + result = new AssertExp(exp.loc, IntegerExp.literal!0, msg); + result.type = exp.type; + } + + return result; +} + /****************************** * Check the tail CallExp is really property function call. * Bugs: @@ -848,6 +879,18 @@ Lagain: if (d) d.checkDisabled(loc, sc); } + + if (auto sd = s.isDeclaration()) + { + if (sd.isSystem()) + { + if (sc.setUnsafePreview(global.params.systemVariables, false, loc, + "cannot access `@system` variable `%s` in @safe code", sd)) + { + return ErrorExp.get(); + } + } + } } if (auto em = s.isEnumMember()) @@ -1714,7 +1757,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, if (sc._module) sc._module.hasAlwaysInlines = true; if (sc.func) - sc.func.flags |= FUNCFLAG.hasAlwaysInline; + sc.func.hasAlwaysInlines = true; } const isCtorCall = fd && fd.needThis() && fd.isCtorDeclaration(); @@ -2200,14 +2243,14 @@ private bool functionParameters(const ref Loc loc, Scope* sc, /* If calling C scanf(), printf(), or any variants, check the format string against the arguments */ const isVa_list = tf.parameterList.varargs == VarArg.none; - if (fd && fd.flags & FUNCFLAG.printf) + if (fd && fd.printf) { if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp()) { checkPrintfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list); } } - else if (fd && fd.flags & FUNCFLAG.scanf) + else if (fd && fd.scanf) { if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp()) { @@ -4628,8 +4671,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor else if (exp.arguments.dim == 1) { e = (*exp.arguments)[0]; - e = e.implicitCastTo(sc, t1); - e = new CastExp(exp.loc, e, t1); + if (!e.type.isTypeNoreturn()) + e = e.implicitCastTo(sc, t1); } else { @@ -7474,6 +7517,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } + if (exp.e1.type.isTypeNoreturn() && (!exp.to || !exp.to.isTypeNoreturn())) + { + result = exp.e1; + return; + } if (exp.to && !exp.to.isTypeSArray() && !exp.to.isTypeFunction()) exp.e1 = exp.e1.arrayFuncConv(sc); @@ -7889,7 +7937,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return setError(); } } - else if (t1b.ty == Tvector) + else if (t1b.ty == Tvector && exp.e1.isLvalue()) { // Convert e1 to corresponding static array TypeVector tv1 = cast(TypeVector)t1b; @@ -8896,7 +8944,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.e1 = e1x; assert(exp.e1.type); } - Type t1 = exp.e1.type.toBasetype(); + Type t1 = exp.e1.type.isTypeEnum() ? exp.e1.type : exp.e1.type.toBasetype(); /* Run this.e2 semantic. * Different from other binary expressions, the analysis of e2 @@ -8918,14 +8966,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor e2x.checkSharedAccess(sc)) return setError(); - if (e2x.type.isTypeNoreturn() && !e2x.isAssertExp() && !e2x.isThrowExp() && !e2x.isCallExp()) - { - auto msg = new StringExp(e2x.loc, "Accessed expression of type `noreturn`"); - msg.type = Type.tstring; - e2x = new AssertExp(e2x.loc, IntegerExp.literal!0, msg); - e2x.type = Type.tnoreturn; - return setResult(e2x); - } + auto etmp = checkNoreturnVarAccess(e2x); + if (etmp != e2x) + return setResult(etmp); + exp.e2 = e2x; } @@ -9890,14 +9934,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor exp.type = exp.e1.type; assert(exp.type); + auto assignElem = exp.e2; auto res = exp.op == EXP.assign ? exp.reorderSettingAAElem(sc) : exp; - Expression tmp; /* https://issues.dlang.org/show_bug.cgi?id=22366 * * `reorderSettingAAElem` creates a tree of comma expressions, however, * `checkAssignExp` expects only AssignExps. */ - checkAssignEscape(sc, Expression.extractLast(res, tmp), false, false); + if (res == exp) // no `AA[k] = v` rewrite was performed + checkAssignEscape(sc, res, false, false); + else + checkNewEscape(sc, assignElem, false); // assigning to AA puts it on heap if (auto ae = res.isConstructExp()) { @@ -9905,40 +9952,48 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (t1b.ty != Tsarray && t1b.ty != Tarray) return setResult(res); - /* Do not lower Rvalues and references, as they need to be moved, - * not copied. - * Skip the lowering when the RHS is an array literal, as e2ir - * already handles such cases more elegantly. - */ - const isArrayCtor = - (ae.e1.isSliceExp || ae.e1.type.ty == Tsarray) && - ae.e2.isLvalue && - !(ae.e1.isVarExp && - ae.e1.isVarExp.var.isVarDeclaration.isReference) && - (ae.e2.isVarExp || - ae.e2.isSliceExp || - (ae.e2.type.ty == Tsarray && !ae.e2.isArrayLiteralExp)) && - ae.e1.type.nextOf && - ae.e2.type.nextOf && - ae.e1.type.nextOf.mutableOf.equals(ae.e2.type.nextOf.mutableOf); - - /* Unlike isArrayCtor above, lower all Rvalues. If the RHS is a literal, - * then we do want to make a temporary for it and call its destructor. - */ - const isArraySetCtor = - (ae.e1.isSliceExp || ae.e1.type.ty == Tsarray) && - (ae.e2.type.ty == Tstruct || ae.e2.type.ty == Tsarray) && - ae.e1.type.nextOf && - ae.e1.type.nextOf.equivalent(ae.e2.type); + // only non-trivial array constructions may need to be lowered (non-POD elements basically) + Type t1e = t1b.nextOf(); + TypeStruct ts = t1e.baseElemOf().isTypeStruct(); + if (!ts || (!ts.sym.postblit && !ts.sym.hasCopyCtor && !ts.sym.dtor)) + return setResult(res); - if (isArrayCtor || isArraySetCtor) + // don't lower ref-constructions etc. + if (!(t1b.ty == Tsarray || ae.e1.isSliceExp) || + (ae.e1.isVarExp && ae.e1.isVarExp.var.isVarDeclaration.isReference)) + return setResult(res); + + // Construction from an equivalent other array? + // Only lower with lvalue RHS elements; let the glue layer move rvalue elements. + Type t2b = ae.e2.type.toBasetype(); + // skip over a (possibly implicit) cast of a static array RHS to a slice + Expression rhs = ae.e2; + Type rhsType = t2b; + if (t2b.ty == Tarray) { - const ts = t1b.nextOf().baseElemOf().isTypeStruct(); - if (!ts || (!ts.sym.postblit && !ts.sym.hasCopyCtor && !ts.sym.dtor)) - return setResult(res); + if (auto ce = rhs.isCastExp()) + { + auto ct = ce.e1.type.toBasetype(); + if (ct.ty == Tsarray) + { + rhs = ce.e1; + rhsType = ct; + } + } + } + const lowerToArrayCtor = + ( (rhsType.ty == Tarray && !rhs.isArrayLiteralExp) || + (rhsType.ty == Tsarray && rhs.isLvalue) ) && + t1e.equivalent(t2b.nextOf); + + // Construction from a single element? + // If the RHS is an rvalue, then we'll need to make a temporary for it (copied multiple times). + const lowerToArraySetCtor = !lowerToArrayCtor && t1e.equivalent(t2b); - auto func = isArrayCtor ? Id._d_arrayctor : Id._d_arraysetctor; - const other = isArrayCtor ? "other array" : "value"; + if (lowerToArrayCtor || lowerToArraySetCtor) + { + auto func = lowerToArrayCtor ? Id._d_arrayctor : Id._d_arraysetctor; + const other = lowerToArrayCtor ? "other array" : "value"; if (!verifyHookExist(exp.loc, *sc, func, "construct array with " ~ other, Id.object)) return setError(); @@ -9948,18 +10003,18 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor id = new DotIdExp(exp.loc, id, func); auto arguments = new Expressions(); - arguments.push(new CastExp(ae.loc, ae.e1, ae.e1.type.nextOf.arrayOf).expressionSemantic(sc)); - if (isArrayCtor) + arguments.push(new CastExp(ae.loc, ae.e1, t1e.arrayOf).expressionSemantic(sc)); + if (lowerToArrayCtor) { - arguments.push(new CastExp(ae.loc, ae.e2, ae.e2.type.nextOf.arrayOf).expressionSemantic(sc)); + arguments.push(new CastExp(ae.loc, rhs, t2b.nextOf.arrayOf).expressionSemantic(sc)); Expression ce = new CallExp(exp.loc, id, arguments); res = ce.expressionSemantic(sc); } else { Expression e0; - // If ae.e2 is not a variable, construct a temp variable, as _d_arraysetctor requires `ref` access - if (!ae.e2.isVarExp) + // promote an rvalue RHS element to a temporary, it's passed by ref to _d_arraysetctor + if (!ae.e2.isLvalue) { auto vd = copyToTemp(STC.scope_, "__setctor", ae.e2); e0 = new DeclarationExp(vd.loc, vd).expressionSemantic(sc); @@ -11759,6 +11814,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor result = arrayLowering; return; } + + if (t1.isTypeVector()) + exp.type = t1; + result = exp; return; } @@ -12038,6 +12097,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor return; } + if (t1.isTypeVector()) + exp.type = t1; + result = exp; } @@ -12490,8 +12552,7 @@ Expression semanticX(DotIdExp exp, Scope* sc) if (f.checkForwardRef(loc)) return ErrorExp.get(); - if (f.flags & (FUNCFLAG.purityInprocess | FUNCFLAG.safetyInprocess | - FUNCFLAG.nothrowInprocess | FUNCFLAG.nogcInprocess)) + if (f.purityInprocess || f.safetyInprocess || f.nothrowInprocess || f.nogcInprocess) { f.error(loc, "cannot retrieve its `.mangleof` while inferring attributes"); return ErrorExp.get(); @@ -13099,7 +13160,7 @@ Lerr: */ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false) { - if (!global.params.noSharedAccess || + if (global.params.noSharedAccess != FeatureState.enabled || sc.intypeof || sc.flags & SCOPE.ctfe) { diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index bcae282f09f..3b0b34e603d 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -182,7 +182,7 @@ public: catches.push(ctch); Statement s2 = new TryCatchStatement(Loc.initial, s._body, catches); - fd.flags &= ~FUNCFLAG.noEH; + fd.hasNoEH = false; replaceCurrent(s2); s2.accept(this); } @@ -191,31 +191,31 @@ public: } } -enum FUNCFLAG : uint +private struct FUNCFLAG { - purityInprocess = 1, /// working on determining purity - safetyInprocess = 2, /// working on determining safety - nothrowInprocess = 4, /// working on determining nothrow - nogcInprocess = 8, /// working on determining @nogc - returnInprocess = 0x10, /// working on inferring 'return' for parameters - inlineScanned = 0x20, /// function has been scanned for inline possibilities - inferScope = 0x40, /// infer 'scope' for parameters - hasCatches = 0x80, /// function has try-catch statements - compileTimeOnly = 0x100, /// is a compile time only function; no code will be generated for it - printf = 0x200, /// is a printf-like function - scanf = 0x400, /// is a scanf-like function - noreturn = 0x800, /// the function does not return - NRVO = 0x1000, /// Support for named return value optimization - naked = 0x2000, /// The function is 'naked' (see inline ASM) - generated = 0x4000, /// The function is compiler generated (e.g. `opCmp`) - introducing = 0x8000, /// If this function introduces the overload set - semantic3Errors = 0x10000, /// If errors in semantic3 this function's frame ptr - noEH = 0x20000, /// No exception unwinding is needed - inferRetType = 0x40000, /// Return type is to be inferred - dualContext = 0x80000, /// has a dual-context 'this' parameter - hasAlwaysInline = 0x100000, /// Contains references to functions that must be inlined - CRTCtor = 0x200000, /// Has attribute pragma(crt_constructor) - CRTDtor = 0x400000, /// Has attribute pragma(crt_destructor) + bool purityInprocess; /// working on determining purity + bool safetyInprocess; /// working on determining safety + bool nothrowInprocess; /// working on determining nothrow + bool nogcInprocess; /// working on determining @nogc + bool returnInprocess; /// working on inferring 'return' for parameters + bool inlineScanned; /// function has been scanned for inline possibilities + bool inferScope; /// infer 'scope' for parameters + bool hasCatches; /// function has try-catch statements + bool isCompileTimeOnly; /// is a compile time only function; no code will be generated for it + bool printf; /// is a printf-like function + bool scanf; /// is a scanf-like function + bool noreturn; /// the function does not return + bool isNRVO = true; /// Support for named return value optimization + bool isNaked; /// The function is 'naked' (see inline ASM) + bool isGenerated; /// The function is compiler generated (e.g. `opCmp`) + bool isIntroducing; /// If this function introduces the overload set + bool hasSemantic3Errors; /// If errors in semantic3 this function's frame ptr + bool hasNoEH; /// No exception unwinding is needed + bool inferRetType; /// Return type is to be inferred + bool hasDualContext; /// has a dual-context 'this' parameter + bool hasAlwaysInlines; /// Contains references to functions that must be inlined + bool isCrtCtor; /// Has attribute pragma(crt_constructor) + bool isCrtDtor; /// Has attribute pragma(crt_destructor) } /*********************************************************** @@ -348,9 +348,9 @@ extern (C++) class FuncDeclaration : Declaration /// better diagnostics AttributeViolation* safetyViolation; - /// Function flags: A collection of boolean packed for memory efficiency - /// See the `FUNCFLAG` enum - uint flags = FUNCFLAG.NRVO; + /// See the `FUNCFLAG` struct + import dmd.common.bitfields; + mixin(generateBitFields!(FUNCFLAG, uint)); /** * Data for a function declaration that is needed for the Objective-C @@ -373,13 +373,13 @@ extern (C++) class FuncDeclaration : Declaration } this.endloc = endloc; if (noreturn) - this.flags |= FUNCFLAG.noreturn; + this.noreturn = true; /* The type given for "infer the return type" is a TypeFunction with * NULL for the return type. */ if (type && type.nextOf() is null) - this.flags |= FUNCFLAG.inferRetType; + this.inferRetType = true; } static FuncDeclaration create(const ref Loc loc, const ref Loc endloc, Identifier id, StorageClass storage_class, Type type, bool noreturn = false) @@ -391,7 +391,7 @@ extern (C++) class FuncDeclaration : Declaration { //printf("FuncDeclaration::syntaxCopy('%s')\n", toChars()); FuncDeclaration f = s ? cast(FuncDeclaration)s - : new FuncDeclaration(loc, endloc, ident, storage_class, type.syntaxCopy(), (flags & FUNCFLAG.noreturn) != 0); + : new FuncDeclaration(loc, endloc, ident, storage_class, type.syntaxCopy(), this.noreturn != 0); f.frequires = frequires ? Statement.arraySyntaxCopy(frequires) : null; f.fensures = fensures ? Ensure.arraySyntaxCopy(fensures) : null; f.fbody = fbody ? fbody.syntaxCopy() : null; @@ -522,7 +522,7 @@ extern (C++) class FuncDeclaration : Declaration { const bool dualCtx = (toParent2() != toParentLocal()); if (dualCtx) - this.flags |= FUNCFLAG.dualContext; + this.hasDualContext = true; auto ad = isThis(); if (!dualCtx && !ad && !isNested()) { @@ -1376,29 +1376,29 @@ extern (C++) class FuncDeclaration : Declaration //printf("initInferAttributes() for %s (%s)\n", toPrettyChars(), ident.toChars()); TypeFunction tf = type.toTypeFunction(); if (tf.purity == PURE.impure) // purity not specified - flags |= FUNCFLAG.purityInprocess; + purityInprocess = true; if (tf.trust == TRUST.default_) - flags |= FUNCFLAG.safetyInprocess; + safetyInprocess = true; if (!tf.isnothrow) - flags |= FUNCFLAG.nothrowInprocess; + nothrowInprocess = true; if (!tf.isnogc) - flags |= FUNCFLAG.nogcInprocess; + nogcInprocess = true; if (!isVirtual() || this.isIntroducing()) - flags |= FUNCFLAG.returnInprocess; + returnInprocess = true; // Initialize for inferring STC.scope_ - flags |= FUNCFLAG.inferScope; + inferScope = true; } final PURE isPure() { //printf("FuncDeclaration::isPure() '%s'\n", toChars()); TypeFunction tf = type.toTypeFunction(); - if (flags & FUNCFLAG.purityInprocess) + if (purityInprocess) setImpure(); if (tf.purity == PURE.fwdref) tf.purityLevel(); @@ -1424,7 +1424,7 @@ extern (C++) class FuncDeclaration : Declaration final PURE isPureBypassingInference() { - if (flags & FUNCFLAG.purityInprocess) + if (purityInprocess) return PURE.fwdref; else return isPure(); @@ -1437,9 +1437,9 @@ extern (C++) class FuncDeclaration : Declaration */ extern (D) final bool setImpure() { - if (flags & FUNCFLAG.purityInprocess) + if (purityInprocess) { - flags &= ~FUNCFLAG.purityInprocess; + purityInprocess = false; if (fes) fes.func.setImpure(); } @@ -1448,21 +1448,32 @@ extern (C++) class FuncDeclaration : Declaration return false; } + extern (D) final uint flags() + { + return bitFields; + } + + extern (D) final uint flags(uint f) + { + bitFields = f; + return bitFields; + } + final bool isSafe() { - if (flags & FUNCFLAG.safetyInprocess) + if (safetyInprocess) setUnsafe(); return type.toTypeFunction().trust == TRUST.safe; } final bool isSafeBypassingInference() { - return !(flags & FUNCFLAG.safetyInprocess) && isSafe(); + return !(safetyInprocess) && isSafe(); } final bool isTrusted() { - if (flags & FUNCFLAG.safetyInprocess) + if (safetyInprocess) setUnsafe(); return type.toTypeFunction().trust == TRUST.trusted; } @@ -1483,9 +1494,9 @@ extern (C++) class FuncDeclaration : Declaration bool gag = false, Loc loc = Loc.init, const(char)* fmt = null, RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null) { - if (flags & FUNCFLAG.safetyInprocess) + if (safetyInprocess) { - flags &= ~FUNCFLAG.safetyInprocess; + safetyInprocess = false; type.toTypeFunction().trust = TRUST.system; if (fmt || arg0) safetyViolation = new AttributeViolation(loc, fmt, arg0, arg1, arg2); @@ -1518,99 +1529,14 @@ extern (C++) class FuncDeclaration : Declaration final bool isNogc() { //printf("isNogc() %s, inprocess: %d\n", toChars(), !!(flags & FUNCFLAG.nogcInprocess)); - if (flags & FUNCFLAG.nogcInprocess) + if (nogcInprocess) setGC(); return type.toTypeFunction().isnogc; } final bool isNogcBypassingInference() { - return !(flags & FUNCFLAG.nogcInprocess) && isNogc(); - } - - final bool isNRVO() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.NRVO); - } - - final void isNRVO(bool v) pure nothrow @safe @nogc - { - if (v) this.flags |= FUNCFLAG.NRVO; - else this.flags &= ~FUNCFLAG.NRVO; - } - - final bool isNaked() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.naked); - } - - final void isNaked(bool v) @safe pure nothrow @nogc - { - if (v) this.flags |= FUNCFLAG.naked; - else this.flags &= ~FUNCFLAG.naked; - } - - final bool isGenerated() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.generated); - } - - final void isGenerated(bool v) pure nothrow @safe @nogc - { - if (v) this.flags |= FUNCFLAG.generated; - else this.flags &= ~FUNCFLAG.generated; - } - - final bool isIntroducing() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.introducing); - } - - final bool hasSemantic3Errors() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.semantic3Errors); - } - - final bool hasNoEH() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.noEH); - } - - final bool inferRetType() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.inferRetType); - } - - final bool hasDualContext() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.dualContext); - } - - final bool hasAlwaysInlines() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.hasAlwaysInline); - } - - final bool isCrtCtor() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.CRTCtor); - } - - final void isCrtCtor(bool v) @safe pure nothrow @nogc - { - if (v) this.flags |= FUNCFLAG.CRTCtor; - else this.flags &= ~FUNCFLAG.CRTCtor; - } - - final bool isCrtDtor() const scope @safe pure nothrow @nogc - { - return !!(this.flags & FUNCFLAG.CRTDtor); - } - - final void isCrtDtor(bool v) @safe pure nothrow @nogc - { - if (v) this.flags |= FUNCFLAG.CRTDtor; - else this.flags &= ~FUNCFLAG.CRTDtor; + return !nogcInprocess && isNogc(); } /************************************** @@ -1622,15 +1548,15 @@ extern (C++) class FuncDeclaration : Declaration extern (D) final bool setGC() { //printf("setGC() %s\n", toChars()); - if (flags & FUNCFLAG.nogcInprocess && semanticRun < PASS.semantic3 && _scope) + if (nogcInprocess && semanticRun < PASS.semantic3 && _scope) { this.semantic2(_scope); this.semantic3(_scope); } - if (flags & FUNCFLAG.nogcInprocess) + if (nogcInprocess) { - flags &= ~FUNCFLAG.nogcInprocess; + nogcInprocess = false; type.toTypeFunction().isnogc = false; if (fes) fes.func.setGC(); @@ -3384,6 +3310,28 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s, // re-resolve to check for supplemental message if (!global.gag || global.params.showGaggedErrors) { + if (tthis) + { + if (auto classType = tthis.isTypeClass()) + { + if (auto baseClass = classType.sym.baseClass) + { + if (auto baseFunction = baseClass.search(baseClass.loc, fd.ident)) + { + MatchAccumulator mErr; + functionResolve(mErr, baseFunction, loc, sc, tiargs, baseClass.type, fargs, null); + if (mErr.last > MATCH.nomatch && mErr.lastf) + { + errorSupplemental(loc, "%s `%s` hides base class function `%s`", + fd.kind, fd.toPrettyChars(), mErr.lastf.toPrettyChars()); + errorSupplemental(loc, "add `alias %s = %s` to `%s`'s body to merge the overload sets", + fd.toChars(), mErr.lastf.toPrettyChars(), tthis.toChars()); + return null; + } + } + } + } + } const(char)* failMessage; functionResolve(m, orig_s, loc, sc, tiargs, tthis, fargs, &failMessage); if (failMessage) @@ -3767,7 +3715,7 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration this.fes = fes; // Always infer scope for function literals // See https://issues.dlang.org/show_bug.cgi?id=20362 - this.flags |= FUNCFLAG.inferScope; + this.inferScope = true; //printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this.ident.toChars(), type.toChars()); } @@ -4431,6 +4379,58 @@ bool setUnsafe(Scope* sc, return sc.func.setUnsafe(gag, loc, fmt, arg0, arg1, arg2); } +/*************************************** + * Like `setUnsafe`, but for safety errors still behind preview switches + * + * Given a `FeatureState fs`, for example dip1000 / dip25 / systemVariables, + * the behavior changes based on the setting: + * + * - In case of `-revert=fs`, it does nothing. + * - In case of `-preview=fs`, it's the same as `setUnsafe` + * - By default, print a deprecation in `@safe` functions, or store an attribute violation in inferred functions. + * + * Params: + * sc = used to find affected function/variable, and for checking whether we are in a deprecated / speculative scope + * fs = feature state from the preview flag + * gag = surpress error message + * loc = location of error + * msg = printf-style format string + * arg0 = (optional) argument for first %s format specifier + * arg1 = (optional) argument for second %s format specifier + * arg2 = (optional) argument for third %s format specifier + * Returns: whether an actual safe error (not deprecation) occured + */ +bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)* msg, + RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null) +{ + if (fs == FeatureState.disabled) + { + return false; + } + else if (fs == FeatureState.enabled) + { + return sc.setUnsafe(gag, loc, msg, arg0, arg1, arg2); + } + else + { + if (!sc.func) + return false; + if (sc.func.isSafeBypassingInference()) + { + if (!gag) + previewErrorFunc(sc.isDeprecated(), fs)( + loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "" + ); + } + else if (!sc.func.safetyViolation) + { + import dmd.func : AttributeViolation; + sc.func.safetyViolation = new AttributeViolation(loc, msg, arg0, arg1, arg2); + } + return false; + } +} + /// Stores a reason why a function failed to infer a function attribute like `@safe` or `pure` /// /// Has two modes: diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 745d5eb067c..2770f5a91ca 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -160,15 +160,16 @@ extern (C++) struct Param // https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a // https://digitalmars.com/d/archives/digitalmars/D/Binding_rvalues_to_ref_parameters_redux_325087.html // Implementation: https://github.com/dlang/dmd/pull/9817 - bool noSharedAccess; // read/write access to shared memory objects + FeatureState noSharedAccess; // read/write access to shared memory objects bool previewIn; // `in` means `[ref] scope const`, accepts rvalues bool inclusiveInContracts; // 'in' contracts of overridden methods must be a superset of parent contract - bool shortenedMethods; // allow => in normal function declarations + bool shortenedMethods = true; // allow => in normal function declarations bool fixImmutableConv; // error on unsound immutable conversion - https://github.com/dlang/dmd/pull/14070 bool fix16997 = true; // fix integral promotions for unary + - ~ operators // https://issues.dlang.org/show_bug.cgi?id=16997 FeatureState dtorFields; // destruct fields of partially constructed objects // https://issues.dlang.org/show_bug.cgi?id=14246 + FeatureState systemVariables; // limit access to variables marked @system from @safe code CHECKENABLE useInvariants = CHECKENABLE._default; // generate class invariant checks CHECKENABLE useIn = CHECKENABLE._default; // generate precondition checks diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index a6b1c90bb6c..d9cb76c707c 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -158,7 +158,7 @@ struct Param // https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a // https://digitalmars.com/d/archives/digitalmars/D/Binding_rvalues_to_ref_parameters_redux_325087.html // Implementation: https://github.com/dlang/dmd/pull/9817 - bool noSharedAccess; // read/write access to shared memory objects + FeatureState noSharedAccess; // read/write access to shared memory objects bool previewIn; // `in` means `[ref] scope const`, accepts rvalues bool inclusiveInContracts; // 'in' contracts of overridden methods must be a superset of parent contract bool shortenedMethods; // allow => in normal function declarations @@ -166,7 +166,9 @@ struct Param bool fix16997; // fix integral promotions for unary + - ~ operators // https://issues.dlang.org/show_bug.cgi?id=16997 FeatureState dtorFields; // destruct fields of partially constructed objects - // https://issues.dlang.org/show_bug.cgi?id=14246 + // https://issues.dlang.org/show_bug.cgi?id=14246 + FeatureState systemVariables; // limit access to variables marked @system from @safe code + CHECKENABLE useInvariants; // generate class invariant checks CHECKENABLE useIn; // generate precondition checks CHECKENABLE useOut; // generate postcondition checks diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index 48995db89f6..debf01d2a8e 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -64,6 +64,7 @@ struct HdrGenState int tpltMember; int autoMember; int forStmtInit; + int insideFuncBody; bool declstring; // set while declaring alias for string,wstring or dstring EnumDeclaration inEnumDecl; @@ -1045,8 +1046,18 @@ public: buf.writestring(", "); argsToBuffer(d.args, buf, hgs); } + buf.writeByte(')'); + + // https://issues.dlang.org/show_bug.cgi?id=14690 + // Unconditionally perform a full output dump + // for `pragma(inline)` declarations. + bool savedFullDump = global.params.dihdr.fullOutput; + if (d.ident == Id.Pinline) + global.params.dihdr.fullOutput = true; + visit(cast(AttribDeclaration)d); + global.params.dihdr.fullOutput = savedFullDump; } override void visit(ConditionalDeclaration d) @@ -1549,7 +1560,7 @@ public: bodyToBuffer(f); hgs.autoMember--; } - else if (hgs.tpltMember == 0 && global.params.dihdr.fullOutput == false) + else if (hgs.tpltMember == 0 && global.params.dihdr.fullOutput == false && !hgs.insideFuncBody) { if (!f.fbody) { @@ -1634,7 +1645,7 @@ public: void bodyToBuffer(FuncDeclaration f) { - if (!f.fbody || (hgs.hdrgen && global.params.dihdr.fullOutput == false && !hgs.autoMember && !hgs.tpltMember)) + if (!f.fbody || (hgs.hdrgen && global.params.dihdr.fullOutput == false && !hgs.autoMember && !hgs.tpltMember && !hgs.insideFuncBody)) { if (!f.fbody && (f.fensures || f.frequires)) { @@ -1645,6 +1656,18 @@ public: buf.writenl(); return; } + + // there is no way to know if a function is nested + // or not after parsing. We need scope information + // for that, which is avaible during semantic + // analysis. To overcome that, a simple mechanism + // is implemented: everytime we print a function + // body (templated or not) we increment a counter. + // We decredement the counter when we stop + // printing the function body. + ++hgs.insideFuncBody; + scope(exit) { --hgs.insideFuncBody; } + const savetlpt = hgs.tpltMember; const saveauto = hgs.autoMember; hgs.tpltMember = 0; diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index 1de89d4d6b6..451e227e98a 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -1197,9 +1197,9 @@ class Lexer /******************************************* * Parse escape sequence. */ - private uint escapeSequence() + private uint escapeSequence(out dchar c2) { - return Lexer.escapeSequence(token.loc, p, Ccompile); + return Lexer.escapeSequence(token.loc, p, Ccompile, c2); } /******** @@ -1211,10 +1211,11 @@ class Lexer * sequence = pointer to string with escape sequence to parse. Updated to * point past the end of the escape sequence * Ccompile = true for compile C11 escape sequences + * c2 = returns second `dchar` of html entity with 2 code units, otherwise stays `dchar.init` * Returns: * the escape sequence as a single character */ - private dchar escapeSequence(const ref Loc loc, ref const(char)* sequence, bool Ccompile) + private dchar escapeSequence(const ref Loc loc, ref const(char)* sequence, bool Ccompile, out dchar c2) { const(char)* p = sequence; // cache sequence reference on stack scope(exit) sequence = p; @@ -1326,12 +1327,16 @@ class Lexer switch (*p) { case ';': - c = HtmlNamedEntity(idstart[0 .. p - idstart]); - if (c == ~0) + auto entity = HtmlNamedEntity(idstart[0 .. p - idstart]); + c = entity[0]; + if (entity == entity.init) { error(loc, "unnamed character entity &%.*s;", cast(int)(p - idstart), idstart); c = '?'; } + if (entity[1] != entity.init[1]) + c2 = entity[1]; + p++; break; default: @@ -1665,6 +1670,7 @@ class Lexer while (1) { dchar c = *p++; + dchar c2; switch (c) { case '\\': @@ -1673,15 +1679,19 @@ class Lexer case '&': if (Ccompile) goto default; - goto case; + c = escapeSequence(c2); + stringbuffer.writeUTF8(c); + if (c2 != dchar.init) + stringbuffer.writeUTF8(c2); + continue; case 'u': case 'U': - c = escapeSequence(); + c = escapeSequence(c2); stringbuffer.writeUTF8(c); continue; default: - c = escapeSequence(); + c = escapeSequence(c2); break; } break; @@ -1746,22 +1756,26 @@ class Lexer //printf("Lexer::charConstant\n"); p++; dchar c = *p++; + dchar c2; switch (c) { case '\\': switch (*p) { case 'u': - t.unsvalue = escapeSequence(); tk = TOK.wcharLiteral; - break; + goto default; case 'U': case '&': - t.unsvalue = escapeSequence(); tk = TOK.dcharLiteral; - break; + goto default; default: - t.unsvalue = escapeSequence(); + t.unsvalue = escapeSequence(c2); + if (c2 != c2.init) + { + error("html entity requires 2 code units, use a string instead of a character"); + t.unsvalue = '?'; + } break; } break; @@ -1978,8 +1992,6 @@ class Lexer break; case 'b': case 'B': - if (Ccompile) - error("binary constants not allowed"); ++p; base = 2; break; @@ -3185,8 +3197,9 @@ unittest static void test(T)(string sequence, T expected, bool Ccompile = false) { auto p = cast(const(char)*)sequence.ptr; + dchar c2; Lexer lexer = new Lexer(); - assert(expected == lexer.escapeSequence(Loc.initial, p, Ccompile)); + assert(expected == lexer.escapeSequence(Loc.initial, p, Ccompile, c2)); assert(p == sequence.ptr + sequence.length); } @@ -3253,7 +3266,8 @@ unittest expected = expectedError; auto p = cast(const(char)*)sequence.ptr; Lexer lexer = new Lexer(); - auto actualReturnValue = lexer.escapeSequence(Loc.initial, p, Ccompile); + dchar c2; + auto actualReturnValue = lexer.escapeSequence(Loc.initial, p, Ccompile, c2); assert(gotError); assert(expectedReturnValue == actualReturnValue); diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h index 341ce361f3c..48046def130 100644 --- a/gcc/d/dmd/module.h +++ b/gcc/d/dmd/module.h @@ -116,7 +116,7 @@ public: size_t namelen; // length of module name in characters static Module* create(const char *arg, Identifier *ident, int doDocComment, int doHdrGen); - + static const char *find(const char *filename); static Module *load(const Loc &loc, Identifiers *packages, Identifier *ident); const char *kind() const override; diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 1240f5a8a9d..265f731cedd 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -2488,6 +2488,16 @@ extern (C++) abstract class Type : ASTNode return false; } + /************************************* + * Detect if this is an unsafe type because of the presence of `@system` members + * Returns: + * true if so + */ + bool hasSystemFields() + { + return false; + } + /*************************************** * Returns: true if type has any invariants */ @@ -3821,6 +3831,16 @@ extern (C++) final class TypeSArray : TypeArray return next.hasPointers(); } + override bool hasSystemFields() + { + return next.hasSystemFields(); + } + + override bool hasVoidInitPointers() + { + return next.hasVoidInitPointers(); + } + override bool hasInvariant() { return next.hasInvariant(); @@ -5532,52 +5552,32 @@ extern (C++) final class TypeStruct : Type override bool hasPointers() { - // Probably should cache this information in sym rather than recompute - StructDeclaration s = sym; - if (sym.members && !sym.determineFields() && sym.type != Type.terror) error(sym.loc, "no size because of forward references"); - foreach (VarDeclaration v; s.fields) - { - if (v.storage_class & STC.ref_ || v.hasPointers()) - return true; - } - return false; + sym.determineTypeProperties(); + return sym.hasPointerField; } override bool hasVoidInitPointers() { - // Probably should cache this information in sym rather than recompute - StructDeclaration s = sym; + sym.size(Loc.initial); // give error for forward references + sym.determineTypeProperties(); + return sym.hasVoidInitPointers; + } + override bool hasSystemFields() + { sym.size(Loc.initial); // give error for forward references - foreach (VarDeclaration v; s.fields) - { - if (v._init && v._init.isVoidInitializer() && v.type.hasPointers()) - return true; - if (!v._init && v.type.hasVoidInitPointers()) - return true; - } - return false; + sym.determineTypeProperties(); + return sym.hasSystemFields; } override bool hasInvariant() { - // Probably should cache this information in sym rather than recompute - StructDeclaration s = sym; - sym.size(Loc.initial); // give error for forward references - - if (s.hasInvariant()) - return true; - - foreach (VarDeclaration v; s.fields) - { - if (v.type.hasInvariant()) - return true; - } - return false; + sym.determineTypeProperties(); + return sym.hasInvariant() || sym.hasFieldWithInvariant; } extern (D) MATCH implicitConvToWithoutAliasThis(Type to) @@ -5857,6 +5857,11 @@ extern (C++) final class TypeEnum : Type return memType().hasVoidInitPointers(); } + override bool hasSystemFields() + { + return memType().hasSystemFields(); + } + override bool hasInvariant() { return memType().hasInvariant(); diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h index 2b9c94cf7f2..c81c25a0d79 100644 --- a/gcc/d/dmd/mtype.h +++ b/gcc/d/dmd/mtype.h @@ -311,6 +311,7 @@ public: virtual int hasWild() const; virtual bool hasPointers(); virtual bool hasVoidInitPointers(); + virtual bool hasSystemFields(); virtual bool hasInvariant(); virtual Type *nextOf(); Type *baseElemOf(); @@ -458,6 +459,8 @@ public: MATCH implicitConvTo(Type *to) override; Expression *defaultInitLiteral(const Loc &loc) override; bool hasPointers() override; + bool hasSystemFields() override; + bool hasVoidInitPointers() override; bool hasInvariant() override; bool needsDestruction() override; bool needsCopyOrPostblit() override; @@ -794,6 +797,7 @@ public: bool needsNested() override; bool hasPointers() override; bool hasVoidInitPointers() override; + bool hasSystemFields() override; bool hasInvariant() override; MATCH implicitConvTo(Type *to) override; MATCH constConv(Type *to) override; @@ -832,6 +836,7 @@ public: bool isZeroInit(const Loc &loc) override; bool hasPointers() override; bool hasVoidInitPointers() override; + bool hasSystemFields() override; bool hasInvariant() override; Type *nextOf() override; diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index 8cf35851922..7ddeeecae9b 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -99,7 +99,7 @@ public: override void visit(ArrayLiteralExp e) { - if (e.type.ty != Tarray || !e.elements || !e.elements.dim) + if (e.type.ty != Tarray || !e.elements || !e.elements.dim || e.onstack) return; if (f.setGC()) { @@ -221,7 +221,7 @@ Expression checkGC(Scope* sc, Expression e) FuncDeclaration f = sc.func; if (e && e.op != EXP.error && f && sc.intypeof != 1 && !(sc.flags & SCOPE.ctfe) && (f.type.ty == Tfunction && - (cast(TypeFunction)f.type).isnogc || (f.flags & FUNCFLAG.nogcInprocess) || global.params.vgc) && + (cast(TypeFunction)f.type).isnogc || f.nogcInprocess || global.params.vgc) && !(sc.flags & SCOPE.debug_)) { scope NOGCVisitor gcv = new NOGCVisitor(f); diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index ed85a5de96a..6fb542fb9aa 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -888,6 +888,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer error("redundant visibility attribute `%s`", AST.visibilityToChars(prot)); } pAttrs.visibility.kind = prot; + const attrloc = token.loc; nextToken(); @@ -908,7 +909,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } } - const attrloc = token.loc; a = parseBlock(pLastDecl, pAttrs); if (pAttrs.visibility.kind != AST.Visibility.Kind.undefined) { @@ -3168,9 +3168,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (udas) { - auto s = new AST.Dsymbols(); - s.push(em); - auto uad = new AST.UserAttributeDeclaration(udas, s); + auto uad = new AST.UserAttributeDeclaration(udas, new AST.Dsymbols()); em.userAttribDecl = uad; } diff --git a/gcc/d/dmd/printast.d b/gcc/d/dmd/printast.d index bba34814472..8c71a1a36aa 100644 --- a/gcc/d/dmd/printast.d +++ b/gcc/d/dmd/printast.d @@ -203,6 +203,13 @@ extern (C++) final class PrintASTVisitor : Visitor printf(".func: %s\n", e.func ? e.func.toChars() : ""); } + override void visit(CompoundLiteralExp e) + { + visit(cast(Expression)e); + printIndent(indent + 2); + printf(".init: %s\n", e.initializer ? e.initializer.toChars() : ""); + } + static void printIndent(int indent) { foreach (i; 0 .. indent) diff --git a/gcc/d/dmd/root/utf.d b/gcc/d/dmd/root/utf.d index 15838e9a068..eb198fc7603 100644 --- a/gcc/d/dmd/root/utf.d +++ b/gcc/d/dmd/root/utf.d @@ -288,7 +288,7 @@ bool isUniAlpha(dchar c) // Binary search while (low <= high) { - size_t mid = (low + high) >> 1; + const size_t mid = low + ((high - low) >> 1); if (c < ALPHA_TABLE[mid][0]) high = mid - 1; else if (ALPHA_TABLE[mid][1] < c) diff --git a/gcc/d/dmd/safe.d b/gcc/d/dmd/safe.d index 4446b5e66b0..397fd2ef472 100644 --- a/gcc/d/dmd/safe.d +++ b/gcc/d/dmd/safe.d @@ -26,7 +26,7 @@ import dmd.identifier; import dmd.mtype; import dmd.target; import dmd.tokens; -import dmd.func : setUnsafe; +import dmd.func : setUnsafe, setUnsafePreview; /************************************************************* * Check for unsafe access in @safe code: @@ -57,6 +57,14 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg) if (!ad) return false; + import dmd.globals : global; + if (v.isSystem()) + { + if (sc.setUnsafePreview(global.params.systemVariables, !printmsg, e.loc, + "cannot access `@system` field `%s.%s` in `@safe` code", ad, v)) + return true; + } + // needed to set v.overlapped and v.overlapUnsafe if (ad.sizeok != Sizeok.done) ad.determineSize(ad.loc); diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index d2f9c0ab04b..8ea419a1f57 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -282,7 +282,7 @@ private extern(C++) final class Semantic3Visitor : Visitor // Disable generated opAssign, because some members forbid identity assignment. funcdecl.storage_class |= STC.disable; funcdecl.fbody = null; // remove fbody which contains the error - funcdecl.flags &= ~FUNCFLAG.semantic3Errors; + funcdecl.hasSemantic3Errors = false; } return; } @@ -292,7 +292,7 @@ private extern(C++) final class Semantic3Visitor : Visitor if (funcdecl.semanticRun >= PASS.semantic3) return; funcdecl.semanticRun = PASS.semantic3; - funcdecl.flags &= ~FUNCFLAG.semantic3Errors; + funcdecl.hasSemantic3Errors = false; if (!funcdecl.type || funcdecl.type.ty != Tfunction) return; @@ -650,7 +650,7 @@ private extern(C++) final class Semantic3Visitor : Visitor // handle NRVO if (!target.isReturnOnStack(f, funcdecl.needThis()) || !funcdecl.checkNRVO()) - funcdecl.flags &= ~FUNCFLAG.NRVO; + funcdecl.isNRVO = false; if (funcdecl.fbody.isErrorStatement()) { @@ -753,15 +753,15 @@ private extern(C++) final class Semantic3Visitor : Visitor if (f.isnothrow && blockexit & BE.throw_) error(funcdecl.loc, "%s `%s` may throw but is marked as `nothrow`", funcdecl.kind(), funcdecl.toPrettyChars()); - if (!(blockexit & (BE.throw_ | BE.halt) || funcdecl.flags & FUNCFLAG.hasCatches)) + if (!(blockexit & (BE.throw_ | BE.halt) || funcdecl.hasCatches)) { /* Don't generate unwind tables for this function * https://issues.dlang.org/show_bug.cgi?id=17997 */ - funcdecl.flags |= FUNCFLAG.noEH; + funcdecl.hasNoEH = true; } - if (funcdecl.flags & FUNCFLAG.nothrowInprocess) + if (funcdecl.nothrowInprocess) { if (funcdecl.type == f) f = cast(TypeFunction)f.copy(); @@ -976,7 +976,7 @@ private extern(C++) final class Semantic3Visitor : Visitor /* Do the semantic analysis on the [in] preconditions and * [out] postconditions. */ - immutable bool isnothrow = f.isnothrow && !(funcdecl.flags & FUNCFLAG.nothrowInprocess); + immutable bool isnothrow = f.isnothrow && !funcdecl.nothrowInprocess; if (freq) { /* frequire is composed of the [in] contracts @@ -1001,11 +1001,11 @@ private extern(C++) final class Semantic3Visitor : Visitor // Deprecated in 2.101, can be made an error in 2.111 deprecation(funcdecl.loc, "`%s`: `in` contract may throw but function is marked as `nothrow`", funcdecl.toPrettyChars()); - else if (funcdecl.flags & FUNCFLAG.nothrowInprocess) + else if (funcdecl.nothrowInprocess) f.isnothrow = false; } - funcdecl.flags &= ~FUNCFLAG.noEH; + funcdecl.hasNoEH = false; sc2 = sc2.pop(); @@ -1048,11 +1048,11 @@ private extern(C++) final class Semantic3Visitor : Visitor // Deprecated in 2.101, can be made an error in 2.111 deprecation(funcdecl.loc, "`%s`: `out` contract may throw but function is marked as `nothrow`", funcdecl.toPrettyChars()); - else if (funcdecl.flags & FUNCFLAG.nothrowInprocess) + else if (funcdecl.nothrowInprocess) f.isnothrow = false; } - funcdecl.flags &= ~FUNCFLAG.noEH; + funcdecl.hasNoEH = false; sc2 = sc2.pop(); @@ -1180,10 +1180,10 @@ private extern(C++) final class Semantic3Visitor : Visitor const blockexit = s.blockExit(funcdecl, isnothrow); if (blockexit & BE.throw_) { - funcdecl.flags &= ~FUNCFLAG.noEH; + funcdecl.hasNoEH = false; if (isnothrow) error(funcdecl.loc, "%s `%s` may throw but is marked as `nothrow`", funcdecl.kind(), funcdecl.toPrettyChars()); - else if (funcdecl.flags & FUNCFLAG.nothrowInprocess) + else if (funcdecl.nothrowInprocess) f.isnothrow = false; } @@ -1195,7 +1195,7 @@ private extern(C++) final class Semantic3Visitor : Visitor } } // from this point on all possible 'throwers' are checked - funcdecl.flags &= ~FUNCFLAG.nothrowInprocess; + funcdecl.nothrowInprocess = false; if (funcdecl.isSynchronized()) { @@ -1274,25 +1274,25 @@ private extern(C++) final class Semantic3Visitor : Visitor /* If function survived being marked as impure, then it is pure */ - if (funcdecl.flags & FUNCFLAG.purityInprocess) + if (funcdecl.purityInprocess) { - funcdecl.flags &= ~FUNCFLAG.purityInprocess; + funcdecl.purityInprocess = false; if (funcdecl.type == f) f = cast(TypeFunction)f.copy(); f.purity = PURE.fwdref; } - if (funcdecl.flags & FUNCFLAG.safetyInprocess) + if (funcdecl.safetyInprocess) { - funcdecl.flags &= ~FUNCFLAG.safetyInprocess; + funcdecl.safetyInprocess = false; if (funcdecl.type == f) f = cast(TypeFunction)f.copy(); f.trust = TRUST.safe; } - if (funcdecl.flags & FUNCFLAG.nogcInprocess) + if (funcdecl.nogcInprocess) { - funcdecl.flags &= ~FUNCFLAG.nogcInprocess; + funcdecl.nogcInprocess = false; if (funcdecl.type == f) f = cast(TypeFunction)f.copy(); f.isnogc = true; @@ -1395,9 +1395,9 @@ private extern(C++) final class Semantic3Visitor : Visitor */ funcdecl.semanticRun = PASS.semantic3done; if ((global.errors != oldErrors) || (funcdecl.fbody && funcdecl.fbody.isErrorStatement())) - funcdecl.flags |= FUNCFLAG.semantic3Errors; + funcdecl.hasSemantic3Errors = true; else - funcdecl.flags &= ~FUNCFLAG.semantic3Errors; + funcdecl.hasSemantic3Errors = false; if (funcdecl.type.ty == Terror) funcdecl.errors = true; //printf("-FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", funcdecl.parent.toChars(), funcdecl.toChars(), sc, funcdecl.loc.toChars()); diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index e5e57535b37..4f9baf89dc2 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -2010,32 +2010,8 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor //printf("body = %p\n", ps._body); if (ps.ident == Id.msg) { - if (ps.args) - { - foreach (arg; *ps.args) - { - sc = sc.startCTFE(); - auto e = arg.expressionSemantic(sc); - e = resolveProperties(sc, e); - sc = sc.endCTFE(); - - // pragma(msg) is allowed to contain types as well as expressions - e = ctfeInterpretForPragmaMsg(e); - if (e.op == EXP.error) - { - errorSupplemental(ps.loc, "while evaluating `pragma(msg, %s)`", arg.toChars()); - return setError(); - } - if (auto se = e.toStringExp()) - { - const slice = se.toUTF8(sc).peekString(); - fprintf(stderr, "%.*s", cast(int)slice.length, slice.ptr); - } - else - fprintf(stderr, "%s", e.toChars()); - } - fprintf(stderr, "\n"); - } + if (!pragmaMsgSemantic(ps.loc, sc, ps.args)) + return setError(); } else if (ps.ident == Id.lib) { @@ -2075,75 +2051,19 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } else if (ps.ident == Id.startaddress) { - if (!ps.args || ps.args.dim != 1) - ps.error("function name expected for start address"); - else - { - Expression e = (*ps.args)[0]; - sc = sc.startCTFE(); - e = e.expressionSemantic(sc); - e = resolveProperties(sc, e); - sc = sc.endCTFE(); - - e = e.ctfeInterpret(); - (*ps.args)[0] = e; - Dsymbol sa = getDsymbol(e); - if (!sa || !sa.isFuncDeclaration()) - { - ps.error("function name expected for start address, not `%s`", e.toChars()); - return setError(); - } - if (ps._body) - { - ps._body = ps._body.statementSemantic(sc); - if (ps._body.isErrorStatement()) - { - result = ps._body; - return; - } - } - result = ps; - return; - } + if (!pragmaStartAddressSemantic(ps.loc, sc, ps.args)) + return setError(); } else if (ps.ident == Id.Pinline) { - PINLINE inlining = PINLINE.default_; - if (!ps.args || ps.args.dim == 0) - inlining = PINLINE.default_; - else if (!ps.args || ps.args.dim != 1) + if (auto fd = sc.func) { - ps.error("boolean expression expected for `pragma(inline)`"); - return setError(); + fd.inlining = evalPragmaInline(ps.loc, sc, ps.args); } else { - Expression e = (*ps.args)[0]; - sc = sc.startCTFE(); - e = e.expressionSemantic(sc); - e = resolveProperties(sc, e); - sc = sc.endCTFE(); - e = e.ctfeInterpret(); - e = e.toBoolean(sc); - if (e.isErrorExp()) - { - ps.error("pragma(`inline`, `true` or `false`) expected, not `%s`", (*ps.args)[0].toChars()); - return setError(); - } - - const opt = e.toBool(); - if (opt.hasValue(true)) - inlining = PINLINE.always; - else if (opt.hasValue(false)) - inlining = PINLINE.never; - - FuncDeclaration fd = sc.func; - if (!fd) - { - ps.error("`pragma(inline)` is not inside a function"); - return setError(); - } - fd.inlining = inlining; + ps.error("`pragma(inline)` is not inside a function"); + return setError(); } } else if (!global.params.ignoreUnsupportedPragmas) @@ -2932,13 +2852,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor } // https://issues.dlang.org/show_bug.cgi?id=23063 - if (texp.isTypeNoreturn() && !rs.exp.isAssertExp() && !rs.exp.isThrowExp() && !rs.exp.isCallExp()) - { - auto msg = new StringExp(rs.exp.loc, "Accessed expression of type `noreturn`"); - msg.type = Type.tstring; - rs.exp = new AssertExp(rs.loc, IntegerExp.literal!0, msg); - rs.exp.type = texp; - } + rs.exp = checkNoreturnVarAccess(rs.exp); // @@@DEPRECATED_2.111@@@ const olderrors = global.startGagging(); @@ -3022,7 +2936,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor // If we previously assumed the function could be ref when // checking for `shared`, make sure we were right - if (global.params.noSharedAccess && rs.exp.type.isShared()) + if (global.params.noSharedAccess == FeatureState.enabled && rs.exp.type.isShared()) { fd.error("function returns `shared` but cannot be inferred `ref`"); supplemental(); @@ -3648,7 +3562,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor if (sc.func) { - sc.func.flags |= FUNCFLAG.hasCatches; + sc.func.hasCatches = true; if (flags == (FLAGcpp | FLAGd)) { tcs.error("cannot mix catching D and C++ exceptions in the same try-catch"); @@ -4925,3 +4839,83 @@ private void debugThrowWalker(Statement s) scope walker = new DebugWalker(); s.accept(walker); } + +/*********************************************************** + * Evaluate and print a `pragma(msg, args)` + * + * Params: + * loc = location for error messages + * sc = scope for argument interpretation + * args = expressions to print + * Returns: + * `true` on success + */ +bool pragmaMsgSemantic(Loc loc, Scope* sc, Expressions* args) +{ + if (!args) + return true; + foreach (arg; *args) + { + sc = sc.startCTFE(); + auto e = arg.expressionSemantic(sc); + e = resolveProperties(sc, e); + sc = sc.endCTFE(); + + // pragma(msg) is allowed to contain types as well as expressions + e = ctfeInterpretForPragmaMsg(e); + if (e.op == EXP.error) + { + errorSupplemental(loc, "while evaluating `pragma(msg, %s)`", arg.toChars()); + return false; + } + if (auto se = e.toStringExp()) + { + const slice = se.toUTF8(sc).peekString(); + fprintf(stderr, "%.*s", cast(int)slice.length, slice.ptr); + } + else + fprintf(stderr, "%s", e.toChars()); + } + fprintf(stderr, "\n"); + return true; +} + +/*********************************************************** + * Evaluate `pragma(startAddress, func)` and store the resolved symbol in `args` + * + * Params: + * loc = location for error messages + * sc = scope for argument interpretation + * args = pragma arguments + * Returns: + * `true` on success + */ +bool pragmaStartAddressSemantic(Loc loc, Scope* sc, Expressions* args) +{ + if (!args || args.dim != 1) + { + .error(loc, "function name expected for start address"); + return false; + } + else + { + /* https://issues.dlang.org/show_bug.cgi?id=11980 + * resolveProperties and ctfeInterpret call are not necessary. + */ + Expression e = (*args)[0]; + sc = sc.startCTFE(); + e = e.expressionSemantic(sc); + // e = resolveProperties(sc, e); + sc = sc.endCTFE(); + + // e = e.ctfeInterpret(); + (*args)[0] = e; + Dsymbol sa = getDsymbol(e); + if (!sa || !sa.isFuncDeclaration()) + { + .error(loc, "function name expected for start address, not `%s`", e.toChars()); + return false; + } + } + return true; +} diff --git a/gcc/d/dmd/templateparamsem.d b/gcc/d/dmd/templateparamsem.d index e093260adc7..e79a9ec957e 100644 --- a/gcc/d/dmd/templateparamsem.d +++ b/gcc/d/dmd/templateparamsem.d @@ -73,6 +73,15 @@ private extern (C++) final class TemplateParameterSemanticVisitor : Visitor result = !(ttp.specType && isError(ttp.specType)); } + override void visit(TemplateThisParameter ttp) + { + import dmd.errors; + + if (!sc.getStructClassScope()) + error(ttp.loc, "cannot use `this` outside an aggregate type"); + visit(cast(TemplateTypeParameter)ttp); + } + override void visit(TemplateValueParameter tvp) { tvp.valType = tvp.valType.typeSemantic(tvp.loc, sc); diff --git a/gcc/d/dmd/transitivevisitor.d b/gcc/d/dmd/transitivevisitor.d index 0d7240f4ef4..cbe6daa35a4 100644 --- a/gcc/d/dmd/transitivevisitor.d +++ b/gcc/d/dmd/transitivevisitor.d @@ -799,6 +799,15 @@ package mixin template ParseVisitMethods(AST) s.accept(this); } + override void visit(AST.InterfaceDeclaration d) + { + //printf("Visiting InterfaceDeclaration\n"); + visitBaseClasses(d); + if (d.members) + foreach (s; *d.members) + s.accept(this); + } + override void visit(AST.AliasDeclaration d) { //printf("Visting AliasDeclaration\n"); diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index fa5ec90a2bc..e939e7761e8 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -1099,6 +1099,7 @@ public: this assignment should call dtors on old assigned elements. */ if ((!postblit && !destructor) || (e->op == EXP::construct && e->e2->op == EXP::arrayLiteral) + || (e->op == EXP::construct && e->e2->op == EXP::call) || (e->op == EXP::construct && !lvalue && postblit) || (e->op == EXP::blit || e->e1->type->size () == 0)) { @@ -2704,6 +2705,14 @@ public: this->result_ = compound_expr (saved_elems, d_convert (type, ctor)); } + else if (e->onstack) + { + /* Array literal for a `scope' dynamic array. */ + gcc_assert (tb->ty == TY::Tarray); + ctor = force_target_expr (ctor); + this->result_ = d_array_value (type, size_int (e->elements->length), + build_address (ctor)); + } else { /* Allocate space on the memory managed heap. */ diff --git a/gcc/d/gdc.texi b/gcc/d/gdc.texi index 2bff627d863..d3bf75ccfa9 100644 --- a/gcc/d/gdc.texi +++ b/gcc/d/gdc.texi @@ -344,6 +344,9 @@ Turns on generation of struct equality to use field-wise comparisons. @item fixaliasthis Implements new lookup rules that check the current scope for @code{alias this} before searching in upper scopes. +@item fiximmutableconv +Disallows unsound immutable conversions that were formerly incorrectly +permitted. @item in Implements @code{in} parameters to mean @code{scope const [ref]} and accepts rvalues. @@ -357,9 +360,8 @@ expressions. Turns off and disallows all access to shared memory objects. @item rvaluerefparam Implements rvalue arguments to @code{ref} parameters. -@item shortenedmethods -Implements use of @code{=>} for methods and top-level functions in addition to -lambdas. +@item systemvariables +Disables access to variables marked @code{@@system} from @code{@@safe} code. @end table @item -frelease diff --git a/gcc/d/lang.opt b/gcc/d/lang.opt index da652396468..15ab725a2dd 100644 --- a/gcc/d/lang.opt +++ b/gcc/d/lang.opt @@ -396,9 +396,9 @@ fpreview=rvaluerefparam D RejectNegative Enable rvalue arguments to ref parameters. -fpreview=shortenedmethods +fpreview=systemvariables D RejectNegative -Allow use of '=>' for methods and top-level functions in addition to lambdas. +Disable access to variables marked `@system' from @safe code. frelease D diff --git a/gcc/testsuite/gdc.dg/simd18867.d b/gcc/testsuite/gdc.dg/simd18867.d new file mode 100644 index 00000000000..295b0f84f7d --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd18867.d @@ -0,0 +1,11 @@ +// https://issues.dlang.org/show_bug.cgi?id=18867 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } +import core.simd; + +ulong2 test18867(ulong s) +{ + ulong2 v; + v[0] = s; + return v; +} diff --git a/gcc/testsuite/gdc.dg/simd19630.d b/gcc/testsuite/gdc.dg/simd19630.d index 0d45d28f47a..c29acfee735 100644 --- a/gcc/testsuite/gdc.dg/simd19630.d +++ b/gcc/testsuite/gdc.dg/simd19630.d @@ -3,19 +3,13 @@ // { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } import core.simd; -enum fail19630a = int4.init[1..2]; enum fail19630b = int4.init.array[1..2]; enum fail19630c = (cast(int[4])int4.init.array)[1..2]; enum fail19630d = (cast(int[4])int4.init)[1..2]; -enum fail19630e = int4(0)[1..2]; enum fail19630f = int4(0).array[1..2]; enum fail19630g = (cast(int[4])int4(0).array)[1..2]; enum fail19630h = (cast(int[4])int4(0))[1..2]; -enum int4 v19630a = int4.init; -enum slice19630a = v19630a[1..2]; -static assert(slice19630a == [0]); - enum int[4] v19630b = int4.init.array; enum slice19630b = v19630b[1..2]; static assert(slice19630b == [0]); @@ -28,10 +22,6 @@ enum int[4] v19630d = cast(int[4])int4.init; enum slice19630d = v19630d[1..2]; static assert(slice19630d == [0]); -enum int4 v19630e = int4(0); -enum slice19630e = v19630e[1..2]; -static assert(slice19630e == [0]); - enum int[4] v19630f = int4(0).array; enum slice19630f = v19630f[1..2]; static assert(slice19630f == [0]); diff --git a/gcc/testsuite/gdc.dg/simd19630b.d b/gcc/testsuite/gdc.dg/simd19630b.d new file mode 100644 index 00000000000..4f09597ffeb --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd19630b.d @@ -0,0 +1,17 @@ +// https://issues.dlang.org/show_bug.cgi?id=19630 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } +import core.simd; + +enum fail19630a = int4.init[1..2]; +// { dg-error "'__vector\\\(int\\\[4\\\]\\\)' cannot be sliced with '\\\[\\\]'" "" { target *-*-* } .-1 } +enum fail19630e = int4(0)[1..2]; +// { dg-error "'__vector\\\(int\\\[4\\\]\\\)' cannot be sliced with '\\\[\\\]'" "" { target *-*-* } .-1 } + +enum int4 v19630a = int4.init; +enum slice19630a = v19630a[1..2]; +// { dg-error "'__vector\\\(int\\\[4\\\]\\\)' cannot be sliced with '\\\[\\\]'" "" { target *-*-* } .-1 } + +enum int4 v19630e = int4(0); +enum slice19630e = v19630e[1..2]; +// { dg-error "'__vector\\\(int\\\[4\\\]\\\)' cannot be sliced with '\\\[\\\]'" "" { target *-*-* } .-1 } diff --git a/gcc/testsuite/gdc.dg/simd19630c.d b/gcc/testsuite/gdc.dg/simd19630c.d new file mode 100644 index 00000000000..d17cf1a0681 --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd19630c.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=19630 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } +import core.simd; + +int4 testz19630() +{ + return [0,0,0,0]; +} + +void test19630() +{ + assert(testz19630()[] == [0,0,0,0]); + // { dg-error "'__vector\\\(int\\\[4\\\]\\\)' cannot be sliced with '\\\[\\\]'" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/gdc.dg/simd19788.d b/gcc/testsuite/gdc.dg/simd19788.d new file mode 100644 index 00000000000..74ab0087a0e --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd19788.d @@ -0,0 +1,11 @@ +// https://issues.dlang.org/show_bug.cgi?id=19788 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } + +void test19788() +{ + enum v = __vector(float[4]).init; + const(float)[] a = v[]; + // { dg-error "'__vector\\\(float\\\[4\\\]\\\)' cannot be sliced with '\\\[\\\]'" "" { target *-*-* } .-1 } +} diff --git a/gcc/testsuite/gdc.dg/simd21469.d b/gcc/testsuite/gdc.dg/simd21469.d new file mode 100644 index 00000000000..9596f5ea0d2 --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd21469.d @@ -0,0 +1,9 @@ +// https://issues.dlang.org/show_bug.cgi?id=18867 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } +import core.simd; + +int4 test21469(short a) +{ + return cast(int4)(short8(a)); +} diff --git a/gcc/testsuite/gdc.dg/simd21672.d b/gcc/testsuite/gdc.dg/simd21672.d new file mode 100644 index 00000000000..c5bd1df8dbc --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd21672.d @@ -0,0 +1,17 @@ +// https://bugzilla.gdcproject.org/show_bug.cgi?id=213 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } + +import core.simd; + +struct S213 +{ + int4 vec; +} + +void test213() +{ + S213 s, b; + + assert(s == b); +} diff --git a/gcc/testsuite/gdc.dg/simd23077.d b/gcc/testsuite/gdc.dg/simd23077.d new file mode 100644 index 00000000000..150ec9f902e --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd23077.d @@ -0,0 +1,11 @@ +// https://issues.dlang.org/show_bug.cgi?id=23077 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } + +float test23077(float x) +{ + short i = *cast(short*)&x; + ++i; + return *cast(float*)&i; // this cast is not allowed in @safe code +} diff --git a/gcc/testsuite/gdc.dg/simd23084.d b/gcc/testsuite/gdc.dg/simd23084.d new file mode 100644 index 00000000000..1f40e3c99a8 --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd23084.d @@ -0,0 +1,17 @@ +// https://issues.dlang.org/show_bug.cgi?id=23084 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } +import core.simd; + +__vector(int[4]) test23084a(__vector(int[4]) a) +{ + __vector(short[8]) r = cast(short)(a.array[0]); + return cast(__vector(int[4]))r; +} + +__vector(int[4]) test23084b(__vector(int[4]) a) +{ + __vector(byte[16]) r = cast(byte)(a.array[0]); + return cast(__vector(int[4]))r; +} diff --git a/gcc/testsuite/gdc.dg/simd23085.d b/gcc/testsuite/gdc.dg/simd23085.d new file mode 100644 index 00000000000..66444addc0d --- /dev/null +++ b/gcc/testsuite/gdc.dg/simd23085.d @@ -0,0 +1,11 @@ +// https://issues.dlang.org/show_bug.cgi?id=23085 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } + +float test23085(float x) +{ + byte i = *cast(byte*)&x; + ++i; + return *cast(float*)&i; // this cast is not allowed in @safe code +} diff --git a/gcc/testsuite/gdc.dg/simd_ctfe.d b/gcc/testsuite/gdc.dg/simd_ctfe.d deleted file mode 100644 index 507de17baa2..00000000000 --- a/gcc/testsuite/gdc.dg/simd_ctfe.d +++ /dev/null @@ -1,88 +0,0 @@ -// { dg-additional-options "-mavx" { target avx_runtime } } -// { dg-do compile { target { avx_runtime || vect_sizes_16B_8B } } } -import core.simd; - -// https://issues.dlang.org/show_bug.cgi?id=19627 -enum int[4] fail19627 = cast(int[4])int4(0); - -// https://issues.dlang.org/show_bug.cgi?id=19628 -enum ice19628a = int4.init[0]; -enum ice19628b = int4.init.array[0]; -enum ice19628c = (cast(int[4])int4.init.array)[0]; -enum ice19628d = (cast(int[4])int4.init)[0]; - -// https://issues.dlang.org/show_bug.cgi?id=19629 -enum fail19629a = int4(0)[0]; -enum fail19629b = int4(0).array[0]; -enum fail19629c = (cast(int[4])int4(0).array)[0]; -enum fail19628d = (cast(int[4])int4(0))[0]; - -// https://issues.dlang.org/show_bug.cgi?id=19630 -enum fail19630a = int4.init[1..2]; -enum fail19630b = int4.init.array[1..2]; -enum fail19630c = (cast(int[4])int4.init.array)[1..2]; -enum fail19630d = int4(0)[1..2]; -enum fail19630e = int4(0).array[1..2]; -enum fail19630f = (cast(int[4])int4(0).array)[1..2]; -enum fail19630g = (cast(int[4])int4.init)[1..2]; -enum fail19630h = (cast(int[4])int4(0))[1..2]; - -// Same tests as above, but use access via enum. -enum int4 V1 = int4.init; -enum int[4] V2 = int4.init.array; -enum int[4] V3 = cast(int[4])int4.init; -enum int[4] V4 = cast(int[4])int4.init.array; -enum int4 V5 = int4(0); -enum int[4] V6 = int4(0).array; -enum int[4] V7 = cast(int[4])int4(0); -enum int[4] V8 = cast(int[4])int4(0).array; - -// CTFE index tests -enum I1 = V1[0]; static assert(I1 == 0); -enum I2 = V2[0]; static assert(I2 == 0); -enum I3 = V3[0]; static assert(I3 == 0); -enum I4 = V4[0]; static assert(I4 == 0); -enum I5 = V5[0]; static assert(I5 == 0); -enum I6 = V6[0]; static assert(I6 == 0); -enum I7 = V7[0]; static assert(I7 == 0); -enum I8 = V8[0]; static assert(I8 == 0); - -// CTFE slice tests -enum S1 = V1[1..2]; static assert(S1 == [0]); -enum S2 = V2[1..2]; static assert(S2 == [0]); -enum S3 = V3[1..2]; static assert(S3 == [0]); -enum S4 = V4[1..2]; static assert(S4 == [0]); -enum S5 = V5[1..2]; static assert(S5 == [0]); -enum S6 = V6[1..2]; static assert(S6 == [0]); -enum S7 = V7[1..2]; static assert(S7 == [0]); -enum S8 = V8[1..2]; static assert(S8 == [0]); - -// Same tests as above, but use access via immutable. -//immutable int4 v1 = int4.init; // Cannot cast to immutable at compile time -immutable int[4] v2 = int4.init.array; -immutable int[4] v3 = cast(int[4])int4.init; -immutable int[4] v4 = cast(int[4])int4.init.array; -//immutable int4 v5 = int4(0); // Cannot cast to immutable at compile time -immutable int[4] v6 = int4(0).array; -immutable int[4] v7 = cast(int[4])int4(0); -immutable int[4] v8 = cast(int[4])int4(0).array; - -// CTFE index tests -//immutable i1 = v1[0]; static assert(i1 == 0); -immutable i2 = v2[0]; static assert(i2 == 0); -immutable i3 = v3[0]; static assert(i3 == 0); -immutable i4 = v4[0]; static assert(i4 == 0); -//immutable i5 = v5[0]; static assert(i5 == 0); -immutable i6 = v6[0]; static assert(i6 == 0); -immutable i7 = v7[0]; static assert(i7 == 0); -immutable i8 = v8[0]; static assert(i8 == 0); - -// CTFE slice tests -//immutable s1 = v1[1..2]; static assert(s1 == [0]); -immutable s2 = v2[1..2]; static assert(s2 == [0]); -immutable s3 = v3[1..2]; static assert(s3 == [0]); -immutable s4 = v4[1..2]; static assert(s4 == [0]); -//immutable s5 = v5[1..2]; static assert(s5 == [0]); -immutable s6 = v6[1..2]; static assert(s6 == [0]); -immutable s7 = v7[1..2]; static assert(s7 == [0]); -immutable s8 = v8[1..2]; static assert(s8 == [0]); diff --git a/gcc/testsuite/gdc.dg/torture/simd19632.d b/gcc/testsuite/gdc.dg/torture/simd19632.d new file mode 100644 index 00000000000..e74a3e82db1 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd19632.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=19632 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do run { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } +import core.simd; + +void main() +{ + int4 v = [1, 2, 3, 4]; + int sum = 0; + foreach (ref e; v) + sum += (e *= 2); + assert(v.array[] == [2, 4, 6, 8]); + assert(sum == 20); +} diff --git a/gcc/testsuite/gdc.dg/torture/simd20041.d b/gcc/testsuite/gdc.dg/torture/simd20041.d new file mode 100644 index 00000000000..a74f58a2a2f --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd20041.d @@ -0,0 +1,22 @@ +// https://issues.dlang.org/show_bug.cgi?id=20041 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do run { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } +import core.simd; + +immutable(float4) test20041() +{ + float4 raw = 2.0f; + raw.array[0] = 1; + return cast(immutable)raw; +} + +void main() +{ + static immutable float4 v = test20041(); + + assert(v.array[0] == 1); + assert(v.array[1] == 2); + assert(v.array[2] == 2); + assert(v.array[3] == 2); +} diff --git a/gcc/testsuite/gdc.dg/torture/simd21673.d b/gcc/testsuite/gdc.dg/torture/simd21673.d new file mode 100644 index 00000000000..701e33a30a8 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd21673.d @@ -0,0 +1,20 @@ +// https://issues.dlang.org/show_bug.cgi?id=21673 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do run { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } +import core.simd; + +float4 _mm_move_ss(float4 a, float4 b) +{ + a.ptr[0] = b.array[0]; + return a; +} + +void main() +{ + float4 A = [1.0f, 2.0f, 3.0f, 4.0f]; + float4 B = [5.0f, 6.0f, 7.0f, 8.0f]; + float4 R = _mm_move_ss(A, B); + float[4] correct = [5.0f, 2.0f, 3.0f, 4.0f]; + assert(R.array == correct); +} diff --git a/gcc/testsuite/gdc.dg/torture/simd21676.d b/gcc/testsuite/gdc.dg/torture/simd21676.d new file mode 100644 index 00000000000..1d7b9117a90 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd21676.d @@ -0,0 +1,36 @@ +// https://issues.dlang.org/show_bug.cgi?id=23009 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do run { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } +import core.simd; + +double2 loadUnaligned21676(const(double)* pvec) +{ + double2 result; + foreach(i; 0..2) + { + result[i] = pvec[i]; + } + return result; +} + +double2 _mm_setr_pd(double e1, double e0) +{ + double[2] result = [e1, e0]; + return loadUnaligned21676(result.ptr); +} + +double2 fun(double2 a, double2 b) +{ + a[0] = (a[0] < b[0]) ? a[0] : b[0]; + return a; +} + +void main() +{ + double2 A = _mm_setr_pd(1.0, 2.0); + double2 B = _mm_setr_pd(4.0, 1.0); + double2 C = fun(A, B); + assert(C.array[0] == 1.0); + assert(C.array[1] == 2.0); +} diff --git a/gcc/testsuite/gdc.dg/torture/simd22438.d b/gcc/testsuite/gdc.dg/torture/simd22438.d new file mode 100644 index 00000000000..9199be67e13 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd22438.d @@ -0,0 +1,18 @@ +// https://issues.dlang.org/show_bug.cgi?id=22438 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do run } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } + +struct T22438 { int x; double d; } + +T22438 foo22438(int x, double d) { return T22438(x, d); } + +struct S22438 { T22438 t; string r; } + +void main() +{ + S22438 s = S22438(foo22438(10, 3.14), "str"); + assert(s.t.x == 10); + assert(s.t.d == 3.14); + assert(s.r == "str"); +} diff --git a/gcc/testsuite/gdc.dg/torture/simd23009.d b/gcc/testsuite/gdc.dg/torture/simd23009.d new file mode 100644 index 00000000000..a45ec4d9a9c --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd23009.d @@ -0,0 +1,22 @@ +// https://issues.dlang.org/show_bug.cgi?id=23009 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do run { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } +import core.simd; + +double2 _mm_loadl_pd(double2 a, const(double)* mem_addr) +{ + a[0] = *mem_addr; + return a; +} + +void main() +{ + double A = 7.0; + double2 B; + B[0] = 4.0; + B[1] = -5.0; + double2 R = _mm_loadl_pd(B, &A); + double[2] correct = [ 7.0, -5.0 ]; + assert(R.array == correct); +} diff --git a/gcc/testsuite/gdc.dg/torture/simd23077.d b/gcc/testsuite/gdc.dg/torture/simd23077.d new file mode 100644 index 00000000000..150ec9f902e --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd23077.d @@ -0,0 +1,11 @@ +// https://issues.dlang.org/show_bug.cgi?id=23077 +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do compile } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } + +float test23077(float x) +{ + short i = *cast(short*)&x; + ++i; + return *cast(float*)&i; // this cast is not allowed in @safe code +} diff --git a/gcc/testsuite/gdc.dg/torture/simd8.d b/gcc/testsuite/gdc.dg/torture/simd8.d new file mode 100644 index 00000000000..3847732382b --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd8.d @@ -0,0 +1,26 @@ +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do run { target { avx_runtime || vect_sizes_16B_8B } } } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } +import gcc.simd; + +alias __m128 = __vector(float[4]); + +__m128 _mm_setr_ps (float e3, float e2, float e1, float e0) pure @trusted +{ + float[4] result = [e3, e2, e1, e0]; + return loadUnaligned!(__m128)(cast(__m128*)result.ptr); +} + +__m128 _mm_movehdup_ps (__m128 a) pure @trusted +{ + a.ptr[0] = a.array[1]; + a.ptr[2] = a.array[3]; + return a; +} + +void main() +{ + __m128 A = _mm_movehdup_ps(_mm_setr_ps(1, 2, 3, 4)); + float[4] correct = [2.0f, 2, 4, 4 ]; + assert(A.array == correct); +} diff --git a/gcc/testsuite/gdc.dg/torture/simd9.d b/gcc/testsuite/gdc.dg/torture/simd9.d new file mode 100644 index 00000000000..06535311b53 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd9.d @@ -0,0 +1,46 @@ +// { dg-additional-options "-mavx" { target avx_runtime } } +// { dg-do run } +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } + +__gshared int testsroa_x; + +template SROA(T1, T2) +{ + struct FPoint + { + T1 x; + T2 y; + } + + void sroa(FPoint p1, ref FPoint quad) + { + quad = FPoint(p1.x, p1.y); + } + + void testit() + { + FPoint p1 = FPoint(1, 2); + + FPoint quad; + sroa(p1, quad); + + if (quad != p1) + { + assert(0); + } + ++testsroa_x; + } +} + +void main() +{ + SROA!(int, int ).testit(); + SROA!(int, float).testit(); + SROA!(float, float).testit(); + SROA!(float, int ).testit(); + + SROA!(long, long ).testit(); + SROA!(long, double).testit(); + SROA!(double, double).testit(); + SROA!(double, long ).testit(); +} diff --git a/gcc/testsuite/gdc.dg/torture/simd_prefetch.d b/gcc/testsuite/gdc.dg/torture/simd_prefetch.d new file mode 100644 index 00000000000..1778476bbe7 --- /dev/null +++ b/gcc/testsuite/gdc.dg/torture/simd_prefetch.d @@ -0,0 +1,21 @@ +// { dg-skip-if "needs gcc/config.d" { ! d_runtime } } +import gcc.simd; + +int testprefetch(byte a) +{ + prefetch!(false, 0)(&a); + prefetch!(false, 1)(&a); + prefetch!(false, 2)(&a); + prefetch!(false, 3)(&a); + prefetch!(true, 0)(&a); + prefetch!(true, 1)(&a); + prefetch!(true, 2)(&a); + prefetch!(true, 3)(&a); + return 3; +} + +void main() +{ + int i = testprefetch(1); + assert(i == 3); +} diff --git a/gcc/testsuite/gdc.test/compilable/cdcmp.d b/gcc/testsuite/gdc.test/compilable/cdcmp.d index 305f097bd81..16abde0bd5b 100644 --- a/gcc/testsuite/gdc.test/compilable/cdcmp.d +++ b/gcc/testsuite/gdc.test/compilable/cdcmp.d @@ -60,20 +60,6 @@ bool test_nez(long x) { return x != 0; } bool test_gez(long x) { return x >= 0; } bool test_gtz(long x) { return x > 0; } -bool test_ltz(float x) { return x < 0; } -bool test_lez(float x) { return x <= 0; } -bool test_eqz(float x) { return x == 0; } -bool test_nez(float x) { return x != 0; } -bool test_gez(float x) { return x >= 0; } -bool test_gtz(float x) { return x > 0; } - -bool test_ltz(double x) { return x < 0; } -bool test_lez(double x) { return x <= 0; } -bool test_eqz(double x) { return x == 0; } -bool test_nez(double x) { return x != 0; } -bool test_gez(double x) { return x >= 0; } -bool test_gtz(double x) { return x > 0; } - /* ----------------------------------- */ bool test_lt(ubyte x, ubyte y) { return x < y; } diff --git a/gcc/testsuite/gdc.test/compilable/extra-files/header2.d b/gcc/testsuite/gdc.test/compilable/extra-files/header2.d index 7dc4659165d..7c011d2f712 100644 --- a/gcc/testsuite/gdc.test/compilable/extra-files/header2.d +++ b/gcc/testsuite/gdc.test/compilable/extra-files/header2.d @@ -162,6 +162,18 @@ align(2) struct S12200_2 align(1): } +// https://issues.dlang.org/show_bug.cgi?id=14694 +inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure nothrow +{ + alias U = inout(T); + static U* max(U* a, U* b) nothrow { return a > b ? a : b; } + static U* min(U* a, U* b) nothrow { return a < b ? a : b; } + + auto b = max(r1.ptr, r2.ptr); + auto e = min(r1.ptr + r1.length, r2.ptr + r2.length); + return b < e ? b[0 .. e - b] : null; +} + // https://issues.dlang.org/show_bug.cgi?id=16140 void gun()() { @@ -173,6 +185,13 @@ void gun()() else break; } +// https://issues.dlang.org/show_bug.cgi?id=14690 +pragma(inline, true) +int fun(int a, int b) +{ + return 3; +} + // https://issues.dlang.org/show_bug.cgi?id=16649 void leFoo()() { diff --git a/gcc/testsuite/gdc.test/compilable/imports/cimports2a.i b/gcc/testsuite/gdc.test/compilable/imports/cimports2a.i index c8ff97644c3..0d001e809ca 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/cimports2a.i +++ b/gcc/testsuite/gdc.test/compilable/imports/cimports2a.i @@ -2,3 +2,10 @@ extern int xx; typedef struct Foo *FooRef; FooRef make_foo(void); + + +typedef struct Foo2 *FooRef2; +struct Foo2 { + int x; +}; +FooRef2 make_foo2(void); diff --git a/gcc/testsuite/gdc.test/compilable/imports/cimports2b.i b/gcc/testsuite/gdc.test/compilable/imports/cimports2b.i index 03b22b2a216..a0a9c2f3a41 100644 --- a/gcc/testsuite/gdc.test/compilable/imports/cimports2b.i +++ b/gcc/testsuite/gdc.test/compilable/imports/cimports2b.i @@ -2,3 +2,11 @@ extern int xx; typedef struct Foo *FooRef; void free_foo(FooRef foo); + +/****************************/ + +typedef struct Foo2 *FooRef2; +struct Foo2 { + int x; +}; +void free_foo2(FooRef2 foo); diff --git a/gcc/testsuite/gdc.test/compilable/imports/pkg22952/package.d b/gcc/testsuite/gdc.test/compilable/imports/pkg22952/package.d new file mode 100644 index 00000000000..1a804d9277e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/pkg22952/package.d @@ -0,0 +1 @@ +module lib; diff --git a/gcc/testsuite/gdc.test/compilable/noreturn3.d b/gcc/testsuite/gdc.test/compilable/noreturn3.d new file mode 100644 index 00000000000..737125d1322 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/noreturn3.d @@ -0,0 +1,257 @@ +/* +REQUIRED_ARGS: -w -o- -d + +More complex examples from the DIP +https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1034.md +*/ + +alias noreturn = typeof(*null); +static assert (!is(noreturn == void)); + +void initialize() +{ + noreturn a; + noreturn b = noreturn.init; +} + +void foo(const noreturn); +void foo(const int); + +noreturn bar(); + +void overloads() +{ + noreturn n; + foo(n); + + foo(bar()); +} + +// /*****************************************************************************/ + +auto inferNoreturn(int i) +{ + if (i < 0) + return assert(false); + else if (i == 0) + return assert(false); + else + return assert(false); +} + +auto inferReturn(int i) +{ + if (i < 0) + return assert(false); + else if (i == 0) + return i; + else + return assert(false); +} + +// /*****************************************************************************/ +// // https://issues.dlang.org/show_bug.cgi?id=22004 + +alias fun22004 = _ => {}(); +alias gun22004 = _ => assert(0); +auto bun22004(bool b) +{ + if (b) + return gun22004(0); + else + return fun22004(0); +} + +static assert(is(typeof(bun22004(true)) == void)); + +// // Reversed order +auto bun22004_reversed(bool b) +{ + if (b) + return fun22004(0); + else + return gun22004(0); +} + +static assert(is(typeof(bun22004_reversed(true)) == void)); + +// /*****************************************************************************/ + +// // Also works fine with non-void types and ref inference + +int global; + +auto ref forwardOrExit(ref int num) +{ + if (num) + return num; + else + return assert(false); +} + +static assert( is(typeof(forwardOrExit(global)) == int)); + +// // Must not infer ref due to the noreturn rvalue +static assert(!is(typeof(&forwardOrExit(global)))); + +auto ref forwardOrExit2(ref int num) +{ + if (num) + return assert(false); + else + return num; +} + +static assert( is(typeof(forwardOrExit2(global)) == int)); + +// // Must not infer ref due to the noreturn rvalue +static assert(!is(typeof(&forwardOrExit2(global)))); + +/*****************************************************************************/ + +void inference() +{ + auto inf = cast(noreturn) 1; + static assert(is(typeof(inf) == noreturn)); + + noreturn n; + auto c = cast(const shared noreturn) n; + static assert(is(typeof(c) == const shared noreturn)); + static assert(is(typeof(n) == noreturn)); + + auto c2 = cast(immutable noreturn) n; + static assert(is(typeof(c) == const shared noreturn)); + static assert(is(typeof(c2) == immutable noreturn)); + static assert(is(typeof(n) == noreturn)); +} + + +/******************************************************************************/ +// https://issues.dlang.org/show_bug.cgi?id=21957 +// Calculate proper alignment and size for noreturn members + +enum longPad = long.alignof - int.sizeof; + +struct BasicStruct +{ + int firstInt; + noreturn noRet; + long lastLong; +} + +static assert(BasicStruct.sizeof == (int.sizeof + longPad + long.sizeof)); + +static assert(BasicStruct.firstInt.offsetof == 0); +static assert(BasicStruct.noRet.offsetof == 4); +static assert(BasicStruct.lastLong.offsetof == (4 + longPad)); + +struct AlignedStruct +{ + int firstInt; + align(16) noreturn noRet; + long lastLong; +} + +static assert(AlignedStruct.sizeof == 32); + +static assert(AlignedStruct.firstInt.offsetof == 0); +static assert(AlignedStruct.noRet.offsetof == 16); +static assert(AlignedStruct.lastLong.offsetof == 16); + +union BasicUnion +{ + int firstInt; + noreturn noRet; + long lastLong; +} + +static assert(BasicUnion.sizeof == 8); + +static assert(BasicUnion.firstInt.offsetof == 0); +static assert(BasicUnion.noRet.offsetof == 0); +static assert(BasicUnion.lastLong.offsetof == 0); + +union AlignedUnion +{ + int firstInt; + align(16) noreturn noRet; + long lastLong; +} + +static assert(AlignedUnion.sizeof == 16); + +static assert(AlignedUnion.firstInt.offsetof == 0); +static assert(AlignedUnion.noRet.offsetof == 0); +static assert(AlignedUnion.lastLong.offsetof == 0); + +class BasicClass +{ + int firstInt; + noreturn noRet; + long lastLong; +} + +enum objectMemberSize = __traits(classInstanceSize, Object); + +static assert(__traits(classInstanceSize, BasicClass) == objectMemberSize + (int.sizeof + longPad + long.sizeof)); + +static assert(BasicClass.firstInt.offsetof == objectMemberSize + 0); +static assert(BasicClass.noRet.offsetof == objectMemberSize + 4); +static assert(BasicClass.lastLong.offsetof == objectMemberSize + (4 + longPad)); + +class AlignedClass +{ + int firstInt; + align(16) noreturn noRet; + long lastLong; +} + +enum offset = (objectMemberSize + 4 + 16) & ~15; + +static assert(__traits(classInstanceSize, AlignedClass) == offset + 8); + +static assert(AlignedClass.firstInt.offsetof == objectMemberSize + 0); +static assert(AlignedClass.noRet.offsetof == offset); +static assert(AlignedClass.lastLong.offsetof == offset); + +struct EmptyStruct +{ + noreturn noRet; +} + +static assert(EmptyStruct.sizeof == 1); +static assert(EmptyStruct.noRet.offsetof == 0); + +struct EmptyStruct2 +{ + noreturn[4] noRet; +} + +static assert(EmptyStruct2.sizeof == 1); +static assert(EmptyStruct2.noRet.offsetof == 0); + +// https://issues.dlang.org/show_bug.cgi?id=22858 +// Shouldn't mess with the alignment of other zero-sized types. + +struct S22858 +{ + int a; + void*[0] arr; + char c; + noreturn[0] arr2; + char c2; +} + +static assert (S22858.arr.offsetof % size_t.sizeof == 0); +static assert (S22858.arr2.offsetof == S22858.c.offsetof + 1); +static assert (S22858.arr2.offsetof == S22858.c2.offsetof); + +// https://issues.dlang.org/show_bug.cgi?id=23331 + +auto fun() { return double(new noreturn[](0)[0]); } +auto gun() { return double(assert(0)); } +auto hun() { return int(assert(0)); } + +// https://issues.dlang.org/show_bug.cgi?id=23379 + +void casting_noreturn() { auto b = cast(double)(assert(0)); } diff --git a/gcc/testsuite/gdc.test/compilable/scope_tuple_expansion.d b/gcc/testsuite/gdc.test/compilable/scope_tuple_expansion.d new file mode 100644 index 00000000000..cac180caaaf --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/scope_tuple_expansion.d @@ -0,0 +1,21 @@ +// REQUIRED_ARGS: -preview=dip1000 + +// Reduced from `std.systime`. +// Tuple expansion can trip up scope checking with errors like: +// Error: scope variable `__tup4` assigned to `found` with longer lifetime + +struct Tuple(T...) +{ + T t; + alias t this; +} + +Tuple!(int*, int) find(return scope int* x) @safe +{ + assert(0); +} + +void fromISOExtString(scope int* str) @safe +{ + int* found = str.find()[0]; +} diff --git a/gcc/testsuite/gdc.test/compilable/shortened_methods.d b/gcc/testsuite/gdc.test/compilable/shortened_methods.d index 5a7ac8749d8..71350af8739 100644 --- a/gcc/testsuite/gdc.test/compilable/shortened_methods.d +++ b/gcc/testsuite/gdc.test/compilable/shortened_methods.d @@ -1,4 +1,4 @@ -// REQUIRED_ARGS: -preview=shortenedMethods +// N.B. Shortened methods are no longer under a preview flag class A { int _x = 34; // short syntax works in all contexts diff --git a/gcc/testsuite/gdc.test/compilable/test11980.d b/gcc/testsuite/gdc.test/compilable/test11980.d index 27974e42451..29ec7a18a2c 100644 --- a/gcc/testsuite/gdc.test/compilable/test11980.d +++ b/gcc/testsuite/gdc.test/compilable/test11980.d @@ -1,2 +1,5 @@ -void start() {} +void start() +{ + pragma(startaddress, start); +} pragma(startaddress, start); diff --git a/gcc/testsuite/gdc.test/compilable/test22674.d b/gcc/testsuite/gdc.test/compilable/test22674.d index cc6e3bb2d07..00750b0108f 100644 --- a/gcc/testsuite/gdc.test/compilable/test22674.d +++ b/gcc/testsuite/gdc.test/compilable/test22674.d @@ -8,3 +8,10 @@ void do_foo(){ FooRef f = make_foo(); // use_foo.d(5) free_foo(f); // use_foo.d(6) } + +// https://issues.dlang.org/show_bug.cgi?id=23357 + +void do_foo2(){ + FooRef2 f = make_foo2(); + free_foo2(f); +} diff --git a/gcc/testsuite/gdc.test/compilable/test22784.d b/gcc/testsuite/gdc.test/compilable/test22784.d new file mode 100644 index 00000000000..1709be4059c --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22784.d @@ -0,0 +1,10 @@ +// Issue 22784 - pragma(printf) applies to nested functions +// https://issues.dlang.org/show_bug.cgi?id=22784 + +import core.stdc.stdarg; +extern(C) +pragma(printf) +void fn(const(char)* fmt, ...) +{ + void inner(){} +} diff --git a/gcc/testsuite/gdc.test/compilable/test22952.d b/gcc/testsuite/gdc.test/compilable/test22952.d new file mode 100644 index 00000000000..d0524b14b57 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22952.d @@ -0,0 +1,10 @@ +/* +REQUIRED_ARGS: -Icompilable/imports -mv=lib=pkg22952 +EXTRA_FILES: imports/pkg22952/package.d +*/ + +// Issue 22952 - Compiler fails to find package.d modules via -mv map +// https://issues.dlang.org/show_bug.cgi?id=22952 + +module test22952; +import lib; diff --git a/gcc/testsuite/gdc.test/compilable/test23380.d b/gcc/testsuite/gdc.test/compilable/test23380.d new file mode 100644 index 00000000000..bf82604a752 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23380.d @@ -0,0 +1,9 @@ +// REQUIRED_ARGS: -preview=dip1000 + +// https://issues.dlang.org/show_bug.cgi?id=23380 +// Issue 23380 - [dip1000] class parameter should not be treated as ref qua lifetime + +@safe void test(scope Object o0, scope Object o1) +{ + o1 = o0; +} diff --git a/gcc/testsuite/gdc.test/compilable/test23386.d b/gcc/testsuite/gdc.test/compilable/test23386.d new file mode 100644 index 00000000000..dc1d75411ed --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23386.d @@ -0,0 +1,12 @@ +// https://issues.dlang.org/show_bug.cgi?id=23386 +// Segfault on enum member UDA inside template + +template E() +{ + enum E : byte + { + @(1) none, + } +} + +alias T = E!(); diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag23384.d b/gcc/testsuite/gdc.test/fail_compilation/diag23384.d new file mode 100644 index 00000000000..1fa4da5ffb9 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/diag23384.d @@ -0,0 +1,29 @@ +// https://issues.dlang.org/show_bug.cgi?id=23384 + +/* +TEST_OUTPUT: +--- +fail_compilation/diag23384.d(28): Error: function `diag23384.Derived.fun(B b)` is not callable using argument types `(A)` +fail_compilation/diag23384.d(28): function `diag23384.Derived.fun` hides base class function `diag23384.Base.fun` +fail_compilation/diag23384.d(28): add `alias fun = diag23384.Base.fun` to `diag23384.Derived`'s body to merge the overload sets +--- +*/ + +struct A {} +struct B {} + +class Base +{ + void fun(A a) {} +} + +class Derived : Base +{ + void fun(B b) {} +} + +void main() +{ + Derived d; + d.fun(A()); +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10905.d b/gcc/testsuite/gdc.test/fail_compilation/fail10905.d deleted file mode 100644 index 52b5285b83b..00000000000 --- a/gcc/testsuite/gdc.test/fail_compilation/fail10905.d +++ /dev/null @@ -1,22 +0,0 @@ -/* -REQUIRED_ARGS: -m64 -TEST_OUTPUT: ---- -fail_compilation/fail10905.d(20): Error: incompatible types for `(this.x) == (cast(const(__vector(long[2])))cast(__vector(long[2]))1L)`: both operands are of type `const(__vector(long[2]))` ---- -*/ - -struct Foo -{ - enum __vector(long[2]) y = 1; -} - -struct Bar -{ - __vector(long[2]) x; - - bool spam() const - { - return x == Foo.y; - } -} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d b/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d index ccdbb570817..e23ed04305f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d @@ -2,7 +2,7 @@ REQUIRED_ARGS: -m64 TEST_OUTPUT: --- -fail_compilation/fail19898a.d(10): Error: incompatible types for `(__key2) < (__limit3)`: both operands are of type `__vector(int[4])` +fail_compilation/fail19898a.d(10): Error: expression `__key2 < __limit3` of type `__vector(int[4])` does not have a boolean value --- */ void f (__vector(int[4]) n) diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d b/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d index 254c2cad028..5101da5617b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d @@ -3,7 +3,7 @@ REQUIRED_ARGS: -m64 TEST_OUTPUT: --- fail_compilation/fail19898b.d(17): Error: cannot implicitly convert expression `m` of type `S` to `__vector(int[4])` -fail_compilation/fail19898b.d(17): Error: incompatible types for `(__key2) != (__limit3)`: both operands are of type `__vector(int[4])` +fail_compilation/fail19898b.d(17): Error: expression `__key2 != __limit3` of type `__vector(int[4])` does not have a boolean value fail_compilation/fail19898b.d(17): Error: cannot cast expression `__key2` of type `__vector(int[4])` to `S` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22366.d b/gcc/testsuite/gdc.test/fail_compilation/fail22366.d index 3a2469f5fe1..6960d5e41d8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail22366.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22366.d @@ -3,7 +3,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail22366.d(13): Error: scope variable `__aaval2` assigned to non-scope `aa[0]` +fail_compilation/fail22366.d(13): Error: scope variable `x` may not be copied into allocated memory --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail23406.d b/gcc/testsuite/gdc.test/fail_compilation/fail23406.d new file mode 100644 index 00000000000..8ac3f147e58 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail23406.d @@ -0,0 +1,40 @@ +// https://issues.dlang.org/show_bug.cgi?id=23406 + +/* +TEST_OUTPUT: +--- +fail_compilation/fail23406.d(39): Error: cannot implicitly convert expression `0` of type `int` to `alphakey` +--- +*/ + +struct flagenum +{ + int i = 1; + alias i this; + + auto opBinary(string s)(int j) + { + assert(j == 1); + return typeof(this)(i*2); + } + + auto opEquals(int a) + { + return false; + } +} + +enum alphakey +{ + a = flagenum(), + b,c,d,e,f,g,h,i, + k,l,m,n,o,p,q,r, + s,t,u,v,w,x,y,z +} + +alphakey alpha; + +void main() +{ + alpha = 0; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/issue21378.d b/gcc/testsuite/gdc.test/fail_compilation/issue21378.d index 22c60a37a4c..172110a0ab0 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/issue21378.d +++ b/gcc/testsuite/gdc.test/fail_compilation/issue21378.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/issue21378.d(13): Error: function `issue21378.fn` circular dependency. Functions cannot be interpreted while being compiled fail_compilation/issue21378.d(12): called from here: `fn()` -fail_compilation/issue21378.d(12): Error: pragma `inline` pragma(`inline`, `true` or `false`) expected, not `fn()` +fail_compilation/issue21378.d(12): Error: pragma(`inline`, `true` or `false`) expected, not `fn()` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/lexer1.d b/gcc/testsuite/gdc.test/fail_compilation/lexer1.d index e6cabf2f26a..0ad3f01156a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/lexer1.d +++ b/gcc/testsuite/gdc.test/fail_compilation/lexer1.d @@ -23,9 +23,9 @@ fail_compilation/lexer1.d(49): Error: unterminated named entity &*; fail_compilation/lexer1.d(50): Error: unterminated named entity &s1"; fail_compilation/lexer1.d(51): Error: unterminated named entity &2; fail_compilation/lexer1.d(52): Error: escape octal sequence \400 is larger than \377 +fail_compilation/lexer1.d(53): Error: html entity requires 2 code units, use a string instead of a character --- */ - // https://dlang.dawg.eu/coverage/src/lexer.c.gcov.html x"01 02 03"w; 0x80000001; @@ -50,3 +50,4 @@ static s5 = "\&*"; static s6 = "\&s1"; static s7 = "\&2;"; static s7 = "\400;"; +dchar s8 = '\∾̳'; diff --git a/gcc/testsuite/gdc.test/fail_compilation/pragmainline.d b/gcc/testsuite/gdc.test/fail_compilation/pragmainline.d index 5d432770087..23f3bfef82e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/pragmainline.d +++ b/gcc/testsuite/gdc.test/fail_compilation/pragmainline.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/pragmainline.d(8): Error: pragma `inline` one boolean expression expected for `pragma(inline)`, not 3 +fail_compilation/pragmainline.d(8): Error: one boolean expression expected for `pragma(inline)`, not 3 --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/pragmas.d b/gcc/testsuite/gdc.test/fail_compilation/pragmas.d index cd56ff4d470..5a4b5d95d07 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/pragmas.d +++ b/gcc/testsuite/gdc.test/fail_compilation/pragmas.d @@ -3,8 +3,8 @@ /* TEST_OUTPUT: --- -fail_compilation/pragmas.d(103): Error: boolean expression expected for `pragma(inline)` -fail_compilation/pragmas.d(108): Error: boolean expression expected for `pragma(inline)` +fail_compilation/pragmas.d(103): Error: one boolean expression expected for `pragma(inline)`, not 2 +fail_compilation/pragmas.d(108): Error: one boolean expression expected for `pragma(inline)`, not 2 fail_compilation/pragmas.d(118): Error: unrecognized `pragma(unrecognized)` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/previewin.d b/gcc/testsuite/gdc.test/fail_compilation/previewin.d index ce0cf926a13..ca540930129 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/previewin.d +++ b/gcc/testsuite/gdc.test/fail_compilation/previewin.d @@ -8,10 +8,10 @@ fail_compilation/previewin.d(5): Error: function `previewin.takeFunction(void fu fail_compilation/previewin.d(5): cannot pass argument `__lambda2` of type `void function(const(real) x) pure nothrow @nogc @safe` to parameter `void function(in real) f` fail_compilation/previewin.d(6): Error: function `previewin.takeFunction(void function(in real) f)` is not callable using argument types `(void function(ref const(real) x) pure nothrow @nogc @safe)` fail_compilation/previewin.d(6): cannot pass argument `__lambda3` of type `void function(ref const(real) x) pure nothrow @nogc @safe` to parameter `void function(in real) f` -fail_compilation/previewin.d(15): Error: scope variable `arg` assigned to non-scope `myGlobal` -fail_compilation/previewin.d(16): Error: scope variable `arg` assigned to non-scope `myGlobal` +fail_compilation/previewin.d(15): Error: scope variable `arg` assigned to global variable `myGlobal` +fail_compilation/previewin.d(16): Error: scope variable `arg` assigned to global variable `myGlobal` fail_compilation/previewin.d(17): Error: scope parameter `arg` may not be returned -fail_compilation/previewin.d(18): Error: scope variable `arg` assigned to `escape` with longer lifetime +fail_compilation/previewin.d(18): Error: scope variable `arg` assigned to `ref` variable `escape` with longer lifetime fail_compilation/previewin.d(22): Error: returning `arg` escapes a reference to parameter `arg` fail_compilation/previewin.d(22): perhaps annotate the parameter with `return` --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d index 6e7e909b5c7..29f96ece787 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d +++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d @@ -117,6 +117,7 @@ fail_compilation/reserved_version.d(218): Error: version identifier `D_PreCondit fail_compilation/reserved_version.d(219): Error: version identifier `D_PostConditions` is reserved and cannot be set fail_compilation/reserved_version.d(220): Error: version identifier `D_ProfileGC` is reserved and cannot be set fail_compilation/reserved_version.d(221): Error: version identifier `D_Invariants` is reserved and cannot be set +fail_compilation/reserved_version.d(222): Error: version identifier `D_Optimized` is reserved and cannot be set --- */ @@ -240,6 +241,7 @@ version = D_PreConditions; version = D_PostConditions; version = D_ProfileGC; version = D_Invariants; +version = D_Optimized; // This should work though debug = DigitalMars; @@ -351,3 +353,4 @@ debug = AVR; debug = D_PreConditions; debug = D_PostConditions; debug = D_ProfileGC; +debug = D_Optimized; diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d index cd85b41a82b..f5f6b1c9acd 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d +++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d @@ -107,6 +107,7 @@ // REQUIRED_ARGS: -version=D_PostConditions // REQUIRED_ARGS: -version=D_ProfileGC // REQUIRED_ARGS: -version=D_Invariants +// REQUIRED_ARGS: -version=D_Optimized // REQUIRED_ARGS: -debug=DigitalMars // REQUIRED_ARGS: -debug=GNU // REQUIRED_ARGS: -debug=LDC @@ -211,6 +212,7 @@ // REQUIRED_ARGS: -debug=D_PostConditions // REQUIRED_ARGS: -debug=D_ProfileGC // REQUIRED_ARGS: -debug=D_Invariants +// REQUIRED_ARGS: -debug=D_Optimized /* TEST_OUTPUT: --- @@ -321,5 +323,6 @@ Error: version identifier `D_PreConditions` is reserved and cannot be set Error: version identifier `D_PostConditions` is reserved and cannot be set Error: version identifier `D_ProfileGC` is reserved and cannot be set Error: version identifier `D_Invariants` is reserved and cannot be set +Error: version identifier `D_Optimized` is reserved and cannot be set --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope.d b/gcc/testsuite/gdc.test/fail_compilation/retscope.d index 2a69fe04f84..ece6a8cf62e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope.d @@ -4,9 +4,9 @@ TEST_OUTPUT: --- fail_compilation/retscope.d(22): Error: scope parameter `p` may not be returned fail_compilation/retscope.d(32): Error: returning `b ? nested1(& i) : nested2(& j)` escapes a reference to local variable `j` -fail_compilation/retscope.d(45): Error: scope variable `p` assigned to non-scope `q` +fail_compilation/retscope.d(45): Error: scope variable `p` assigned to global variable `q` fail_compilation/retscope.d(47): Error: address of variable `i` assigned to `q` with longer lifetime -fail_compilation/retscope.d(48): Error: scope variable `a` assigned to non-scope `b` +fail_compilation/retscope.d(48): Error: scope variable `a` assigned to global variable `b` fail_compilation/retscope.d(49): Error: address of struct temporary returned by `(*fp2)()` assigned to longer lived variable `q` --- */ @@ -662,7 +662,7 @@ int test21() /********************************************* TEST_OUTPUT: --- -fail_compilation/retscope.d(1907): Error: scope variable `x` assigned to `this` with longer lifetime +fail_compilation/retscope.d(1907): Error: scope variable `x` assigned to `ref` variable `this` with longer lifetime fail_compilation/retscope.d(1913): Error: scope variable `x` may not be returned --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d index 9f1e13dde98..1cb76d6d5ae 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope2.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope2.d @@ -2,7 +2,7 @@ REQUIRED_ARGS: -preview=dip1000 TEST_OUTPUT: --- -fail_compilation/retscope2.d(102): Error: scope variable `s` assigned to `p` with longer lifetime +fail_compilation/retscope2.d(102): Error: scope variable `s` assigned to `ref` variable `p` with longer lifetime fail_compilation/retscope2.d(107): Error: address of variable `s` assigned to `p` with longer lifetime --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d index 95d5dbe5507..9736d37e949 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/retscope6.d +++ b/gcc/testsuite/gdc.test/fail_compilation/retscope6.d @@ -25,7 +25,7 @@ int* test() @safe --- fail_compilation/retscope6.d(7034): Error: address of variable `i` assigned to `s` with longer lifetime fail_compilation/retscope6.d(7035): Error: address of variable `i` assigned to `s` with longer lifetime -fail_compilation/retscope6.d(7025): Error: scope variable `_param_2` assigned to `t` with longer lifetime +fail_compilation/retscope6.d(7025): Error: scope variable `_param_2` assigned to `ref` variable `t` with longer lifetime fail_compilation/retscope6.d(7037): Error: template instance `retscope6.S.emplace4!(int*)` error instantiating fail_compilation/retscope6.d(7037): Error: address of variable `i` assigned to `s` with longer lifetime --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/systemvariables.d b/gcc/testsuite/gdc.test/fail_compilation/systemvariables.d new file mode 100644 index 00000000000..0079719e355 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/systemvariables.d @@ -0,0 +1,48 @@ +/* +REQUIRED_ARGS: -preview=systemVariables +TEST_OUTPUT: +--- +fail_compilation/systemvariables.d(30): Error: cannot access `@system` variable `gInt` in @safe code +fail_compilation/systemvariables.d(31): Error: cannot access `@system` variable `gInt` in @safe code +fail_compilation/systemvariables.d(32): Error: cannot access `@system` variable `gArr` in @safe code +fail_compilation/systemvariables.d(33): Error: cannot access `@system` variable `gArr` in @safe code +fail_compilation/systemvariables.d(34): Error: cannot access `@system` variable `gInt` in @safe code +fail_compilation/systemvariables.d(37): Error: cannot access `@system` variable `lSys` in @safe code +fail_compilation/systemvariables.d(38): Error: cannot access `@system` variable `lSys` in @safe code +fail_compilation/systemvariables.d(39): Error: cannot access `@system` variable `lSys` in @safe code +fail_compilation/systemvariables.d(41): Error: cannot access `@system` variable `eInt` in @safe code +--- +*/ + +// http://dlang.org/dips/1035 + + +@system int gInt; +@system enum int eInt = 3; +@system { int[] gArr; } +alias aliasToSys = gInt; + +void increment(ref int x) @safe { x++; } +void incrementP(int* x) @safe { (*x)++; } + +void basic() @safe +{ + gInt = 0; // error + gInt++; // error + gArr ~= 30; // error + const c = gArr[0]; // error + aliasToSys++; // error + + @system int lSys = 0; + lSys = 0; // error + increment(lSys); // error + incrementP(&lSys); // error + + int a = eInt; // error + int b = typeof(eInt).max; // allowed + + void f() @trusted + { + lSys = 0; // allowed + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/systemvariables_deprecation.d b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_deprecation.d new file mode 100644 index 00000000000..75dbe2dc1a0 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_deprecation.d @@ -0,0 +1,28 @@ +/* +REQUIRED_ARGS: -de +TEST_OUTPUT: +--- +fail_compilation/systemvariables_deprecation.d(16): Deprecation: `@safe` function `main` calling `middle` +fail_compilation/systemvariables_deprecation.d(21): which calls `systemvariables_deprecation.inferred` +fail_compilation/systemvariables_deprecation.d(27): which would be `@system` because of: +fail_compilation/systemvariables_deprecation.d(27): cannot access `@system` variable `x0` in @safe code +--- +*/ + +// test deprecation messages before -preview=systemVariables becomes default + +void main() @safe +{ + middle(); // nested deprecation +} + +auto middle() +{ + return inferred(); // no deprecation, inferredC is not explicit `@safe` +} + +auto inferred() +{ + @system int* x0; + x0 = null; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/systemvariables_struct.d b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_struct.d new file mode 100644 index 00000000000..7d8bfabeb7d --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_struct.d @@ -0,0 +1,60 @@ +/* +REQUIRED_ARGS: -preview=systemVariables +TEST_OUTPUT: +--- +fail_compilation/systemvariables_struct.d(31): Error: cannot access `@system` field `S.syst` in `@safe` code +fail_compilation/systemvariables_struct.d(32): Error: cannot access `@system` field `S.syst` in `@safe` code +fail_compilation/systemvariables_struct.d(33): Error: cannot access `@system` field `S.syst` in `@safe` code +fail_compilation/systemvariables_struct.d(36): Error: cannot access `@system` field `S.syst` in `@safe` code +fail_compilation/systemvariables_struct.d(37): Error: cannot access `@system` field `S.syst` in `@safe` code +fail_compilation/systemvariables_struct.d(38): Error: cannot access `@system` field `S.syst` in `@safe` code +fail_compilation/systemvariables_struct.d(54): Error: cannot access `@system` field `S2.syst` in `@safe` code +fail_compilation/systemvariables_struct.d(55): Error: cannot access `@system` field `S2.syst` in `@safe` code +fail_compilation/systemvariables_struct.d(56): Error: cannot access `@system` field `S.syst` in `@safe` code +fail_compilation/systemvariables_struct.d(57): Error: cannot access `@system` field `S.syst` in `@safe` code +--- +*/ + +// http://dlang.org/dips/1035 + +struct S +{ + @system S* syst; + @safe S* safe; +} + +void aggregate() @safe +{ + S s0; + + // write access + s0.syst = null; + __traits(getMember, s0, "syst") = null; + s0.tupleof[0] = null; + + // read access + auto a0 = s0.syst; + auto a1 = __traits(getMember, s0, "syst"); + auto a2 = s0.tupleof[0]; + + S s1; + s1 = s0; // allowed +} + +struct S2 +{ + @system S syst; + @safe S safe; +} + +@safe S2 gs2; + +void aggregate2() @safe +{ + gs2.syst.syst = null; + gs2.syst.safe = null; + gs2.safe.syst = null; + gs2.safe.syst.safe = null; + + gs2.safe.safe = null; // allowed +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/systemvariables_void_init.d b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_void_init.d new file mode 100644 index 00000000000..6f44093a8af --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/systemvariables_void_init.d @@ -0,0 +1,32 @@ +/** +REQUIRED_ARGS: -preview=systemVariables +TEST_OUTPUT: +--- +fail_compilation/systemvariables_void_init.d(29): Error: `void` initializers for `@system` variables not allowed in safe functions +fail_compilation/systemvariables_void_init.d(30): Error: `void` initializers for `@system` variables not allowed in safe functions +fail_compilation/systemvariables_void_init.d(31): Error: `void` initializers for `@system` variables not allowed in safe functions +--- +*/ + +struct S +{ + int x; + @system int y; +} + +struct C +{ + S[2] x; +} + +enum E : C +{ + x = C.init, +} + +void main() @safe +{ + S s = void; + C c = void; + E e = void; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/templatethis.d b/gcc/testsuite/gdc.test/fail_compilation/templatethis.d new file mode 100644 index 00000000000..73036d959b4 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/templatethis.d @@ -0,0 +1,37 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/templatethis.d(13): Error: cannot use `this` outside an aggregate type +fail_compilation/templatethis.d(17): Error: cannot use `this` outside an aggregate type +fail_compilation/templatethis.d(21): Error: cannot use `this` outside an aggregate type +fail_compilation/templatethis.d(23): Error: cannot use `this` outside an aggregate type +fail_compilation/templatethis.d(29): Error: cannot use `this` outside an aggregate type +fail_compilation/templatethis.d(32): Error: mixin `templatethis.t2!()` error instantiating +--- +*/ + +template t(this T) +{ +} + +struct S(this T) +{ +} + +enum e(this T) = 1; + +void f(this T)() +{ +} + +mixin template t2() +{ + int i(this T) = 1; +} + +mixin t2; + +class C +{ + mixin t2; // OK +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test14496.d b/gcc/testsuite/gdc.test/fail_compilation/test14496.d index 9f628caf219..94d5d0ffc5f 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test14496.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test14496.d @@ -6,10 +6,10 @@ fail_compilation/test14496.d(24): Error: `void` initializers for pointers not al fail_compilation/test14496.d(28): Error: `void` initializers for pointers not allowed in safe functions fail_compilation/test14496.d(48): Error: `void` initializers for pointers not allowed in safe functions fail_compilation/test14496.d(49): Error: `void` initializers for pointers not allowed in safe functions +fail_compilation/test14496.d(50): Error: `void` initializers for pointers not allowed in safe functions --- */ // https://issues.dlang.org/show_bug.cgi?id=14496 - @safe void foo() { struct Foo { @@ -47,4 +47,5 @@ struct Baz { @safe void sinister() { Bar bar; Baz baz; + Bar[2] bars; // https://issues.dlang.org/show_bug.cgi?id=23412 } diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17764.d b/gcc/testsuite/gdc.test/fail_compilation/test17764.d index 6ee988a5dbb..befcdb19fee 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test17764.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test17764.d @@ -1,7 +1,7 @@ /* REQUIRED_ARGS: -preview=dip1000 * TEST_OUTPUT: --- -fail_compilation/test17764.d(109): Error: scope variable `c` assigned to non-scope `global` +fail_compilation/test17764.d(109): Error: scope variable `c` assigned to global variable `global` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test19097.d b/gcc/testsuite/gdc.test/fail_compilation/test19097.d index 9c025a83ff0..980931e3da2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test19097.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test19097.d @@ -3,7 +3,7 @@ --- fail_compilation/test19097.d(44): Error: scope variable `s` may not be returned fail_compilation/test19097.d(48): Error: scope variable `s1` may not be returned -fail_compilation/test19097.d(77): Error: scope variable `z` assigned to `refPtr` with longer lifetime +fail_compilation/test19097.d(77): Error: scope variable `z` assigned to `ref` variable `refPtr` with longer lifetime fail_compilation/test19097.d(108): Error: scope variable `s4` may not be returned fail_compilation/test19097.d(126): Error: scope variable `s5c` may not be returned fail_compilation/test19097.d(130): Error: scope variable `s5m` may not be returned diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22145.d b/gcc/testsuite/gdc.test/fail_compilation/test22145.d index 394116dd21d..55e7c639dd4 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test22145.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test22145.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: REQUIRED_ARGS: -preview=dip1000 --- -fail_compilation/test22145.d(115): Error: scope variable `x` assigned to non-scope `global` +fail_compilation/test22145.d(115): Error: scope variable `x` assigned to global variable `global` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22680.d b/gcc/testsuite/gdc.test/fail_compilation/test22680.d index caf0f4adff4..85e653e91ea 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/test22680.d +++ b/gcc/testsuite/gdc.test/fail_compilation/test22680.d @@ -1,7 +1,7 @@ /* REQUIRED_ARGS: -preview=dip1000 TEST_OUTPUT: --- -fail_compilation/test22680.d(104): Error: scope variable `this` assigned to non-scope `c` +fail_compilation/test22680.d(104): Error: scope variable `this` assigned to global variable `c` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/warn14905.d b/gcc/testsuite/gdc.test/fail_compilation/warn14905.d new file mode 100644 index 00000000000..55520ba69c2 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/warn14905.d @@ -0,0 +1,23 @@ +// REQUIRED_ARGS: -o- -w + +/* +TEST_OUTPUT: +--- +fail_compilation/warn14905.d(16): Warning: statement is not reachable in template instance warn14905.fun!"a".fun +fail_compilation/warn14905.d(16): Warning: statement is not reachable in template instance warn14905.fun!"b".fun +Error: warnings are treated as errors + Use -wi if you wish to treat warnings only as informational. +--- +*/ + +bool fun(string s)() +{ + return true; + return false; +} + +void main() +{ + cast(void)fun!"a"; + cast(void)fun!"b"; +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/xmmslice.d b/gcc/testsuite/gdc.test/fail_compilation/xmmslice.d new file mode 100644 index 00000000000..6cf0e238f29 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/xmmslice.d @@ -0,0 +1,22 @@ + +/* REQUIRED_ARGS: -mcpu=avx +DISABLED: win32 freebsd32 linux32 osx32 +TEST_OUTPUT: +--- +fail_compilation/xmmslice.d(110): Error: `__vector(int[4])` cannot be sliced with `[]` +--- + */ + +#line 100 + +import core.simd; + +int4 testz4() +{ + return [0,0,0,0]; +} + +void test() +{ + assert(testz4()[] == [0,0,0,0]); +} diff --git a/gcc/testsuite/gdc.test/runnable/cdcmp.d b/gcc/testsuite/gdc.test/runnable/cdcmp.d new file mode 100644 index 00000000000..1c998dca55a --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/cdcmp.d @@ -0,0 +1,146 @@ + + +bool test_ltz(float x) { return x < 0; } +bool test_lez(float x) { return x <= 0; } +bool test_eqz(float x) { return x == 0; } +bool test_nez(float x) { return x != 0; } +bool test_gez(float x) { return x >= 0; } +bool test_gtz(float x) { return x > 0; } + +void test1f() +{ + assert(!test_ltz(0.0f)); + assert(!test_ltz(1.0f)); + assert( test_ltz(-1.0f)); + + assert( test_lez(0.0f)); + assert(!test_lez(1.0f)); + assert( test_lez(-1.0f)); + + assert( test_eqz(0.0f)); + assert(!test_eqz(1.0f)); + assert(!test_eqz(-1.0f)); + + assert(!test_nez(0.0f)); + assert( test_nez(1.0f)); + assert( test_nez(-1.0f)); + + assert( test_gez(0.0f)); + assert( test_gez(1.0f)); + assert(!test_gez(-1.0f)); + + assert(!test_gtz(0.0f)); + assert( test_gtz(1.0f)); + assert(!test_gtz(-1.0f)); +} + +bool test_ltz(double x) { return x < 0; } +bool test_lez(double x) { return x <= 0; } +bool test_eqz(double x) { return x == 0; } +bool test_nez(double x) { return x != 0; } +bool test_gez(double x) { return x >= 0; } +bool test_gtz(double x) { return x > 0; } + +void test1d() +{ + assert(!test_ltz(0.0)); + assert(!test_ltz(1.0)); + assert( test_ltz(-1.0)); + + assert( test_lez(0.0)); + assert(!test_lez(1.0)); + assert( test_lez(-1.0)); + + assert( test_eqz(0.0)); + assert(!test_eqz(1.0)); + assert(!test_eqz(-1.0)); + + assert(!test_nez(0.0)); + assert( test_nez(1.0)); + assert( test_nez(-1.0)); + + assert( test_gez(0.0)); + assert( test_gez(1.0)); + assert(!test_gez(-1.0)); + + assert(!test_gtz(0.0)); + assert( test_gtz(1.0)); + assert(!test_gtz(-1.0)); +} + +bool test_lt(float x, float y) { return x < y; } +bool test_le(float x, float y) { return x <= y; } +bool test_eq(float x, float y) { return x == y; } +bool test_ne(float x, float y) { return x != y; } +bool test_ge(float x, float y) { return x >= y; } +bool test_gt(float x, float y) { return x > y; } + +void test2f() +{ + assert(!test_lt(1.0f, 1.0f)); + assert( test_lt(1.0f, 2.0f)); + assert(!test_lt(2.0f, 1.0f)); + + assert( test_le(1.0f, 1.0f)); + assert( test_le(1.0f, 2.0f)); + assert(! test_le(2.0f, 1.0f)); + + assert( test_eq(1.0f, 1.0f)); + assert(!test_eq(1.0f, 2.0f)); + assert(!test_eq(2.0f, 1.0f)); + + assert(!test_ne(1.0f, 1.0f)); + assert( test_ne(1.0f, 2.0f)); + assert( test_ne(2.0f, 1.0f)); + + assert( test_ge(1.0f, 1.0f)); + assert(!test_ge(1.0f, 2.0f)); + assert( test_ge(2.0f, 1.0f)); + + assert(!test_gt(1.0f, 1.0f)); + assert(!test_gt(1.0f, 2.0f)); + assert( test_gt(2.0f, 1.0f)); +} + +bool test_lt(double x, double y) { return x < y; } +bool test_le(double x, double y) { return x <= y; } +bool test_eq(double x, double y) { return x == y; } +bool test_ne(double x, double y) { return x != y; } +bool test_ge(double x, double y) { return x >= y; } +bool test_gt(double x, double y) { return x > y; } + +void test2d() +{ + assert(!test_lt(1.0, 1.0)); + assert( test_lt(1.0, 2.0)); + assert(!test_lt(2.0, 1.0)); + + assert( test_le(1.0, 1.0)); + assert( test_le(1.0, 2.0)); + assert(! test_le(2.0, 1.0)); + + assert( test_eq(1.0, 1.0)); + assert(!test_eq(1.0, 2.0)); + assert(!test_eq(2.0, 1.0)); + + assert(!test_ne(1.0, 1.0)); + assert( test_ne(1.0, 2.0)); + assert( test_ne(2.0, 1.0)); + + assert( test_ge(1.0, 1.0)); + assert(!test_ge(1.0, 2.0)); + assert( test_ge(2.0, 1.0)); + + assert(!test_gt(1.0, 1.0)); + assert(!test_gt(1.0, 2.0)); + assert( test_gt(2.0, 1.0)); +} + +int main() +{ + test1f(); + test1d(); + test2f(); + test2d(); + return 0; +} diff --git a/gcc/testsuite/gdc.test/runnable/lexer.d b/gcc/testsuite/gdc.test/runnable/lexer.d index 6e31c07f9cb..897514681d5 100644 --- a/gcc/testsuite/gdc.test/runnable/lexer.d +++ b/gcc/testsuite/gdc.test/runnable/lexer.d @@ -87,6 +87,10 @@ enum e13102=184467440737095516153.6L; /*********************************************************/ +static assert("\∾̳" == "\U0000223E\U00000333"); // ="\xe2\x88\xbe\xcc\xb3" + +/*********************************************************/ + int main() { test6(); diff --git a/gcc/testsuite/gdc.test/runnable/test20734.d b/gcc/testsuite/gdc.test/runnable/test20734.d index b3c5916ada5..bd012bba19e 100644 --- a/gcc/testsuite/gdc.test/runnable/test20734.d +++ b/gcc/testsuite/gdc.test/runnable/test20734.d @@ -17,6 +17,14 @@ extern(C) int main() nothrow @nogc @safe takeScopeSlice([ S(1), S(2) ]); // @nogc => no GC allocation (() @trusted { assert(numDtor == 2); })(); // stack-allocated array literal properly destructed assert23100([]); + + // https://issues.dlang.org/show_bug.cgi?id=22306 + // scope array variable should be stack allocated + scope int[] sa = [10, 20]; + assert(sa[0] == 10); + assert(sa[1] == 20); + assert(sa.length == 2); + return 0; } diff --git a/gcc/testsuite/gdc.test/runnable/test23337.d b/gcc/testsuite/gdc.test/runnable/test23337.d new file mode 100644 index 00000000000..47deabab7f9 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test23337.d @@ -0,0 +1,182 @@ +// https://issues.dlang.org/show_bug.cgi?id=23337 + +int copies, destroyed; + +void reset() { copies = destroyed = 0; } + +struct S +{ + this(inout ref S) inout { ++copies; } + ~this() { ++destroyed; } +} + +S[3] globals; + +S[3] makeStaticArray() { return (S[3]).init; } + +S[] makeSlice(ref S[3] sa) { return sa[]; } + +void main() +{ + { + S[3] fromLvalStaticArray = globals; + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + S[3] fromRvalStaticArray = makeStaticArray(); + assert(copies == 0); // moved or emplaced + } + assert(destroyed == 3); + reset(); + + { + S[3] fromArrayLiteral = [S(), S(), S()]; + assert(copies == 0); // moved or emplaced + } + assert(destroyed == 3); + reset(); + + { + S[3] fromSliceExp = globals[]; + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + S[] slice = globals[]; + S[3] fromLvalSlice = slice; + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + S[3] fromRvalSlice = makeSlice(globals); + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + S *p = &globals[0]; + S[3] fromSingleLval = *p; + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + S[3] fromSingleRval = S(); + assert(destroyed == 1); // temporary + assert(copies == 3); + } + assert(destroyed == 4); + reset(); + + // slice-exp left-hand-sides (*construction* only in ctors): + + { + static struct T + { + S[3] ss; + this(int) { ss[] = globals; } + } + T fromLvalStaticArray = T(0); + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + static struct T + { + S[3] ss; + this(int) { ss[] = makeStaticArray(); } + } + T fromRvalStaticArray = T(0); + assert(copies == 0); // moved or emplaced + } + assert(destroyed == 3); + reset(); + + { + static struct T + { + S[3] ss; + this(int) { ss[] = [S(), S(), S()]; } + } + T fromArrayLiteral = T(0); + assert(copies == 0); // moved or emplaced + } + assert(destroyed == 3); + reset(); + + { + static struct T + { + S[3] ss; + this(int) { ss[] = globals[]; } + } + T fromSliceExp = T(0); + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + static struct T + { + S[3] ss; + this(int) + { + S[] slice = globals[]; + ss[] = slice; + } + } + T fromLvalSlice = T(0); + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + static struct T + { + S[3] ss; + this(int) { ss[] = makeSlice(globals); } + } + T fromRvalSlice = T(0); + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + static struct T + { + S[3] ss; + this(int) { ss[] = globals[0]; } + } + T fromSingleLval = T(0); + assert(copies == 3); + } + assert(destroyed == 3); + reset(); + + { + static struct T + { + S[3] ss; + this(int) { ss[] = S(); } + } + T fromSingleRval = T(0); + assert(destroyed == 1); // temporary + assert(copies == 3); + } + assert(destroyed == 4); + reset(); +} diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index a4c46f3306e..2398875bce7 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -4219ba670ce9ff92f3e874f0f048f2c28134c008 +e4f89195913be1dc638707b1abb24c4f3ae7e0bf The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/libphobos/libdruntime/core/stdc/fenv.d b/libphobos/libdruntime/core/stdc/fenv.d index 5242ba9d4e2..dbe7daa7791 100644 --- a/libphobos/libdruntime/core/stdc/fenv.d +++ b/libphobos/libdruntime/core/stdc/fenv.d @@ -24,7 +24,6 @@ else version (WatchOS) version = Darwin; extern (C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/stdc/signal.d b/libphobos/libdruntime/core/stdc/signal.d index 8d5d8459da1..13c6f9efbe8 100644 --- a/libphobos/libdruntime/core/stdc/signal.d +++ b/libphobos/libdruntime/core/stdc/signal.d @@ -15,7 +15,6 @@ module core.stdc.signal; extern (C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/stdc/stdarg.d b/libphobos/libdruntime/core/stdc/stdarg.d index 646905eaffb..5b79813ae1b 100644 --- a/libphobos/libdruntime/core/stdc/stdarg.d +++ b/libphobos/libdruntime/core/stdc/stdarg.d @@ -12,7 +12,6 @@ module core.stdc.stdarg; -@system: @nogc: nothrow: diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d index fc98350e139..ee37da1a5dd 100644 --- a/libphobos/libdruntime/core/stdc/stdio.d +++ b/libphobos/libdruntime/core/stdc/stdio.d @@ -49,7 +49,6 @@ private } extern (C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/stdc/stdlib.d b/libphobos/libdruntime/core/stdc/stdlib.d index 920c3117732..0b42de8ec3b 100644 --- a/libphobos/libdruntime/core/stdc/stdlib.d +++ b/libphobos/libdruntime/core/stdc/stdlib.d @@ -31,7 +31,6 @@ version (CRuntime_Glibc) else {} extern (C): -@system: /* Placed outside `nothrow` and `@nogc` in order to not constrain what the callback does. */ diff --git a/libphobos/libdruntime/core/stdc/string.d b/libphobos/libdruntime/core/stdc/string.d index f15ef851909..3591a6d2d77 100644 --- a/libphobos/libdruntime/core/stdc/string.d +++ b/libphobos/libdruntime/core/stdc/string.d @@ -30,7 +30,6 @@ else version (CRuntime_UClibc) version = ReturnStrerrorR; extern (C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/stdc/wchar_.d b/libphobos/libdruntime/core/stdc/wchar_.d index d0870290854..fe5fce481cd 100644 --- a/libphobos/libdruntime/core/stdc/wchar_.d +++ b/libphobos/libdruntime/core/stdc/wchar_.d @@ -22,7 +22,6 @@ public import core.stdc.time; // for tm public import core.stdc.stdint; // for WCHAR_MIN, WCHAR_MAX extern (C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/sys/darwin/fcntl.d b/libphobos/libdruntime/core/sys/darwin/fcntl.d index 47d895ad6cb..413d9c655b1 100644 --- a/libphobos/libdruntime/core/sys/darwin/fcntl.d +++ b/libphobos/libdruntime/core/sys/darwin/fcntl.d @@ -15,6 +15,5 @@ version (Darwin): extern (C): nothrow: @nogc: -@system: enum F_FULLFSYNC = 51; diff --git a/libphobos/libdruntime/core/sys/darwin/ifaddrs.d b/libphobos/libdruntime/core/sys/darwin/ifaddrs.d index a2540361d0f..2e744b0feca 100644 --- a/libphobos/libdruntime/core/sys/darwin/ifaddrs.d +++ b/libphobos/libdruntime/core/sys/darwin/ifaddrs.d @@ -29,7 +29,6 @@ version (Darwin): extern (C): nothrow: @nogc: -@system: import core.sys.posix.sys.socket; diff --git a/libphobos/libdruntime/core/sys/elf/package.d b/libphobos/libdruntime/core/sys/elf/package.d index 2dcfd201dd5..b120ee58f69 100644 --- a/libphobos/libdruntime/core/sys/elf/package.d +++ b/libphobos/libdruntime/core/sys/elf/package.d @@ -8,7 +8,6 @@ module core.sys.elf; extern (C): pure: nothrow: -@system: import core.stdc.stdint; diff --git a/libphobos/libdruntime/core/sys/linux/dlfcn.d b/libphobos/libdruntime/core/sys/linux/dlfcn.d index fbb84627af8..a13bae76631 100644 --- a/libphobos/libdruntime/core/sys/linux/dlfcn.d +++ b/libphobos/libdruntime/core/sys/linux/dlfcn.d @@ -9,7 +9,6 @@ version (linux): extern (C): nothrow: @nogc: -@system: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/linux/elf.d b/libphobos/libdruntime/core/sys/linux/elf.d index 168b936f921..0486cbee0bb 100644 --- a/libphobos/libdruntime/core/sys/linux/elf.d +++ b/libphobos/libdruntime/core/sys/linux/elf.d @@ -9,7 +9,6 @@ version (linux): extern (C): pure: nothrow: -@system: import core.stdc.stdint; public import core.sys.elf; diff --git a/libphobos/libdruntime/core/sys/linux/epoll.d b/libphobos/libdruntime/core/sys/linux/epoll.d index f5ff7dba0f8..99099b52417 100644 --- a/libphobos/libdruntime/core/sys/linux/epoll.d +++ b/libphobos/libdruntime/core/sys/linux/epoll.d @@ -13,10 +13,8 @@ version (linux): import core.sys.posix.signal : sigset_t; extern (C): -@system: @nogc: nothrow: -@system: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/linux/err.d b/libphobos/libdruntime/core/sys/linux/err.d index be5378d0618..c3752de5207 100644 --- a/libphobos/libdruntime/core/sys/linux/err.d +++ b/libphobos/libdruntime/core/sys/linux/err.d @@ -12,7 +12,6 @@ version (linux): extern (C): nothrow: @nogc: -@system: void err(int eval, scope const char* fmt, ...); void errx(int eval, scope const char* fmt, ...); diff --git a/libphobos/libdruntime/core/sys/linux/errno.d b/libphobos/libdruntime/core/sys/linux/errno.d index d7a39acb932..74844e798e8 100644 --- a/libphobos/libdruntime/core/sys/linux/errno.d +++ b/libphobos/libdruntime/core/sys/linux/errno.d @@ -8,7 +8,6 @@ module core.sys.linux.errno; version (linux): extern (C): nothrow: -@system: public import core.stdc.errno; import core.sys.linux.config; diff --git a/libphobos/libdruntime/core/sys/linux/execinfo.d b/libphobos/libdruntime/core/sys/linux/execinfo.d index 4169ca36c5b..50dc60d208a 100644 --- a/libphobos/libdruntime/core/sys/linux/execinfo.d +++ b/libphobos/libdruntime/core/sys/linux/execinfo.d @@ -10,7 +10,6 @@ module core.sys.linux.execinfo; version (linux): extern (C): nothrow: -@system: @nogc: int backtrace(void** buffer, int size); diff --git a/libphobos/libdruntime/core/sys/linux/fcntl.d b/libphobos/libdruntime/core/sys/linux/fcntl.d index 89dc019cc8f..d666efecdb4 100644 --- a/libphobos/libdruntime/core/sys/linux/fcntl.d +++ b/libphobos/libdruntime/core/sys/linux/fcntl.d @@ -5,7 +5,6 @@ public import core.sys.posix.fcntl; version (linux): extern(C): nothrow: -@system: // From linux/falloc.h /// fallocate(2) params diff --git a/libphobos/libdruntime/core/sys/linux/fs.d b/libphobos/libdruntime/core/sys/linux/fs.d index c5525066969..ca885670076 100644 --- a/libphobos/libdruntime/core/sys/linux/fs.d +++ b/libphobos/libdruntime/core/sys/linux/fs.d @@ -18,7 +18,6 @@ public import core.sys.posix.sys.ioctl; import core.stdc.config : c_ulong, c_long; extern (C): -@system: @nogc: nothrow: diff --git a/libphobos/libdruntime/core/sys/linux/ifaddrs.d b/libphobos/libdruntime/core/sys/linux/ifaddrs.d index 5490e97aa0f..479dfa8d39b 100644 --- a/libphobos/libdruntime/core/sys/linux/ifaddrs.d +++ b/libphobos/libdruntime/core/sys/linux/ifaddrs.d @@ -22,7 +22,6 @@ version (linux): extern (C): nothrow: @nogc: -@system: struct ifaddrs { diff --git a/libphobos/libdruntime/core/sys/linux/io_uring.d b/libphobos/libdruntime/core/sys/linux/io_uring.d index 5e1a20c24b3..7bafb9fec0b 100644 --- a/libphobos/libdruntime/core/sys/linux/io_uring.d +++ b/libphobos/libdruntime/core/sys/linux/io_uring.d @@ -14,10 +14,8 @@ version (linux): import core.sys.linux.fs : __kernel_rwf_t; extern (C): -@system: @nogc: nothrow: -@system: /** * IO submission data structure (Submission Queue Entry) diff --git a/libphobos/libdruntime/core/sys/linux/link.d b/libphobos/libdruntime/core/sys/linux/link.d index b417ec8ec77..4d7eb1eb7d3 100644 --- a/libphobos/libdruntime/core/sys/linux/link.d +++ b/libphobos/libdruntime/core/sys/linux/link.d @@ -8,7 +8,6 @@ module core.sys.linux.link; version (linux): extern (C): nothrow: -@system: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/linux/perf_event.d b/libphobos/libdruntime/core/sys/linux/perf_event.d index 9e96a7f5f43..b9993a78413 100644 --- a/libphobos/libdruntime/core/sys/linux/perf_event.d +++ b/libphobos/libdruntime/core/sys/linux/perf_event.d @@ -9,7 +9,6 @@ module core.sys.linux.perf_event; version (linux) : extern (C): @nogc: nothrow: -@system: import core.sys.posix.sys.ioctl; import core.sys.posix.unistd; diff --git a/libphobos/libdruntime/core/sys/linux/sched.d b/libphobos/libdruntime/core/sys/linux/sched.d index e828b7447d1..5cd512e8263 100644 --- a/libphobos/libdruntime/core/sys/linux/sched.d +++ b/libphobos/libdruntime/core/sys/linux/sched.d @@ -26,7 +26,6 @@ version (linux): extern (C): @nogc: nothrow: -@system: private // helpers diff --git a/libphobos/libdruntime/core/sys/linux/stdio.d b/libphobos/libdruntime/core/sys/linux/stdio.d index ab8971b482f..2d079fd71f7 100644 --- a/libphobos/libdruntime/core/sys/linux/stdio.d +++ b/libphobos/libdruntime/core/sys/linux/stdio.d @@ -13,7 +13,6 @@ import core.sys.linux.config : __USE_FILE_OFFSET64; import core.stdc.stdio : FILE; import core.stdc.stddef : wchar_t; -@system: extern(C) nothrow { @@ -29,7 +28,7 @@ extern(C) nothrow cookie_seek_function_t seek; cookie_close_function_t close; } - FILE* fopencookie(in void* cookie, in char* mode, cookie_io_functions_t io_funcs); + FILE* fopencookie(void* cookie, const(char)* mode, cookie_io_functions_t io_funcs); void setbuffer(FILE *stream, char *buf, size_t size); // note: _DEFAULT_SOURCE } diff --git a/libphobos/libdruntime/core/sys/linux/string.d b/libphobos/libdruntime/core/sys/linux/string.d index 880faa4d701..a8da3982461 100644 --- a/libphobos/libdruntime/core/sys/linux/string.d +++ b/libphobos/libdruntime/core/sys/linux/string.d @@ -14,7 +14,6 @@ version (linux): extern (C): nothrow: @nogc: -@system: static if (_GNU_SOURCE) { diff --git a/libphobos/libdruntime/core/sys/linux/sys/eventfd.d b/libphobos/libdruntime/core/sys/linux/sys/eventfd.d index 0954b3f0257..a35d71479d8 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/eventfd.d +++ b/libphobos/libdruntime/core/sys/linux/sys/eventfd.d @@ -9,7 +9,6 @@ module core.sys.linux.sys.eventfd; version (linux): extern (C): @nogc: -@system: nothrow: version (ARM) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/linux/sys/inotify.d b/libphobos/libdruntime/core/sys/linux/sys/inotify.d index 11bdc85cf78..c74aaa6e7e2 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/inotify.d +++ b/libphobos/libdruntime/core/sys/linux/sys/inotify.d @@ -22,7 +22,6 @@ version (DragonFlyBSD) version = LinuxOrCompatible; version (LinuxOrCompatible): extern (C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/sys/linux/sys/mman.d b/libphobos/libdruntime/core/sys/linux/sys/mman.d index 649e2af848f..43a1aec1f94 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/mman.d +++ b/libphobos/libdruntime/core/sys/linux/sys/mman.d @@ -8,7 +8,6 @@ module core.sys.linux.sys.mman; version (linux): extern (C): nothrow: -@system: @nogc: version (ARM) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/linux/sys/prctl.d b/libphobos/libdruntime/core/sys/linux/sys/prctl.d index a7322166a20..363e1e3652b 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/prctl.d +++ b/libphobos/libdruntime/core/sys/linux/sys/prctl.d @@ -8,7 +8,6 @@ module core.sys.linux.sys.prctl; version (linux): extern (C): -@system: @nogc: nothrow: diff --git a/libphobos/libdruntime/core/sys/linux/sys/signalfd.d b/libphobos/libdruntime/core/sys/linux/sys/signalfd.d index 736b1456169..8834be4b00b 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/signalfd.d +++ b/libphobos/libdruntime/core/sys/linux/sys/signalfd.d @@ -12,7 +12,6 @@ import core.sys.posix.signal; version (linux): extern (C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d b/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d index 0c9ed592c3b..699cd3e67c4 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d +++ b/libphobos/libdruntime/core/sys/linux/sys/sysinfo.d @@ -7,7 +7,6 @@ module core.sys.linux.sys.sysinfo; version (linux) extern(C) @nogc nothrow: -@system: import core.sys.linux.config; diff --git a/libphobos/libdruntime/core/sys/linux/sys/xattr.d b/libphobos/libdruntime/core/sys/linux/sys/xattr.d index 6446ff8b9a3..8618fc9b938 100644 --- a/libphobos/libdruntime/core/sys/linux/sys/xattr.d +++ b/libphobos/libdruntime/core/sys/linux/sys/xattr.d @@ -11,7 +11,6 @@ import core.sys.posix.sys.types; version (linux): extern (C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/sys/linux/timerfd.d b/libphobos/libdruntime/core/sys/linux/timerfd.d index f8a9719a87e..eacc4480694 100644 --- a/libphobos/libdruntime/core/sys/linux/timerfd.d +++ b/libphobos/libdruntime/core/sys/linux/timerfd.d @@ -11,7 +11,6 @@ version (linux): public import core.sys.posix.time; extern (C): -@system: @nogc: nothrow: diff --git a/libphobos/libdruntime/core/sys/linux/tipc.d b/libphobos/libdruntime/core/sys/linux/tipc.d index 4d5d886269a..50f90eeb524 100644 --- a/libphobos/libdruntime/core/sys/linux/tipc.d +++ b/libphobos/libdruntime/core/sys/linux/tipc.d @@ -10,7 +10,6 @@ module core.sys.linux.tipc; version (linux): extern (C) nothrow @nogc: -@system: struct tipc_portid { diff --git a/libphobos/libdruntime/core/sys/linux/unistd.d b/libphobos/libdruntime/core/sys/linux/unistd.d index 48457467005..faa226cf407 100644 --- a/libphobos/libdruntime/core/sys/linux/unistd.d +++ b/libphobos/libdruntime/core/sys/linux/unistd.d @@ -5,7 +5,6 @@ public import core.sys.posix.unistd; version (linux): extern(C): nothrow: -@system: // Additional seek constants for sparse file handling // from Linux's unistd.h, stdio.h, and linux/fs.h diff --git a/libphobos/libdruntime/core/sys/openbsd/sys/mman.d b/libphobos/libdruntime/core/sys/openbsd/sys/mman.d index 765483436ac..8a8542a5709 100644 --- a/libphobos/libdruntime/core/sys/openbsd/sys/mman.d +++ b/libphobos/libdruntime/core/sys/openbsd/sys/mman.d @@ -47,5 +47,6 @@ static if (__BSD_VISIBLE) int madvise(void *, size_t, int); int minherit(void *, size_t, int); + int mimmutable(void *, size_t); void* mquery(void *, size_t, int, int, int, off_t); } diff --git a/libphobos/libdruntime/core/sys/posix/aio.d b/libphobos/libdruntime/core/sys/posix/aio.d index a76846e91df..3ea7f6a19ad 100644 --- a/libphobos/libdruntime/core/sys/posix/aio.d +++ b/libphobos/libdruntime/core/sys/posix/aio.d @@ -23,7 +23,6 @@ else version (WatchOS) version (Posix): extern (C): -@system: @nogc: nothrow: diff --git a/libphobos/libdruntime/core/sys/posix/config.d b/libphobos/libdruntime/core/sys/posix/config.d index 7bd07229ea5..ae6752f220e 100644 --- a/libphobos/libdruntime/core/sys/posix/config.d +++ b/libphobos/libdruntime/core/sys/posix/config.d @@ -19,7 +19,6 @@ public import core.stdc.config; version (Posix): extern (C) nothrow @nogc: -@system: enum _XOPEN_SOURCE = 600; enum _POSIX_SOURCE = true; diff --git a/libphobos/libdruntime/core/sys/posix/dirent.d b/libphobos/libdruntime/core/sys/posix/dirent.d index bffbc5149a1..c7e8649d6c5 100644 --- a/libphobos/libdruntime/core/sys/posix/dirent.d +++ b/libphobos/libdruntime/core/sys/posix/dirent.d @@ -31,7 +31,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/dlfcn.d b/libphobos/libdruntime/core/sys/posix/dlfcn.d index 04a8e8bb866..5797b8fd35d 100644 --- a/libphobos/libdruntime/core/sys/posix/dlfcn.d +++ b/libphobos/libdruntime/core/sys/posix/dlfcn.d @@ -45,7 +45,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // XOpen (XSI) diff --git a/libphobos/libdruntime/core/sys/posix/fcntl.d b/libphobos/libdruntime/core/sys/posix/fcntl.d index dc0a183f25e..0a58034087d 100644 --- a/libphobos/libdruntime/core/sys/posix/fcntl.d +++ b/libphobos/libdruntime/core/sys/posix/fcntl.d @@ -49,7 +49,6 @@ extern (C): nothrow: @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/grp.d b/libphobos/libdruntime/core/sys/posix/grp.d index 92dcf34ee31..3a9b993c0ed 100644 --- a/libphobos/libdruntime/core/sys/posix/grp.d +++ b/libphobos/libdruntime/core/sys/posix/grp.d @@ -30,7 +30,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/iconv.d b/libphobos/libdruntime/core/sys/posix/iconv.d index cea89870eca..e588fb8210a 100644 --- a/libphobos/libdruntime/core/sys/posix/iconv.d +++ b/libphobos/libdruntime/core/sys/posix/iconv.d @@ -34,7 +34,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: alias void* iconv_t; diff --git a/libphobos/libdruntime/core/sys/posix/inttypes.d b/libphobos/libdruntime/core/sys/posix/inttypes.d index 4bde28f015d..e0a4473a23a 100644 --- a/libphobos/libdruntime/core/sys/posix/inttypes.d +++ b/libphobos/libdruntime/core/sys/posix/inttypes.d @@ -19,7 +19,6 @@ public import core.stdc.inttypes; version (Posix): extern (C) nothrow @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/libgen.d b/libphobos/libdruntime/core/sys/posix/libgen.d index b90765fcf80..6770cd828b3 100644 --- a/libphobos/libdruntime/core/sys/posix/libgen.d +++ b/libphobos/libdruntime/core/sys/posix/libgen.d @@ -15,7 +15,6 @@ module core.sys.posix.libgen; @nogc nothrow: -@system: extern (C): version (Posix): diff --git a/libphobos/libdruntime/core/sys/posix/locale.d b/libphobos/libdruntime/core/sys/posix/locale.d index 85e2fb66915..0864f7c6325 100644 --- a/libphobos/libdruntime/core/sys/posix/locale.d +++ b/libphobos/libdruntime/core/sys/posix/locale.d @@ -12,7 +12,6 @@ module core.sys.posix.locale; version (Posix): extern(C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/sys/posix/mqueue.d b/libphobos/libdruntime/core/sys/posix/mqueue.d index 7085fc4dfa5..ac697bf8b9b 100644 --- a/libphobos/libdruntime/core/sys/posix/mqueue.d +++ b/libphobos/libdruntime/core/sys/posix/mqueue.d @@ -31,7 +31,6 @@ version (Posix): version (CRuntime_Glibc): extern (C): @nogc nothrow: -@system: /// Message queue descriptor. diff --git a/libphobos/libdruntime/core/sys/posix/netdb.d b/libphobos/libdruntime/core/sys/posix/netdb.d index d1411ea8afb..70a5fe1901f 100644 --- a/libphobos/libdruntime/core/sys/posix/netdb.d +++ b/libphobos/libdruntime/core/sys/posix/netdb.d @@ -33,7 +33,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/poll.d b/libphobos/libdruntime/core/sys/posix/poll.d index 7c2d5705e4f..5901f62b5c3 100644 --- a/libphobos/libdruntime/core/sys/posix/poll.d +++ b/libphobos/libdruntime/core/sys/posix/poll.d @@ -29,7 +29,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // XOpen (XSI) diff --git a/libphobos/libdruntime/core/sys/posix/pthread.d b/libphobos/libdruntime/core/sys/posix/pthread.d index 395ed0f7e91..6c5f1a93e45 100644 --- a/libphobos/libdruntime/core/sys/posix/pthread.d +++ b/libphobos/libdruntime/core/sys/posix/pthread.d @@ -33,7 +33,6 @@ else version (WatchOS) version (Posix): extern (C) nothrow: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/pwd.d b/libphobos/libdruntime/core/sys/posix/pwd.d index e7ddda79973..e2a77dec3cf 100644 --- a/libphobos/libdruntime/core/sys/posix/pwd.d +++ b/libphobos/libdruntime/core/sys/posix/pwd.d @@ -30,7 +30,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/sched.d b/libphobos/libdruntime/core/sys/posix/sched.d index 35463d4fb6c..f6f0a58e359 100644 --- a/libphobos/libdruntime/core/sys/posix/sched.d +++ b/libphobos/libdruntime/core/sys/posix/sched.d @@ -32,7 +32,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/semaphore.d b/libphobos/libdruntime/core/sys/posix/semaphore.d index a163e592bda..d755f86c9cc 100644 --- a/libphobos/libdruntime/core/sys/posix/semaphore.d +++ b/libphobos/libdruntime/core/sys/posix/semaphore.d @@ -30,7 +30,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/setjmp.d b/libphobos/libdruntime/core/sys/posix/setjmp.d index 5a15d82d2ee..0d43c61389b 100644 --- a/libphobos/libdruntime/core/sys/posix/setjmp.d +++ b/libphobos/libdruntime/core/sys/posix/setjmp.d @@ -19,7 +19,6 @@ import core.sys.posix.signal; // for sigset_t version (Posix): extern (C) nothrow @nogc: -@system: version (RISCV32) version = RISCV_Any; version (RISCV64) version = RISCV_Any; diff --git a/libphobos/libdruntime/core/sys/posix/spawn.d b/libphobos/libdruntime/core/sys/posix/spawn.d index 206496261b0..789053396f0 100644 --- a/libphobos/libdruntime/core/sys/posix/spawn.d +++ b/libphobos/libdruntime/core/sys/posix/spawn.d @@ -49,7 +49,6 @@ public import core.sys.posix.sched : sched_param; extern(C): @nogc: nothrow: -@system: int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t*, int); int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t*, int, int); diff --git a/libphobos/libdruntime/core/sys/posix/stdio.d b/libphobos/libdruntime/core/sys/posix/stdio.d index d0d3d60ff46..d3799890261 100644 --- a/libphobos/libdruntime/core/sys/posix/stdio.d +++ b/libphobos/libdruntime/core/sys/posix/stdio.d @@ -32,7 +32,6 @@ extern (C): nothrow: @nogc: -@system: // // Required (defined in core.stdc.stdio) diff --git a/libphobos/libdruntime/core/sys/posix/stdlib.d b/libphobos/libdruntime/core/sys/posix/stdlib.d index df96a3d3371..8dd7b68e869 100644 --- a/libphobos/libdruntime/core/sys/posix/stdlib.d +++ b/libphobos/libdruntime/core/sys/posix/stdlib.d @@ -31,7 +31,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // Required (defined in core.stdc.stdlib) diff --git a/libphobos/libdruntime/core/sys/posix/string.d b/libphobos/libdruntime/core/sys/posix/string.d index 79d25624e2a..8c4ea38cc83 100644 --- a/libphobos/libdruntime/core/sys/posix/string.d +++ b/libphobos/libdruntime/core/sys/posix/string.d @@ -16,7 +16,6 @@ module core.sys.posix.string; version (Posix): extern(C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/sys/posix/strings.d b/libphobos/libdruntime/core/sys/posix/strings.d index 96fbcccaee7..768a47f39f1 100644 --- a/libphobos/libdruntime/core/sys/posix/strings.d +++ b/libphobos/libdruntime/core/sys/posix/strings.d @@ -15,7 +15,6 @@ module core.sys.posix.strings; version (Posix): extern(C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/sys/posix/sys/filio.d b/libphobos/libdruntime/core/sys/posix/sys/filio.d index a8d837c52b6..bedbd6a08fd 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/filio.d +++ b/libphobos/libdruntime/core/sys/posix/sys/filio.d @@ -20,7 +20,6 @@ else version (WatchOS) version (Posix): nothrow @nogc: -@system: version (Darwin) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/ioccom.d b/libphobos/libdruntime/core/sys/posix/sys/ioccom.d index 4a0e96b3ea9..36917653e3c 100755 --- a/libphobos/libdruntime/core/sys/posix/sys/ioccom.d +++ b/libphobos/libdruntime/core/sys/posix/sys/ioccom.d @@ -18,7 +18,6 @@ else version (WatchOS) version (Posix): nothrow @nogc: -@system: version (Darwin) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/ioctl.d b/libphobos/libdruntime/core/sys/posix/sys/ioctl.d index 36d1edc4ebc..caf3ebafb5a 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/ioctl.d +++ b/libphobos/libdruntime/core/sys/posix/sys/ioctl.d @@ -29,7 +29,6 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: -@system: version (linux) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/ipc.d b/libphobos/libdruntime/core/sys/posix/sys/ipc.d index 17182438e7a..32caba95a10 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/ipc.d +++ b/libphobos/libdruntime/core/sys/posix/sys/ipc.d @@ -28,7 +28,6 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: -@system: // // XOpen (XSI) diff --git a/libphobos/libdruntime/core/sys/posix/sys/mman.d b/libphobos/libdruntime/core/sys/posix/sys/mman.d index 430f21571ec..0d3d517d69a 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/mman.d +++ b/libphobos/libdruntime/core/sys/posix/sys/mman.d @@ -45,7 +45,6 @@ version (X86_64) version = X86_Any; version (Posix): extern (C) nothrow @nogc: -@system: // // Advisory Information (ADV) diff --git a/libphobos/libdruntime/core/sys/posix/sys/msg.d b/libphobos/libdruntime/core/sys/posix/sys/msg.d index 4760f2e22f6..208e5c2dd47 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/msg.d +++ b/libphobos/libdruntime/core/sys/posix/sys/msg.d @@ -14,7 +14,6 @@ import core.stdc.config; version (CRuntime_Glibc): // Some of these may be from linux kernel headers. extern (C): -@system: version (ARM) version = ARM_Any; version (AArch64) version = ARM_Any; diff --git a/libphobos/libdruntime/core/sys/posix/sys/resource.d b/libphobos/libdruntime/core/sys/posix/sys/resource.d index 5ab01744067..1f46f03e14d 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/resource.d +++ b/libphobos/libdruntime/core/sys/posix/sys/resource.d @@ -23,7 +23,6 @@ else version (WatchOS) version = Darwin; nothrow @nogc extern(C): -@system: // // XOpen (XSI) diff --git a/libphobos/libdruntime/core/sys/posix/sys/select.d b/libphobos/libdruntime/core/sys/posix/sys/select.d index 925976d3e33..06b094093ed 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/select.d +++ b/libphobos/libdruntime/core/sys/posix/sys/select.d @@ -27,7 +27,6 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/sys/shm.d b/libphobos/libdruntime/core/sys/posix/sys/shm.d index d04e7926913..6ecdc0defeb 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/shm.d +++ b/libphobos/libdruntime/core/sys/posix/sys/shm.d @@ -29,7 +29,6 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: -@system: // // XOpen (XSI) diff --git a/libphobos/libdruntime/core/sys/posix/sys/socket.d b/libphobos/libdruntime/core/sys/posix/sys/socket.d index fc5dc5d1684..340f3ce93bb 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/socket.d +++ b/libphobos/libdruntime/core/sys/posix/sys/socket.d @@ -45,7 +45,6 @@ version (X86_64) version = X86_Any; version (Posix): extern (C) nothrow @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/sys/stat.d b/libphobos/libdruntime/core/sys/posix/sys/stat.d index 1fb4e44cbbf..ecc98ccf0ed 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/stat.d +++ b/libphobos/libdruntime/core/sys/posix/sys/stat.d @@ -35,7 +35,6 @@ version (SPARC64) version = SPARC_Any; version (Posix): extern (C) nothrow @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/sys/statvfs.d b/libphobos/libdruntime/core/sys/posix/sys/statvfs.d index df9030d6e5b..eae0e5c95c6 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/statvfs.d +++ b/libphobos/libdruntime/core/sys/posix/sys/statvfs.d @@ -16,7 +16,6 @@ version (Posix): extern (C) : nothrow: @nogc: -@system: version (CRuntime_Glibc) { static if (__WORDSIZE == 32) diff --git a/libphobos/libdruntime/core/sys/posix/sys/time.d b/libphobos/libdruntime/core/sys/posix/sys/time.d index 95cf88364c7..b536eedc14f 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/time.d +++ b/libphobos/libdruntime/core/sys/posix/sys/time.d @@ -31,7 +31,6 @@ version (linux) public import core.sys.linux.sys.time; version (Posix): extern (C) nothrow @nogc: -@system: // // XOpen (XSI) diff --git a/libphobos/libdruntime/core/sys/posix/sys/ttycom.d b/libphobos/libdruntime/core/sys/posix/sys/ttycom.d index 0cc2d9cdc84..f4c9c5896ce 100755 --- a/libphobos/libdruntime/core/sys/posix/sys/ttycom.d +++ b/libphobos/libdruntime/core/sys/posix/sys/ttycom.d @@ -22,7 +22,6 @@ else version (WatchOS) version (Posix): nothrow @nogc: -@system: version (Darwin) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/types.d b/libphobos/libdruntime/core/sys/posix/sys/types.d index 3e515c4c68e..cd11b0d3092 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/types.d +++ b/libphobos/libdruntime/core/sys/posix/sys/types.d @@ -30,7 +30,6 @@ else version (WatchOS) version (Posix): extern (C): -@system: // // bits/typesizes.h -- underlying types for *_t. diff --git a/libphobos/libdruntime/core/sys/posix/sys/uio.d b/libphobos/libdruntime/core/sys/posix/sys/uio.d index 2563c6df5ad..e2839631e3b 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/uio.d +++ b/libphobos/libdruntime/core/sys/posix/sys/uio.d @@ -28,7 +28,6 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/sys/un.d b/libphobos/libdruntime/core/sys/posix/sys/un.d index 5030e16f258..11e98a72ab2 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/un.d +++ b/libphobos/libdruntime/core/sys/posix/sys/un.d @@ -25,7 +25,6 @@ else version (WatchOS) version (Posix): extern(C): -@system: public import core.sys.posix.sys.socket: sa_family_t; diff --git a/libphobos/libdruntime/core/sys/posix/sys/utsname.d b/libphobos/libdruntime/core/sys/posix/sys/utsname.d index 0abbf14dfe2..5de50aca465 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/utsname.d +++ b/libphobos/libdruntime/core/sys/posix/sys/utsname.d @@ -16,7 +16,6 @@ version (Posix): extern(C): nothrow: @nogc: -@system: version (CRuntime_Glibc) { diff --git a/libphobos/libdruntime/core/sys/posix/sys/wait.d b/libphobos/libdruntime/core/sys/posix/sys/wait.d index 91b9c9e8409..766a4e0b6aa 100644 --- a/libphobos/libdruntime/core/sys/posix/sys/wait.d +++ b/libphobos/libdruntime/core/sys/posix/sys/wait.d @@ -30,7 +30,6 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/syslog.d b/libphobos/libdruntime/core/sys/posix/syslog.d index cf85664590c..ba2a4ac03ff 100644 --- a/libphobos/libdruntime/core/sys/posix/syslog.d +++ b/libphobos/libdruntime/core/sys/posix/syslog.d @@ -27,7 +27,6 @@ else version (WatchOS) version (Posix): extern (C) nothrow @nogc: -@system: version (CRuntime_Glibc) { diff --git a/libphobos/libdruntime/core/sys/posix/termios.d b/libphobos/libdruntime/core/sys/posix/termios.d index 357060bd57f..e4a99e68651 100644 --- a/libphobos/libdruntime/core/sys/posix/termios.d +++ b/libphobos/libdruntime/core/sys/posix/termios.d @@ -31,7 +31,6 @@ extern (C): nothrow: @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/posix/time.d b/libphobos/libdruntime/core/sys/posix/time.d index ff3a3c46cd0..af52002b1aa 100644 --- a/libphobos/libdruntime/core/sys/posix/time.d +++ b/libphobos/libdruntime/core/sys/posix/time.d @@ -33,7 +33,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // Required (defined in core.stdc.time) diff --git a/libphobos/libdruntime/core/sys/posix/ucontext.d b/libphobos/libdruntime/core/sys/posix/ucontext.d index e8c2f87bbd3..512d7301e9b 100644 --- a/libphobos/libdruntime/core/sys/posix/ucontext.d +++ b/libphobos/libdruntime/core/sys/posix/ucontext.d @@ -22,7 +22,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: version (OSX) version = Darwin; diff --git a/libphobos/libdruntime/core/sys/posix/unistd.d b/libphobos/libdruntime/core/sys/posix/unistd.d index d996556fca0..d1300e1e083 100644 --- a/libphobos/libdruntime/core/sys/posix/unistd.d +++ b/libphobos/libdruntime/core/sys/posix/unistd.d @@ -32,7 +32,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: enum STDIN_FILENO = 0; enum STDOUT_FILENO = 1; diff --git a/libphobos/libdruntime/core/sys/posix/utime.d b/libphobos/libdruntime/core/sys/posix/utime.d index 66aea58d78f..fcec7af3fde 100644 --- a/libphobos/libdruntime/core/sys/posix/utime.d +++ b/libphobos/libdruntime/core/sys/posix/utime.d @@ -30,7 +30,6 @@ version (Posix): extern (C): nothrow: @nogc: -@system: // // Required diff --git a/libphobos/libdruntime/core/sys/windows/aclapi.d b/libphobos/libdruntime/core/sys/windows/aclapi.d index f145ac26af0..4905351b565 100644 --- a/libphobos/libdruntime/core/sys/windows/aclapi.d +++ b/libphobos/libdruntime/core/sys/windows/aclapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.aclapi; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "advapi32"); diff --git a/libphobos/libdruntime/core/sys/windows/aclui.d b/libphobos/libdruntime/core/sys/windows/aclui.d index c5a28992631..08be626ad2d 100644 --- a/libphobos/libdruntime/core/sys/windows/aclui.d +++ b/libphobos/libdruntime/core/sys/windows/aclui.d @@ -9,7 +9,6 @@ */ module core.sys.windows.aclui; version (Windows): -@system: pragma(lib, "aclui"); import core.sys.windows.w32api; diff --git a/libphobos/libdruntime/core/sys/windows/basetsd.d b/libphobos/libdruntime/core/sys/windows/basetsd.d index 0c689024aaa..3c5c35f6603 100644 --- a/libphobos/libdruntime/core/sys/windows/basetsd.d +++ b/libphobos/libdruntime/core/sys/windows/basetsd.d @@ -9,7 +9,6 @@ */ module core.sys.windows.basetsd; version (Windows): -@system: /* This template is used in these modules to declare constant pointer types, * in order to support both D 1.x and 2.x. diff --git a/libphobos/libdruntime/core/sys/windows/basetyps.d b/libphobos/libdruntime/core/sys/windows/basetyps.d index 086e6ab30e3..d90d9f3425a 100644 --- a/libphobos/libdruntime/core/sys/windows/basetyps.d +++ b/libphobos/libdruntime/core/sys/windows/basetyps.d @@ -8,7 +8,6 @@ */ module core.sys.windows.basetyps; version (Windows): -@system: import core.sys.windows.windef, core.sys.windows.basetsd; diff --git a/libphobos/libdruntime/core/sys/windows/com.d b/libphobos/libdruntime/core/sys/windows/com.d index 6935dd94f95..c724f1c9e10 100644 --- a/libphobos/libdruntime/core/sys/windows/com.d +++ b/libphobos/libdruntime/core/sys/windows/com.d @@ -1,6 +1,5 @@ module core.sys.windows.com; version (Windows): -@system: pragma(lib,"uuid"); diff --git a/libphobos/libdruntime/core/sys/windows/comcat.d b/libphobos/libdruntime/core/sys/windows/comcat.d index 3018c64d7f0..4cc35f467f7 100644 --- a/libphobos/libdruntime/core/sys/windows/comcat.d +++ b/libphobos/libdruntime/core/sys/windows/comcat.d @@ -9,7 +9,6 @@ */ module core.sys.windows.comcat; version (Windows): -@system: import core.sys.windows.ole2; import core.sys.windows.basetyps, core.sys.windows.cguid, core.sys.windows.objbase, core.sys.windows.unknwn, diff --git a/libphobos/libdruntime/core/sys/windows/commctrl.d b/libphobos/libdruntime/core/sys/windows/commctrl.d index 4bc60b1fd8b..dabee5672b9 100644 --- a/libphobos/libdruntime/core/sys/windows/commctrl.d +++ b/libphobos/libdruntime/core/sys/windows/commctrl.d @@ -8,7 +8,6 @@ */ module core.sys.windows.commctrl; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "comctl32"); diff --git a/libphobos/libdruntime/core/sys/windows/commdlg.d b/libphobos/libdruntime/core/sys/windows/commdlg.d index b49d2fba6fe..9be9a9f1f21 100644 --- a/libphobos/libdruntime/core/sys/windows/commdlg.d +++ b/libphobos/libdruntime/core/sys/windows/commdlg.d @@ -8,7 +8,6 @@ */ module core.sys.windows.commdlg; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "comdlg32"); diff --git a/libphobos/libdruntime/core/sys/windows/cpl.d b/libphobos/libdruntime/core/sys/windows/cpl.d index 49ebb208c74..df98703520e 100644 --- a/libphobos/libdruntime/core/sys/windows/cpl.d +++ b/libphobos/libdruntime/core/sys/windows/cpl.d @@ -9,7 +9,6 @@ */ module core.sys.windows.cpl; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/cplext.d b/libphobos/libdruntime/core/sys/windows/cplext.d index e13316bcec9..4aff3a9640f 100644 --- a/libphobos/libdruntime/core/sys/windows/cplext.d +++ b/libphobos/libdruntime/core/sys/windows/cplext.d @@ -9,7 +9,6 @@ */ module core.sys.windows.cplext; version (Windows): -@system: enum : uint { CPLPAGE_MOUSE_BUTTONS = 1, diff --git a/libphobos/libdruntime/core/sys/windows/custcntl.d b/libphobos/libdruntime/core/sys/windows/custcntl.d index c736cb31a9c..f9234ac4f89 100644 --- a/libphobos/libdruntime/core/sys/windows/custcntl.d +++ b/libphobos/libdruntime/core/sys/windows/custcntl.d @@ -9,7 +9,6 @@ */ module core.sys.windows.custcntl; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp.d b/libphobos/libdruntime/core/sys/windows/dbghelp.d index 96698e8f0f9..de14bce94ee 100644 --- a/libphobos/libdruntime/core/sys/windows/dbghelp.d +++ b/libphobos/libdruntime/core/sys/windows/dbghelp.d @@ -11,7 +11,6 @@ module core.sys.windows.dbghelp; version (Windows): -@system: import core.sys.windows.winbase /+: FreeLibrary, GetProcAddress, LoadLibraryA+/; import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/dbghelp_types.d b/libphobos/libdruntime/core/sys/windows/dbghelp_types.d index 64477df96ff..f75f98bc882 100644 --- a/libphobos/libdruntime/core/sys/windows/dbghelp_types.d +++ b/libphobos/libdruntime/core/sys/windows/dbghelp_types.d @@ -11,7 +11,6 @@ module core.sys.windows.dbghelp_types; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/dbt.d b/libphobos/libdruntime/core/sys/windows/dbt.d index 308c609a9ba..41f1c32a419 100644 --- a/libphobos/libdruntime/core/sys/windows/dbt.d +++ b/libphobos/libdruntime/core/sys/windows/dbt.d @@ -9,7 +9,6 @@ */ module core.sys.windows.dbt; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/dde.d b/libphobos/libdruntime/core/sys/windows/dde.d index bec339c223c..d9b8bec5152 100644 --- a/libphobos/libdruntime/core/sys/windows/dde.d +++ b/libphobos/libdruntime/core/sys/windows/dde.d @@ -9,7 +9,6 @@ */ module core.sys.windows.dde; version (Windows): -@system: pragma(lib, "user32"); import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/ddeml.d b/libphobos/libdruntime/core/sys/windows/ddeml.d index 22b330cfc47..00bad1d300d 100644 --- a/libphobos/libdruntime/core/sys/windows/ddeml.d +++ b/libphobos/libdruntime/core/sys/windows/ddeml.d @@ -9,7 +9,6 @@ */ module core.sys.windows.ddeml; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "user32"); diff --git a/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d b/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d index 0d3d71690b8..d21169a7346 100644 --- a/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d +++ b/libphobos/libdruntime/core/sys/windows/dhcpcsdk.d @@ -9,7 +9,6 @@ */ module core.sys.windows.dhcpcsdk; version (Windows): -@system: import core.sys.windows.w32api, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/dlgs.d b/libphobos/libdruntime/core/sys/windows/dlgs.d index 34cab9bea2a..52568629f3d 100644 --- a/libphobos/libdruntime/core/sys/windows/dlgs.d +++ b/libphobos/libdruntime/core/sys/windows/dlgs.d @@ -9,7 +9,6 @@ */ module core.sys.windows.dlgs; version (Windows): -@system: import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d index d602347f2a3..367c1d90d93 100644 --- a/libphobos/libdruntime/core/sys/windows/dll.d +++ b/libphobos/libdruntime/core/sys/windows/dll.d @@ -14,7 +14,6 @@ */ module core.sys.windows.dll; version (Windows): -@system: import core.sys.windows.winbase; import core.sys.windows.winnt; diff --git a/libphobos/libdruntime/core/sys/windows/docobj.d b/libphobos/libdruntime/core/sys/windows/docobj.d index 4e45693eb3d..4abbea31241 100644 --- a/libphobos/libdruntime/core/sys/windows/docobj.d +++ b/libphobos/libdruntime/core/sys/windows/docobj.d @@ -8,7 +8,6 @@ */ module core.sys.windows.docobj; version (Windows): -@system: import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.objidl, core.sys.windows.oleidl, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; diff --git a/libphobos/libdruntime/core/sys/windows/errorrep.d b/libphobos/libdruntime/core/sys/windows/errorrep.d index 63ec8d75746..42fad9a39ec 100644 --- a/libphobos/libdruntime/core/sys/windows/errorrep.d +++ b/libphobos/libdruntime/core/sys/windows/errorrep.d @@ -9,7 +9,6 @@ */ module core.sys.windows.errorrep; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/exdisp.d b/libphobos/libdruntime/core/sys/windows/exdisp.d index 8ee3c267371..5a9ea980446 100644 --- a/libphobos/libdruntime/core/sys/windows/exdisp.d +++ b/libphobos/libdruntime/core/sys/windows/exdisp.d @@ -8,7 +8,6 @@ */ module core.sys.windows.exdisp; version (Windows): -@system: import core.sys.windows.docobj, core.sys.windows.oaidl, core.sys.windows.ocidl; import core.sys.windows.basetyps, core.sys.windows.windef, core.sys.windows.wtypes; diff --git a/libphobos/libdruntime/core/sys/windows/httpext.d b/libphobos/libdruntime/core/sys/windows/httpext.d index 4e07c6aa15c..6973879abf3 100644 --- a/libphobos/libdruntime/core/sys/windows/httpext.d +++ b/libphobos/libdruntime/core/sys/windows/httpext.d @@ -8,7 +8,6 @@ */ module core.sys.windows.httpext; version (Windows): -@system: /* Comment from MinGW httpext.h - Header for ISAPI extensions. diff --git a/libphobos/libdruntime/core/sys/windows/imagehlp.d b/libphobos/libdruntime/core/sys/windows/imagehlp.d index ed93746d7f6..399c0b2b1af 100644 --- a/libphobos/libdruntime/core/sys/windows/imagehlp.d +++ b/libphobos/libdruntime/core/sys/windows/imagehlp.d @@ -9,7 +9,6 @@ */ module core.sys.windows.imagehlp; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/imm.d b/libphobos/libdruntime/core/sys/windows/imm.d index 128fd56e87c..4ad678c9b4d 100644 --- a/libphobos/libdruntime/core/sys/windows/imm.d +++ b/libphobos/libdruntime/core/sys/windows/imm.d @@ -8,7 +8,6 @@ */ module core.sys.windows.imm; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "imm32"); diff --git a/libphobos/libdruntime/core/sys/windows/intshcut.d b/libphobos/libdruntime/core/sys/windows/intshcut.d index eab7a8dafe2..ab662e418e7 100644 --- a/libphobos/libdruntime/core/sys/windows/intshcut.d +++ b/libphobos/libdruntime/core/sys/windows/intshcut.d @@ -9,7 +9,6 @@ */ module core.sys.windows.intshcut; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/ipexport.d b/libphobos/libdruntime/core/sys/windows/ipexport.d index dbb4a0eb5ff..b0a4a0151ab 100644 --- a/libphobos/libdruntime/core/sys/windows/ipexport.d +++ b/libphobos/libdruntime/core/sys/windows/ipexport.d @@ -9,7 +9,6 @@ */ module core.sys.windows.ipexport; version (Windows): -@system: import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/iphlpapi.d b/libphobos/libdruntime/core/sys/windows/iphlpapi.d index f95e7990935..4a8e64cbef0 100644 --- a/libphobos/libdruntime/core/sys/windows/iphlpapi.d +++ b/libphobos/libdruntime/core/sys/windows/iphlpapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.iphlpapi; version (Windows): -@system: import core.sys.windows.ipexport, core.sys.windows.iprtrmib, core.sys.windows.iptypes; import core.sys.windows.winbase, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/iprtrmib.d b/libphobos/libdruntime/core/sys/windows/iprtrmib.d index 3db453908a1..05c31b3dd07 100644 --- a/libphobos/libdruntime/core/sys/windows/iprtrmib.d +++ b/libphobos/libdruntime/core/sys/windows/iprtrmib.d @@ -9,7 +9,6 @@ */ module core.sys.windows.iprtrmib; version (Windows): -@system: import core.sys.windows.ipifcons; import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/iptypes.d b/libphobos/libdruntime/core/sys/windows/iptypes.d index 7cce34b0ebe..baaf6ae765b 100644 --- a/libphobos/libdruntime/core/sys/windows/iptypes.d +++ b/libphobos/libdruntime/core/sys/windows/iptypes.d @@ -9,7 +9,6 @@ */ module core.sys.windows.iptypes; version (Windows): -@system: import core.sys.windows.windef; import core.stdc.time; diff --git a/libphobos/libdruntime/core/sys/windows/lm.d b/libphobos/libdruntime/core/sys/windows/lm.d index 3d488564e57..115925c2c06 100644 --- a/libphobos/libdruntime/core/sys/windows/lm.d +++ b/libphobos/libdruntime/core/sys/windows/lm.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lm; version (Windows): -@system: /* removed - now supporting only Win2k up version (WindowsVista) { diff --git a/libphobos/libdruntime/core/sys/windows/lmaccess.d b/libphobos/libdruntime/core/sys/windows/lmaccess.d index b23e52ed6f9..9791ff6e391 100644 --- a/libphobos/libdruntime/core/sys/windows/lmaccess.d +++ b/libphobos/libdruntime/core/sys/windows/lmaccess.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmaccess; version (Windows): -@system: pragma(lib, "netapi32"); /** diff --git a/libphobos/libdruntime/core/sys/windows/lmalert.d b/libphobos/libdruntime/core/sys/windows/lmalert.d index 5ddd6d0988c..ad0c3ca7b18 100644 --- a/libphobos/libdruntime/core/sys/windows/lmalert.d +++ b/libphobos/libdruntime/core/sys/windows/lmalert.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmalert; version (Windows): -@system: pragma(lib, "netapi32"); import core.sys.windows.lmcons, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/lmat.d b/libphobos/libdruntime/core/sys/windows/lmat.d index 3e1468a0e83..ee1249e9157 100644 --- a/libphobos/libdruntime/core/sys/windows/lmat.d +++ b/libphobos/libdruntime/core/sys/windows/lmat.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmat; version (Windows): -@system: pragma(lib, "netapi32"); import core.sys.windows.lmcons, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/lmaudit.d b/libphobos/libdruntime/core/sys/windows/lmaudit.d index f4a7ca243e8..8db56f17631 100644 --- a/libphobos/libdruntime/core/sys/windows/lmaudit.d +++ b/libphobos/libdruntime/core/sys/windows/lmaudit.d @@ -9,7 +9,6 @@ // COMMENT: This file may be deprecated. module core.sys.windows.lmaudit; version (Windows): -@system: import core.sys.windows.lmcons, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/lmbrowsr.d b/libphobos/libdruntime/core/sys/windows/lmbrowsr.d index ea0e0f38ced..16cc6611394 100644 --- a/libphobos/libdruntime/core/sys/windows/lmbrowsr.d +++ b/libphobos/libdruntime/core/sys/windows/lmbrowsr.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmbrowsr; version (Windows): -@system: import core.sys.windows.lmcons, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/lmchdev.d b/libphobos/libdruntime/core/sys/windows/lmchdev.d index 00aaafcf50d..55460e16bdf 100644 --- a/libphobos/libdruntime/core/sys/windows/lmchdev.d +++ b/libphobos/libdruntime/core/sys/windows/lmchdev.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmchdev; version (Windows): -@system: // COMMENT: This file might be deprecated. diff --git a/libphobos/libdruntime/core/sys/windows/lmconfig.d b/libphobos/libdruntime/core/sys/windows/lmconfig.d index 57d3ed938fb..6652a521448 100644 --- a/libphobos/libdruntime/core/sys/windows/lmconfig.d +++ b/libphobos/libdruntime/core/sys/windows/lmconfig.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmconfig; version (Windows): -@system: // All functions in this file are deprecated! diff --git a/libphobos/libdruntime/core/sys/windows/lmcons.d b/libphobos/libdruntime/core/sys/windows/lmcons.d index 69a63df0f19..838748a1387 100644 --- a/libphobos/libdruntime/core/sys/windows/lmcons.d +++ b/libphobos/libdruntime/core/sys/windows/lmcons.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmcons; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/lmerr.d b/libphobos/libdruntime/core/sys/windows/lmerr.d index d50ec49dcb8..23f5e59cb93 100644 --- a/libphobos/libdruntime/core/sys/windows/lmerr.d +++ b/libphobos/libdruntime/core/sys/windows/lmerr.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmerr; version (Windows): -@system: import core.sys.windows.winerror; diff --git a/libphobos/libdruntime/core/sys/windows/lmerrlog.d b/libphobos/libdruntime/core/sys/windows/lmerrlog.d index a49b4988825..effe73a9ae5 100644 --- a/libphobos/libdruntime/core/sys/windows/lmerrlog.d +++ b/libphobos/libdruntime/core/sys/windows/lmerrlog.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmerrlog; version (Windows): -@system: // COMMENT: This appears to be only for Win16. All functions are deprecated. diff --git a/libphobos/libdruntime/core/sys/windows/lmmsg.d b/libphobos/libdruntime/core/sys/windows/lmmsg.d index c87f1e00ed3..a3abd605422 100644 --- a/libphobos/libdruntime/core/sys/windows/lmmsg.d +++ b/libphobos/libdruntime/core/sys/windows/lmmsg.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmmsg; version (Windows): -@system: pragma(lib, "netapi32"); import core.sys.windows.lmcons, core.sys.windows.windef, core.sys.windows.w32api; diff --git a/libphobos/libdruntime/core/sys/windows/lmremutl.d b/libphobos/libdruntime/core/sys/windows/lmremutl.d index d0f3b41cc38..8c90df73f2a 100644 --- a/libphobos/libdruntime/core/sys/windows/lmremutl.d +++ b/libphobos/libdruntime/core/sys/windows/lmremutl.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmremutl; version (Windows): -@system: pragma(lib, "netapi32"); // D Conversion Note: DESC_CHAR is defined as TCHAR. diff --git a/libphobos/libdruntime/core/sys/windows/lmrepl.d b/libphobos/libdruntime/core/sys/windows/lmrepl.d index 093588ca84e..1563a5e2902 100644 --- a/libphobos/libdruntime/core/sys/windows/lmrepl.d +++ b/libphobos/libdruntime/core/sys/windows/lmrepl.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmrepl; version (Windows): -@system: pragma(lib, "netapi32"); import core.sys.windows.lmcons, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/lmserver.d b/libphobos/libdruntime/core/sys/windows/lmserver.d index fad5bc509c4..5a550bca80d 100644 --- a/libphobos/libdruntime/core/sys/windows/lmserver.d +++ b/libphobos/libdruntime/core/sys/windows/lmserver.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmserver; version (Windows): -@system: import core.sys.windows.winsvc; import core.sys.windows.lmcons, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/lmshare.d b/libphobos/libdruntime/core/sys/windows/lmshare.d index d81080edda1..bd8eecb46dd 100644 --- a/libphobos/libdruntime/core/sys/windows/lmshare.d +++ b/libphobos/libdruntime/core/sys/windows/lmshare.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmshare; version (Windows): -@system: pragma(lib, "netapi32"); import core.sys.windows.lmcons; diff --git a/libphobos/libdruntime/core/sys/windows/lmsname.d b/libphobos/libdruntime/core/sys/windows/lmsname.d index 09b1b00cb6d..a8f4f762081 100644 --- a/libphobos/libdruntime/core/sys/windows/lmsname.d +++ b/libphobos/libdruntime/core/sys/windows/lmsname.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmsname; version (Windows): -@system: import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/lmstats.d b/libphobos/libdruntime/core/sys/windows/lmstats.d index 4baa3903b15..e83808b12a7 100644 --- a/libphobos/libdruntime/core/sys/windows/lmstats.d +++ b/libphobos/libdruntime/core/sys/windows/lmstats.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmstats; version (Windows): -@system: pragma(lib, "netapi32"); import core.sys.windows.lmcons, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/lmsvc.d b/libphobos/libdruntime/core/sys/windows/lmsvc.d index c0df69902e0..ddea61c7d0b 100644 --- a/libphobos/libdruntime/core/sys/windows/lmsvc.d +++ b/libphobos/libdruntime/core/sys/windows/lmsvc.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmsvc; version (Windows): -@system: // FIXME: Is this file deprecated? All of the functions are only for Win16. /** diff --git a/libphobos/libdruntime/core/sys/windows/lmuse.d b/libphobos/libdruntime/core/sys/windows/lmuse.d index 03e153abea8..a48d72e0050 100644 --- a/libphobos/libdruntime/core/sys/windows/lmuse.d +++ b/libphobos/libdruntime/core/sys/windows/lmuse.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmuse; version (Windows): -@system: pragma(lib, "netapi32"); import core.sys.windows.lmuseflg; diff --git a/libphobos/libdruntime/core/sys/windows/lmwksta.d b/libphobos/libdruntime/core/sys/windows/lmwksta.d index cdd3a070365..29ddca76d89 100644 --- a/libphobos/libdruntime/core/sys/windows/lmwksta.d +++ b/libphobos/libdruntime/core/sys/windows/lmwksta.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lmwksta; version (Windows): -@system: pragma(lib, "netapi32"); import core.sys.windows.lmuseflg; diff --git a/libphobos/libdruntime/core/sys/windows/lzexpand.d b/libphobos/libdruntime/core/sys/windows/lzexpand.d index a01489bef57..6c3bd0084fe 100644 --- a/libphobos/libdruntime/core/sys/windows/lzexpand.d +++ b/libphobos/libdruntime/core/sys/windows/lzexpand.d @@ -8,7 +8,6 @@ */ module core.sys.windows.lzexpand; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "lz32"); diff --git a/libphobos/libdruntime/core/sys/windows/mapi.d b/libphobos/libdruntime/core/sys/windows/mapi.d index 06fd955611c..8f8eea1e12b 100644 --- a/libphobos/libdruntime/core/sys/windows/mapi.d +++ b/libphobos/libdruntime/core/sys/windows/mapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.mapi; version (Windows): -@system: import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/mciavi.d b/libphobos/libdruntime/core/sys/windows/mciavi.d index 4e3d14e0b6a..08410f5834c 100644 --- a/libphobos/libdruntime/core/sys/windows/mciavi.d +++ b/libphobos/libdruntime/core/sys/windows/mciavi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.mciavi; version (Windows): -@system: import core.sys.windows.mmsystem; diff --git a/libphobos/libdruntime/core/sys/windows/mcx.d b/libphobos/libdruntime/core/sys/windows/mcx.d index 03224130137..5c6ac24a315 100644 --- a/libphobos/libdruntime/core/sys/windows/mcx.d +++ b/libphobos/libdruntime/core/sys/windows/mcx.d @@ -9,7 +9,6 @@ */ module core.sys.windows.mcx; version (Windows): -@system: import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/mgmtapi.d b/libphobos/libdruntime/core/sys/windows/mgmtapi.d index d9fb6b72a9c..8f84eea54e8 100644 --- a/libphobos/libdruntime/core/sys/windows/mgmtapi.d +++ b/libphobos/libdruntime/core/sys/windows/mgmtapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.mgmtapi; version (Windows): -@system: import core.sys.windows.snmp; import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/mmsystem.d b/libphobos/libdruntime/core/sys/windows/mmsystem.d index 5c3d9207118..7e7c34ba4f0 100644 --- a/libphobos/libdruntime/core/sys/windows/mmsystem.d +++ b/libphobos/libdruntime/core/sys/windows/mmsystem.d @@ -8,7 +8,6 @@ */ module core.sys.windows.mmsystem; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "winmm"); diff --git a/libphobos/libdruntime/core/sys/windows/msacm.d b/libphobos/libdruntime/core/sys/windows/msacm.d index 47263282fb1..645e40d4ecb 100644 --- a/libphobos/libdruntime/core/sys/windows/msacm.d +++ b/libphobos/libdruntime/core/sys/windows/msacm.d @@ -9,7 +9,6 @@ */ module core.sys.windows.msacm; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/mshtml.d b/libphobos/libdruntime/core/sys/windows/mshtml.d index d5cf7cbc012..d20c4bbb304 100644 --- a/libphobos/libdruntime/core/sys/windows/mshtml.d +++ b/libphobos/libdruntime/core/sys/windows/mshtml.d @@ -8,7 +8,6 @@ */ module core.sys.windows.mshtml; version (Windows): -@system: import core.sys.windows.basetyps, core.sys.windows.oaidl, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; diff --git a/libphobos/libdruntime/core/sys/windows/mswsock.d b/libphobos/libdruntime/core/sys/windows/mswsock.d index 27c0cdb5bb2..d8beee421a1 100644 --- a/libphobos/libdruntime/core/sys/windows/mswsock.d +++ b/libphobos/libdruntime/core/sys/windows/mswsock.d @@ -9,7 +9,6 @@ */ module core.sys.windows.mswsock; version (Windows): -@system: import core.sys.windows.winbase, core.sys.windows.windef; import core.sys.windows.basetyps, core.sys.windows.w32api; diff --git a/libphobos/libdruntime/core/sys/windows/nb30.d b/libphobos/libdruntime/core/sys/windows/nb30.d index 8f92eddba17..cfa57d609e3 100644 --- a/libphobos/libdruntime/core/sys/windows/nb30.d +++ b/libphobos/libdruntime/core/sys/windows/nb30.d @@ -9,7 +9,6 @@ */ module core.sys.windows.nb30; version (Windows): -@system: import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/nddeapi.d b/libphobos/libdruntime/core/sys/windows/nddeapi.d index dc3890c6118..3efca620e17 100644 --- a/libphobos/libdruntime/core/sys/windows/nddeapi.d +++ b/libphobos/libdruntime/core/sys/windows/nddeapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.nddeapi; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/nspapi.d b/libphobos/libdruntime/core/sys/windows/nspapi.d index 79c9fceb45c..bac6526849d 100644 --- a/libphobos/libdruntime/core/sys/windows/nspapi.d +++ b/libphobos/libdruntime/core/sys/windows/nspapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.nspapi; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/ntdef.d b/libphobos/libdruntime/core/sys/windows/ntdef.d index 78e60e77749..a0213dc56f0 100644 --- a/libphobos/libdruntime/core/sys/windows/ntdef.d +++ b/libphobos/libdruntime/core/sys/windows/ntdef.d @@ -9,7 +9,6 @@ */ module core.sys.windows.ntdef; version (Windows): -@system: import core.sys.windows.basetsd, core.sys.windows.subauth, core.sys.windows.windef, core.sys.windows.winnt; diff --git a/libphobos/libdruntime/core/sys/windows/ntdll.d b/libphobos/libdruntime/core/sys/windows/ntdll.d index 4ac1bcccbb9..28d560c537b 100644 --- a/libphobos/libdruntime/core/sys/windows/ntdll.d +++ b/libphobos/libdruntime/core/sys/windows/ntdll.d @@ -9,7 +9,6 @@ */ module core.sys.windows.ntdll; version (Windows): -@system: import core.sys.windows.w32api; diff --git a/libphobos/libdruntime/core/sys/windows/ntldap.d b/libphobos/libdruntime/core/sys/windows/ntldap.d index 52caddec763..8f9abfe45dd 100644 --- a/libphobos/libdruntime/core/sys/windows/ntldap.d +++ b/libphobos/libdruntime/core/sys/windows/ntldap.d @@ -9,7 +9,6 @@ */ module core.sys.windows.ntldap; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/ntsecapi.d b/libphobos/libdruntime/core/sys/windows/ntsecapi.d index 1118057b4c9..fbc6b7f6b99 100644 --- a/libphobos/libdruntime/core/sys/windows/ntsecapi.d +++ b/libphobos/libdruntime/core/sys/windows/ntsecapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.ntsecapi; version (Windows): -@system: pragma(lib, "advapi32"); version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/ntsecpkg.d b/libphobos/libdruntime/core/sys/windows/ntsecpkg.d index d8c5e95edbd..56803b043c4 100644 --- a/libphobos/libdruntime/core/sys/windows/ntsecpkg.d +++ b/libphobos/libdruntime/core/sys/windows/ntsecpkg.d @@ -9,7 +9,6 @@ */ module core.sys.windows.ntsecpkg; version (Windows): -@system: import core.sys.windows.windef, core.sys.windows.ntsecapi, core.sys.windows.security, core.sys.windows.ntdef, core.sys.windows.sspi; import core.sys.windows.basetyps : GUID; diff --git a/libphobos/libdruntime/core/sys/windows/oaidl.d b/libphobos/libdruntime/core/sys/windows/oaidl.d index 6c9368241f1..cd11061d0bb 100644 --- a/libphobos/libdruntime/core/sys/windows/oaidl.d +++ b/libphobos/libdruntime/core/sys/windows/oaidl.d @@ -8,7 +8,6 @@ */ module core.sys.windows.oaidl; version (Windows): -@system: import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; diff --git a/libphobos/libdruntime/core/sys/windows/objbase.d b/libphobos/libdruntime/core/sys/windows/objbase.d index bb9e7ea0240..350c2b88396 100644 --- a/libphobos/libdruntime/core/sys/windows/objbase.d +++ b/libphobos/libdruntime/core/sys/windows/objbase.d @@ -8,7 +8,6 @@ */ module core.sys.windows.objbase; version (Windows): -@system: nothrow: pragma(lib, "ole32"); diff --git a/libphobos/libdruntime/core/sys/windows/objfwd.d b/libphobos/libdruntime/core/sys/windows/objfwd.d index 89d5cad90db..076e02e608c 100644 --- a/libphobos/libdruntime/core/sys/windows/objfwd.d +++ b/libphobos/libdruntime/core/sys/windows/objfwd.d @@ -8,7 +8,6 @@ */ module core.sys.windows.objfwd; version (Windows): -@system: import core.sys.windows.objidl; diff --git a/libphobos/libdruntime/core/sys/windows/objidl.d b/libphobos/libdruntime/core/sys/windows/objidl.d index 528c58b2789..aa51840a51c 100644 --- a/libphobos/libdruntime/core/sys/windows/objidl.d +++ b/libphobos/libdruntime/core/sys/windows/objidl.d @@ -12,7 +12,6 @@ // # do we need the proxies that are defined in this file? module core.sys.windows.objidl; version (Windows): -@system: import core.sys.windows.unknwn; import core.sys.windows.objfwd; diff --git a/libphobos/libdruntime/core/sys/windows/objsafe.d b/libphobos/libdruntime/core/sys/windows/objsafe.d index 449a4c3166d..f7dc445cb05 100644 --- a/libphobos/libdruntime/core/sys/windows/objsafe.d +++ b/libphobos/libdruntime/core/sys/windows/objsafe.d @@ -9,7 +9,6 @@ */ module core.sys.windows.objsafe; version (Windows): -@system: import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/ocidl.d b/libphobos/libdruntime/core/sys/windows/ocidl.d index af42beaf159..9bacbf0f34f 100644 --- a/libphobos/libdruntime/core/sys/windows/ocidl.d +++ b/libphobos/libdruntime/core/sys/windows/ocidl.d @@ -10,7 +10,6 @@ */ module core.sys.windows.ocidl; version (Windows): -@system: import core.sys.windows.ole2, core.sys.windows.oleidl, core.sys.windows.oaidl, core.sys.windows.objfwd, core.sys.windows.windef, core.sys.windows.wtypes; diff --git a/libphobos/libdruntime/core/sys/windows/odbcinst.d b/libphobos/libdruntime/core/sys/windows/odbcinst.d index b0ca42adf12..ebacb5889ff 100644 --- a/libphobos/libdruntime/core/sys/windows/odbcinst.d +++ b/libphobos/libdruntime/core/sys/windows/odbcinst.d @@ -8,7 +8,6 @@ */ module core.sys.windows.odbcinst; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/ole.d b/libphobos/libdruntime/core/sys/windows/ole.d index 21218f11605..c29ec5047ff 100644 --- a/libphobos/libdruntime/core/sys/windows/ole.d +++ b/libphobos/libdruntime/core/sys/windows/ole.d @@ -9,7 +9,6 @@ */ module core.sys.windows.ole; version (Windows): -@system: pragma(lib, "ole32"); import core.sys.windows.windef, core.sys.windows.wingdi, core.sys.windows.uuid; diff --git a/libphobos/libdruntime/core/sys/windows/ole2.d b/libphobos/libdruntime/core/sys/windows/ole2.d index 0945fcaca26..3fef058411f 100644 --- a/libphobos/libdruntime/core/sys/windows/ole2.d +++ b/libphobos/libdruntime/core/sys/windows/ole2.d @@ -8,7 +8,6 @@ */ module core.sys.windows.ole2; version (Windows): -@system: pragma(lib, "ole32"); public import core.sys.windows.basetyps, core.sys.windows.objbase, core.sys.windows.oleauto, core.sys.windows.olectlid, diff --git a/libphobos/libdruntime/core/sys/windows/oleacc.d b/libphobos/libdruntime/core/sys/windows/oleacc.d index 77137c6b617..b19855d9af0 100644 --- a/libphobos/libdruntime/core/sys/windows/oleacc.d +++ b/libphobos/libdruntime/core/sys/windows/oleacc.d @@ -8,7 +8,6 @@ */ module core.sys.windows.oleacc; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "oleacc"); diff --git a/libphobos/libdruntime/core/sys/windows/oleauto.d b/libphobos/libdruntime/core/sys/windows/oleauto.d index f8d76e15bef..188813609ff 100644 --- a/libphobos/libdruntime/core/sys/windows/oleauto.d +++ b/libphobos/libdruntime/core/sys/windows/oleauto.d @@ -8,7 +8,6 @@ */ module core.sys.windows.oleauto; version (Windows): -@system: pragma(lib, "oleaut32"); import core.sys.windows.oaidl; diff --git a/libphobos/libdruntime/core/sys/windows/olectl.d b/libphobos/libdruntime/core/sys/windows/olectl.d index f671ce44804..df8266b142d 100644 --- a/libphobos/libdruntime/core/sys/windows/olectl.d +++ b/libphobos/libdruntime/core/sys/windows/olectl.d @@ -8,7 +8,6 @@ */ module core.sys.windows.olectl; version (Windows): -@system: // In conversion from MinGW, the following was deleted: //#define FONTSIZE(n) {n##0000, 0} diff --git a/libphobos/libdruntime/core/sys/windows/oledlg.d b/libphobos/libdruntime/core/sys/windows/oledlg.d index f1a05104d43..f810f6c13da 100644 --- a/libphobos/libdruntime/core/sys/windows/oledlg.d +++ b/libphobos/libdruntime/core/sys/windows/oledlg.d @@ -7,7 +7,6 @@ * Source: $(DRUNTIMESRC core/sys/windows/_oledlg.d) */ module core.sys.windows.oledlg; -@system: version (Windows): version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/oleidl.d b/libphobos/libdruntime/core/sys/windows/oleidl.d index 4ef564d20a5..17e1d647b32 100644 --- a/libphobos/libdruntime/core/sys/windows/oleidl.d +++ b/libphobos/libdruntime/core/sys/windows/oleidl.d @@ -8,7 +8,6 @@ */ module core.sys.windows.oleidl; version (Windows): -@system: // DAC: This is defined in ocidl !! // what is it doing in here? diff --git a/libphobos/libdruntime/core/sys/windows/pbt.d b/libphobos/libdruntime/core/sys/windows/pbt.d index 3b65ba58649..268988484dd 100644 --- a/libphobos/libdruntime/core/sys/windows/pbt.d +++ b/libphobos/libdruntime/core/sys/windows/pbt.d @@ -9,7 +9,6 @@ */ module core.sys.windows.pbt; version (Windows): -@system: import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/powrprof.d b/libphobos/libdruntime/core/sys/windows/powrprof.d index 275dbeabd07..be4d0aa2d20 100644 --- a/libphobos/libdruntime/core/sys/windows/powrprof.d +++ b/libphobos/libdruntime/core/sys/windows/powrprof.d @@ -9,7 +9,6 @@ */ module core.sys.windows.powrprof; version (Windows): -@system: pragma(lib, "powrprof"); import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/prsht.d b/libphobos/libdruntime/core/sys/windows/prsht.d index ba04b5743c4..92596b5b548 100644 --- a/libphobos/libdruntime/core/sys/windows/prsht.d +++ b/libphobos/libdruntime/core/sys/windows/prsht.d @@ -9,7 +9,6 @@ */ module core.sys.windows.prsht; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "comctl32"); diff --git a/libphobos/libdruntime/core/sys/windows/psapi.d b/libphobos/libdruntime/core/sys/windows/psapi.d index 585f9088813..968ce6c4530 100644 --- a/libphobos/libdruntime/core/sys/windows/psapi.d +++ b/libphobos/libdruntime/core/sys/windows/psapi.d @@ -13,7 +13,6 @@ module core.sys.windows.psapi; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/rapi.d b/libphobos/libdruntime/core/sys/windows/rapi.d index 086b7a6023b..2fc640468b9 100644 --- a/libphobos/libdruntime/core/sys/windows/rapi.d +++ b/libphobos/libdruntime/core/sys/windows/rapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.rapi; version (Windows): -@system: /* Comment from MinGW NOTE: This strictly does not belong in the Win32 API since it's diff --git a/libphobos/libdruntime/core/sys/windows/ras.d b/libphobos/libdruntime/core/sys/windows/ras.d index 1f665461b9c..cb69686e9bc 100644 --- a/libphobos/libdruntime/core/sys/windows/ras.d +++ b/libphobos/libdruntime/core/sys/windows/ras.d @@ -8,7 +8,6 @@ */ module core.sys.windows.ras; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "rasapi32"); diff --git a/libphobos/libdruntime/core/sys/windows/rasdlg.d b/libphobos/libdruntime/core/sys/windows/rasdlg.d index 1add3ae1479..a980d270f89 100644 --- a/libphobos/libdruntime/core/sys/windows/rasdlg.d +++ b/libphobos/libdruntime/core/sys/windows/rasdlg.d @@ -9,7 +9,6 @@ */ module core.sys.windows.rasdlg; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/raserror.d b/libphobos/libdruntime/core/sys/windows/raserror.d index c21409b379b..48a275625fc 100644 --- a/libphobos/libdruntime/core/sys/windows/raserror.d +++ b/libphobos/libdruntime/core/sys/windows/raserror.d @@ -8,7 +8,6 @@ */ module core.sys.windows.raserror; version (Windows): -@system: enum { SUCCESS = 0, diff --git a/libphobos/libdruntime/core/sys/windows/rassapi.d b/libphobos/libdruntime/core/sys/windows/rassapi.d index aed14f162f8..5244ca41157 100644 --- a/libphobos/libdruntime/core/sys/windows/rassapi.d +++ b/libphobos/libdruntime/core/sys/windows/rassapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.rassapi; version (Windows): -@system: import core.sys.windows.lmcons, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/reason.d b/libphobos/libdruntime/core/sys/windows/reason.d index 4274efa33ed..e1fb1cabdf1 100644 --- a/libphobos/libdruntime/core/sys/windows/reason.d +++ b/libphobos/libdruntime/core/sys/windows/reason.d @@ -9,7 +9,6 @@ */ module core.sys.windows.reason; version (Windows): -@system: import core.sys.windows.w32api, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/regstr.d b/libphobos/libdruntime/core/sys/windows/regstr.d index 71a86ef8700..f8851fa720b 100644 --- a/libphobos/libdruntime/core/sys/windows/regstr.d +++ b/libphobos/libdruntime/core/sys/windows/regstr.d @@ -8,7 +8,6 @@ */ module core.sys.windows.regstr; version (Windows): -@system: // TODO: fix possible conflict with shloj. Sort out NEC_98 issue. diff --git a/libphobos/libdruntime/core/sys/windows/richedit.d b/libphobos/libdruntime/core/sys/windows/richedit.d index 676076480c4..0f56fef0979 100644 --- a/libphobos/libdruntime/core/sys/windows/richedit.d +++ b/libphobos/libdruntime/core/sys/windows/richedit.d @@ -8,7 +8,6 @@ */ module core.sys.windows.richedit; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/richole.d b/libphobos/libdruntime/core/sys/windows/richole.d index 288ef220a85..01518189df0 100644 --- a/libphobos/libdruntime/core/sys/windows/richole.d +++ b/libphobos/libdruntime/core/sys/windows/richole.d @@ -8,7 +8,6 @@ */ module core.sys.windows.richole; version (Windows): -@system: import core.sys.windows.objfwd, core.sys.windows.objidl, core.sys.windows.ole2, core.sys.windows.unknwn, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/rpc.d b/libphobos/libdruntime/core/sys/windows/rpc.d index a9640ada476..b432bc7c681 100644 --- a/libphobos/libdruntime/core/sys/windows/rpc.d +++ b/libphobos/libdruntime/core/sys/windows/rpc.d @@ -8,7 +8,6 @@ */ module core.sys.windows.rpc; version (Windows): -@system: /* Moved to rpcdecp (duplicate definition). typedef void *I_RPC_HANDLE; diff --git a/libphobos/libdruntime/core/sys/windows/rpcdce.d b/libphobos/libdruntime/core/sys/windows/rpcdce.d index 1eccb0dcf23..4f3f3cc1f66 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcdce.d +++ b/libphobos/libdruntime/core/sys/windows/rpcdce.d @@ -8,7 +8,6 @@ */ module core.sys.windows.rpcdce; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "Rpcrt4"); diff --git a/libphobos/libdruntime/core/sys/windows/rpcdce2.d b/libphobos/libdruntime/core/sys/windows/rpcdce2.d index c8223f6cd5b..08348c06235 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcdce2.d +++ b/libphobos/libdruntime/core/sys/windows/rpcdce2.d @@ -8,7 +8,6 @@ */ module core.sys.windows.rpcdce2; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/rpcdcep.d b/libphobos/libdruntime/core/sys/windows/rpcdcep.d index 1abbb78852d..cebe9816875 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcdcep.d +++ b/libphobos/libdruntime/core/sys/windows/rpcdcep.d @@ -8,7 +8,6 @@ */ module core.sys.windows.rpcdcep; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/rpcndr.d b/libphobos/libdruntime/core/sys/windows/rpcndr.d index 6e9722c984f..127d88b5b63 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcndr.d +++ b/libphobos/libdruntime/core/sys/windows/rpcndr.d @@ -8,7 +8,6 @@ */ module core.sys.windows.rpcndr; version (Windows): -@system: pragma(lib, "rpcrt4"); /* Translation notes: diff --git a/libphobos/libdruntime/core/sys/windows/rpcnsi.d b/libphobos/libdruntime/core/sys/windows/rpcnsi.d index 608b92cead2..1294d0dc08c 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcnsi.d +++ b/libphobos/libdruntime/core/sys/windows/rpcnsi.d @@ -10,7 +10,6 @@ */ module core.sys.windows.rpcnsi; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "rpcns4"); diff --git a/libphobos/libdruntime/core/sys/windows/rpcnsip.d b/libphobos/libdruntime/core/sys/windows/rpcnsip.d index 219d7b007d8..ccf026f495f 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcnsip.d +++ b/libphobos/libdruntime/core/sys/windows/rpcnsip.d @@ -8,7 +8,6 @@ */ module core.sys.windows.rpcnsip; version (Windows): -@system: import core.sys.windows.rpcdce, core.sys.windows.rpcdcep, core.sys.windows.rpcnsi; diff --git a/libphobos/libdruntime/core/sys/windows/rpcnterr.d b/libphobos/libdruntime/core/sys/windows/rpcnterr.d index 426077aabe5..bbead749c4a 100644 --- a/libphobos/libdruntime/core/sys/windows/rpcnterr.d +++ b/libphobos/libdruntime/core/sys/windows/rpcnterr.d @@ -8,7 +8,6 @@ */ module core.sys.windows.rpcnterr; version (Windows): -@system: import core.sys.windows.winerror; diff --git a/libphobos/libdruntime/core/sys/windows/schannel.d b/libphobos/libdruntime/core/sys/windows/schannel.d index 98c5cf80023..6ffab30f174 100644 --- a/libphobos/libdruntime/core/sys/windows/schannel.d +++ b/libphobos/libdruntime/core/sys/windows/schannel.d @@ -9,7 +9,6 @@ */ module core.sys.windows.schannel; version (Windows): -@system: import core.sys.windows.wincrypt; import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/sdkddkver.d b/libphobos/libdruntime/core/sys/windows/sdkddkver.d index 4b5bad52822..3f5c01be148 100644 --- a/libphobos/libdruntime/core/sys/windows/sdkddkver.d +++ b/libphobos/libdruntime/core/sys/windows/sdkddkver.d @@ -9,7 +9,6 @@ module core.sys.windows.sdkddkver; version (Windows): -@system: enum _WIN32_WINNT_NT4 = 0x0400; enum _WIN32_WINNT_WIN2K = 0x0500; diff --git a/libphobos/libdruntime/core/sys/windows/secext.d b/libphobos/libdruntime/core/sys/windows/secext.d index 6b92fcddf75..ab615365aa5 100644 --- a/libphobos/libdruntime/core/sys/windows/secext.d +++ b/libphobos/libdruntime/core/sys/windows/secext.d @@ -9,7 +9,6 @@ // Don't include this file directly, use core.sys.windows.security instead. module core.sys.windows.secext; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "secur32"); diff --git a/libphobos/libdruntime/core/sys/windows/security.d b/libphobos/libdruntime/core/sys/windows/security.d index b81abb3fe2d..f93dc813fc5 100644 --- a/libphobos/libdruntime/core/sys/windows/security.d +++ b/libphobos/libdruntime/core/sys/windows/security.d @@ -9,7 +9,6 @@ */ module core.sys.windows.security; version (Windows): -@system: enum : SECURITY_STATUS { diff --git a/libphobos/libdruntime/core/sys/windows/servprov.d b/libphobos/libdruntime/core/sys/windows/servprov.d index 89ab47c97cb..ae8bef11ebc 100644 --- a/libphobos/libdruntime/core/sys/windows/servprov.d +++ b/libphobos/libdruntime/core/sys/windows/servprov.d @@ -8,7 +8,6 @@ */ module core.sys.windows.servprov; version (Windows): -@system: import core.sys.windows.basetyps, core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; diff --git a/libphobos/libdruntime/core/sys/windows/setupapi.d b/libphobos/libdruntime/core/sys/windows/setupapi.d index 80e8dbaf961..7a052cde2b4 100644 --- a/libphobos/libdruntime/core/sys/windows/setupapi.d +++ b/libphobos/libdruntime/core/sys/windows/setupapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.setupapi; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "setupapi"); diff --git a/libphobos/libdruntime/core/sys/windows/shellapi.d b/libphobos/libdruntime/core/sys/windows/shellapi.d index f4019979b3c..fdd9938d908 100644 --- a/libphobos/libdruntime/core/sys/windows/shellapi.d +++ b/libphobos/libdruntime/core/sys/windows/shellapi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.shellapi; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "shell32"); diff --git a/libphobos/libdruntime/core/sys/windows/shldisp.d b/libphobos/libdruntime/core/sys/windows/shldisp.d index ecb0edee876..144f90775e1 100644 --- a/libphobos/libdruntime/core/sys/windows/shldisp.d +++ b/libphobos/libdruntime/core/sys/windows/shldisp.d @@ -8,7 +8,6 @@ */ module core.sys.windows.shldisp; version (Windows): -@system: import core.sys.windows.unknwn, core.sys.windows.windef, core.sys.windows.wtypes; diff --git a/libphobos/libdruntime/core/sys/windows/shlguid.d b/libphobos/libdruntime/core/sys/windows/shlguid.d index e0c1af1045a..f4c73efe99e 100644 --- a/libphobos/libdruntime/core/sys/windows/shlguid.d +++ b/libphobos/libdruntime/core/sys/windows/shlguid.d @@ -8,7 +8,6 @@ */ module core.sys.windows.shlguid; version (Windows): -@system: import core.sys.windows.basetyps, core.sys.windows.w32api; diff --git a/libphobos/libdruntime/core/sys/windows/shlobj.d b/libphobos/libdruntime/core/sys/windows/shlobj.d index 75ac6226306..bcd254b18ed 100644 --- a/libphobos/libdruntime/core/sys/windows/shlobj.d +++ b/libphobos/libdruntime/core/sys/windows/shlobj.d @@ -8,7 +8,6 @@ */ module core.sys.windows.shlobj; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "shell32"); diff --git a/libphobos/libdruntime/core/sys/windows/shlwapi.d b/libphobos/libdruntime/core/sys/windows/shlwapi.d index d1a61a3844f..cfabbada223 100644 --- a/libphobos/libdruntime/core/sys/windows/shlwapi.d +++ b/libphobos/libdruntime/core/sys/windows/shlwapi.d @@ -8,7 +8,6 @@ */ module core.sys.windows.shlwapi; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "shlwapi"); diff --git a/libphobos/libdruntime/core/sys/windows/snmp.d b/libphobos/libdruntime/core/sys/windows/snmp.d index bf56b28c02b..62c81e1357e 100644 --- a/libphobos/libdruntime/core/sys/windows/snmp.d +++ b/libphobos/libdruntime/core/sys/windows/snmp.d @@ -9,7 +9,6 @@ */ module core.sys.windows.snmp; version (Windows): -@system: import core.sys.windows.basetsd /+: HANDLE+/; import core.sys.windows.windef /+: BOOL, BYTE, DWORD, INT, LONG, UINT, ULONG+/; diff --git a/libphobos/libdruntime/core/sys/windows/sql.d b/libphobos/libdruntime/core/sys/windows/sql.d index 7c8758efccb..58c6d42bd04 100644 --- a/libphobos/libdruntime/core/sys/windows/sql.d +++ b/libphobos/libdruntime/core/sys/windows/sql.d @@ -8,7 +8,6 @@ */ module core.sys.windows.sql; version (Windows): -@system: public import core.sys.windows.sqltypes; import core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/sqlext.d b/libphobos/libdruntime/core/sys/windows/sqlext.d index 2ddff201279..8702cda3359 100644 --- a/libphobos/libdruntime/core/sys/windows/sqlext.d +++ b/libphobos/libdruntime/core/sys/windows/sqlext.d @@ -8,7 +8,6 @@ */ module core.sys.windows.sqlext; version (Windows): -@system: /* Conversion notes: The MinGW file was a horrible mess. All of the #defines were sorted alphabetically, diff --git a/libphobos/libdruntime/core/sys/windows/sqltypes.d b/libphobos/libdruntime/core/sys/windows/sqltypes.d index fd77b819a5e..28d5f5df1da 100644 --- a/libphobos/libdruntime/core/sys/windows/sqltypes.d +++ b/libphobos/libdruntime/core/sys/windows/sqltypes.d @@ -8,7 +8,6 @@ */ module core.sys.windows.sqltypes; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/sqlucode.d b/libphobos/libdruntime/core/sys/windows/sqlucode.d index 85f0d0603c8..d4f03f62d94 100644 --- a/libphobos/libdruntime/core/sys/windows/sqlucode.d +++ b/libphobos/libdruntime/core/sys/windows/sqlucode.d @@ -8,7 +8,6 @@ */ module core.sys.windows.sqlucode; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/sspi.d b/libphobos/libdruntime/core/sys/windows/sspi.d index 21e982daa81..3686c6f96f0 100644 --- a/libphobos/libdruntime/core/sys/windows/sspi.d +++ b/libphobos/libdruntime/core/sys/windows/sspi.d @@ -9,7 +9,6 @@ */ module core.sys.windows.sspi; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/stacktrace.d b/libphobos/libdruntime/core/sys/windows/stacktrace.d index 798208597b1..6e5c4cd13cf 100644 --- a/libphobos/libdruntime/core/sys/windows/stacktrace.d +++ b/libphobos/libdruntime/core/sys/windows/stacktrace.d @@ -11,7 +11,6 @@ module core.sys.windows.stacktrace; version (Windows): -@system: import core.demangle; import core.stdc.stdlib; diff --git a/libphobos/libdruntime/core/sys/windows/stat.d b/libphobos/libdruntime/core/sys/windows/stat.d index 16f66e1287e..c87c7498873 100644 --- a/libphobos/libdruntime/core/sys/windows/stat.d +++ b/libphobos/libdruntime/core/sys/windows/stat.d @@ -6,7 +6,6 @@ module core.sys.windows.stat; version (Windows): extern (C) nothrow @nogc: -@system: import core.sys.windows.stdc.time; diff --git a/libphobos/libdruntime/core/sys/windows/stdc/malloc.d b/libphobos/libdruntime/core/sys/windows/stdc/malloc.d index 278c9fe6fc8..768102cdd96 100644 --- a/libphobos/libdruntime/core/sys/windows/stdc/malloc.d +++ b/libphobos/libdruntime/core/sys/windows/stdc/malloc.d @@ -10,7 +10,6 @@ module core.sys.windows.stdc.malloc; version (CRuntime_Microsoft): extern (C): -@system: nothrow: @nogc: diff --git a/libphobos/libdruntime/core/sys/windows/subauth.d b/libphobos/libdruntime/core/sys/windows/subauth.d index e0d67ffdcee..a48fb9955c4 100644 --- a/libphobos/libdruntime/core/sys/windows/subauth.d +++ b/libphobos/libdruntime/core/sys/windows/subauth.d @@ -8,7 +8,6 @@ */ module core.sys.windows.subauth; version (Windows): -@system: import core.sys.windows.ntdef, core.sys.windows.windef; diff --git a/libphobos/libdruntime/core/sys/windows/threadaux.d b/libphobos/libdruntime/core/sys/windows/threadaux.d index 34fda656c8c..92bd1c6752a 100644 --- a/libphobos/libdruntime/core/sys/windows/threadaux.d +++ b/libphobos/libdruntime/core/sys/windows/threadaux.d @@ -14,7 +14,6 @@ */ module core.sys.windows.threadaux; version (Windows): -@system: import core.sys.windows.basetsd/+ : HANDLE+/; import core.sys.windows.winbase/+ : CloseHandle, GetCurrentThreadId, GetCurrentProcessId, diff --git a/libphobos/libdruntime/core/sys/windows/tlhelp32.d b/libphobos/libdruntime/core/sys/windows/tlhelp32.d index 34ed1013ea9..ecbfe38ab47 100644 --- a/libphobos/libdruntime/core/sys/windows/tlhelp32.d +++ b/libphobos/libdruntime/core/sys/windows/tlhelp32.d @@ -8,7 +8,6 @@ */ module core.sys.windows.tlhelp32; version (Windows): -@system: pragma(lib, "kernel32"); version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/tmschema.d b/libphobos/libdruntime/core/sys/windows/tmschema.d index b82dc5c84f3..7bca8786089 100644 --- a/libphobos/libdruntime/core/sys/windows/tmschema.d +++ b/libphobos/libdruntime/core/sys/windows/tmschema.d @@ -8,7 +8,6 @@ */ module core.sys.windows.tmschema; version (Windows): -@system: /* BUTTON parts */ enum { diff --git a/libphobos/libdruntime/core/sys/windows/unknwn.d b/libphobos/libdruntime/core/sys/windows/unknwn.d index 6db1db883c6..0b002792276 100644 --- a/libphobos/libdruntime/core/sys/windows/unknwn.d +++ b/libphobos/libdruntime/core/sys/windows/unknwn.d @@ -8,7 +8,6 @@ */ module core.sys.windows.unknwn; version (Windows): -@system: nothrow: import core.sys.windows.objfwd, core.sys.windows.windef, core.sys.windows.wtypes; diff --git a/libphobos/libdruntime/core/sys/windows/uuid.d b/libphobos/libdruntime/core/sys/windows/uuid.d index 7e8d4b9b7e0..d3b979dac89 100644 --- a/libphobos/libdruntime/core/sys/windows/uuid.d +++ b/libphobos/libdruntime/core/sys/windows/uuid.d @@ -1,6 +1,5 @@ module core.sys.windows.uuid; version (Windows): -@system: import core.sys.windows.basetyps; diff --git a/libphobos/libdruntime/core/sys/windows/vfw.d b/libphobos/libdruntime/core/sys/windows/vfw.d index c67753a42e6..ebe0ed0e03d 100644 --- a/libphobos/libdruntime/core/sys/windows/vfw.d +++ b/libphobos/libdruntime/core/sys/windows/vfw.d @@ -9,7 +9,6 @@ module core.sys.windows.vfw; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "vfw32"); diff --git a/libphobos/libdruntime/core/sys/windows/w32api.d b/libphobos/libdruntime/core/sys/windows/w32api.d index 2752da1adc8..5a8a59bad46 100644 --- a/libphobos/libdruntime/core/sys/windows/w32api.d +++ b/libphobos/libdruntime/core/sys/windows/w32api.d @@ -9,7 +9,6 @@ */ module core.sys.windows.w32api; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/winbase.d b/libphobos/libdruntime/core/sys/windows/winbase.d index 1806796b34d..3b571ad57da 100644 --- a/libphobos/libdruntime/core/sys/windows/winbase.d +++ b/libphobos/libdruntime/core/sys/windows/winbase.d @@ -8,7 +8,6 @@ */ module core.sys.windows.winbase; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "kernel32"); diff --git a/libphobos/libdruntime/core/sys/windows/winber.d b/libphobos/libdruntime/core/sys/windows/winber.d index d6a79cd3542..b21193896b1 100644 --- a/libphobos/libdruntime/core/sys/windows/winber.d +++ b/libphobos/libdruntime/core/sys/windows/winber.d @@ -9,7 +9,6 @@ */ module core.sys.windows.winber; version (Windows): -@system: /* Comment from MinGW winber.h - Header file for the Windows LDAP Basic Encoding Rules API diff --git a/libphobos/libdruntime/core/sys/windows/wincon.d b/libphobos/libdruntime/core/sys/windows/wincon.d index a404c5c2d69..a00ba2e31df 100644 --- a/libphobos/libdruntime/core/sys/windows/wincon.d +++ b/libphobos/libdruntime/core/sys/windows/wincon.d @@ -8,7 +8,6 @@ */ module core.sys.windows.wincon; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "kernel32"); diff --git a/libphobos/libdruntime/core/sys/windows/wincrypt.d b/libphobos/libdruntime/core/sys/windows/wincrypt.d index d6c617d2f14..cb52d9e717d 100644 --- a/libphobos/libdruntime/core/sys/windows/wincrypt.d +++ b/libphobos/libdruntime/core/sys/windows/wincrypt.d @@ -9,7 +9,6 @@ */ module core.sys.windows.wincrypt; version (Windows): -@system: pragma(lib, "advapi32"); version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/windef.d b/libphobos/libdruntime/core/sys/windows/windef.d index 31af66a2501..4e951f3ddac 100644 --- a/libphobos/libdruntime/core/sys/windows/windef.d +++ b/libphobos/libdruntime/core/sys/windows/windef.d @@ -9,7 +9,6 @@ */ module core.sys.windows.windef; version (Windows): -@system: public import core.sys.windows.winnt; import core.sys.windows.w32api; diff --git a/libphobos/libdruntime/core/sys/windows/windows.d b/libphobos/libdruntime/core/sys/windows/windows.d index 4a1b02f9a86..a289fb12676 100644 --- a/libphobos/libdruntime/core/sys/windows/windows.d +++ b/libphobos/libdruntime/core/sys/windows/windows.d @@ -8,7 +8,6 @@ */ module core.sys.windows.windows; version (Windows): -@system: /* windows.h - main header file for the Win32 API diff --git a/libphobos/libdruntime/core/sys/windows/winerror.d b/libphobos/libdruntime/core/sys/windows/winerror.d index a26b05c1d2f..865319b3c3c 100644 --- a/libphobos/libdruntime/core/sys/windows/winerror.d +++ b/libphobos/libdruntime/core/sys/windows/winerror.d @@ -8,7 +8,6 @@ */ module core.sys.windows.winerror; version (Windows): -@system: /* Comments from the Mingw header: * WAIT_TIMEOUT is also defined in winbase.h diff --git a/libphobos/libdruntime/core/sys/windows/wingdi.d b/libphobos/libdruntime/core/sys/windows/wingdi.d index ba45c27d359..5a4eeaa1cd3 100644 --- a/libphobos/libdruntime/core/sys/windows/wingdi.d +++ b/libphobos/libdruntime/core/sys/windows/wingdi.d @@ -8,7 +8,6 @@ */ module core.sys.windows.wingdi; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "gdi32"); diff --git a/libphobos/libdruntime/core/sys/windows/winhttp.d b/libphobos/libdruntime/core/sys/windows/winhttp.d index f66580508aa..63d59cb157c 100644 --- a/libphobos/libdruntime/core/sys/windows/winhttp.d +++ b/libphobos/libdruntime/core/sys/windows/winhttp.d @@ -8,7 +8,6 @@ */ module core.sys.windows.winhttp; version (Windows): -@system: pragma(lib, "winhttp"); // FIXME: Grouping of constants. Windows SDK doesn't make this entirely clear // FIXME: Verify WINHTTP_STATUS_CALLBACK function declaration works correctly diff --git a/libphobos/libdruntime/core/sys/windows/wininet.d b/libphobos/libdruntime/core/sys/windows/wininet.d index f4aa997b162..328af503a4c 100644 --- a/libphobos/libdruntime/core/sys/windows/wininet.d +++ b/libphobos/libdruntime/core/sys/windows/wininet.d @@ -9,7 +9,6 @@ */ module core.sys.windows.wininet; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "wininet"); diff --git a/libphobos/libdruntime/core/sys/windows/winioctl.d b/libphobos/libdruntime/core/sys/windows/winioctl.d index b91ddda1d93..f9db05d9d6c 100644 --- a/libphobos/libdruntime/core/sys/windows/winioctl.d +++ b/libphobos/libdruntime/core/sys/windows/winioctl.d @@ -9,7 +9,6 @@ */ module core.sys.windows.winioctl; version (Windows): -@system: // FIXME: check types of some constants diff --git a/libphobos/libdruntime/core/sys/windows/winldap.d b/libphobos/libdruntime/core/sys/windows/winldap.d index 0ab11d68d5c..bcdb2b33a75 100644 --- a/libphobos/libdruntime/core/sys/windows/winldap.d +++ b/libphobos/libdruntime/core/sys/windows/winldap.d @@ -9,7 +9,6 @@ */ module core.sys.windows.winldap; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/winnetwk.d b/libphobos/libdruntime/core/sys/windows/winnetwk.d index e0c7551096c..9bf2e64614a 100644 --- a/libphobos/libdruntime/core/sys/windows/winnetwk.d +++ b/libphobos/libdruntime/core/sys/windows/winnetwk.d @@ -9,7 +9,6 @@ */ module core.sys.windows.winnetwk; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "mpr"); diff --git a/libphobos/libdruntime/core/sys/windows/winnls.d b/libphobos/libdruntime/core/sys/windows/winnls.d index b487a17894f..f2b5409102b 100644 --- a/libphobos/libdruntime/core/sys/windows/winnls.d +++ b/libphobos/libdruntime/core/sys/windows/winnls.d @@ -9,7 +9,6 @@ */ module core.sys.windows.winnls; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "kernel32"); diff --git a/libphobos/libdruntime/core/sys/windows/winnt.d b/libphobos/libdruntime/core/sys/windows/winnt.d index bf30072fa8a..3bd9966e33e 100644 --- a/libphobos/libdruntime/core/sys/windows/winnt.d +++ b/libphobos/libdruntime/core/sys/windows/winnt.d @@ -8,7 +8,6 @@ */ module core.sys.windows.winnt; version (Windows): -@system: version (ANSI) {} else version = Unicode; diff --git a/libphobos/libdruntime/core/sys/windows/winperf.d b/libphobos/libdruntime/core/sys/windows/winperf.d index cd31990baef..77638c88af5 100644 --- a/libphobos/libdruntime/core/sys/windows/winperf.d +++ b/libphobos/libdruntime/core/sys/windows/winperf.d @@ -8,7 +8,6 @@ */ module core.sys.windows.winperf; version (Windows): -@system: import core.sys.windows.windef; import core.sys.windows.winbase; // for SYSTEMTIME diff --git a/libphobos/libdruntime/core/sys/windows/winreg.d b/libphobos/libdruntime/core/sys/windows/winreg.d index c3e58545b3d..6bffe88f251 100644 --- a/libphobos/libdruntime/core/sys/windows/winreg.d +++ b/libphobos/libdruntime/core/sys/windows/winreg.d @@ -9,7 +9,6 @@ */ module core.sys.windows.winreg; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "advapi32"); diff --git a/libphobos/libdruntime/core/sys/windows/winsock2.d b/libphobos/libdruntime/core/sys/windows/winsock2.d index 8a4b1fda274..522564516a9 100644 --- a/libphobos/libdruntime/core/sys/windows/winsock2.d +++ b/libphobos/libdruntime/core/sys/windows/winsock2.d @@ -6,7 +6,6 @@ module core.sys.windows.winsock2; version (Windows): -@system: pragma(lib, "ws2_32"); diff --git a/libphobos/libdruntime/core/sys/windows/winspool.d b/libphobos/libdruntime/core/sys/windows/winspool.d index 2ff621adf1a..12942fb7712 100644 --- a/libphobos/libdruntime/core/sys/windows/winspool.d +++ b/libphobos/libdruntime/core/sys/windows/winspool.d @@ -8,7 +8,6 @@ */ module core.sys.windows.winspool; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "winspool"); diff --git a/libphobos/libdruntime/core/sys/windows/winsvc.d b/libphobos/libdruntime/core/sys/windows/winsvc.d index 14ab6e42159..f7f2fa7d27d 100644 --- a/libphobos/libdruntime/core/sys/windows/winsvc.d +++ b/libphobos/libdruntime/core/sys/windows/winsvc.d @@ -9,7 +9,6 @@ */ module core.sys.windows.winsvc; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "advapi32"); diff --git a/libphobos/libdruntime/core/sys/windows/winuser.d b/libphobos/libdruntime/core/sys/windows/winuser.d index 078e0610b5e..71cd8827d22 100644 --- a/libphobos/libdruntime/core/sys/windows/winuser.d +++ b/libphobos/libdruntime/core/sys/windows/winuser.d @@ -8,7 +8,6 @@ */ module core.sys.windows.winuser; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "user32"); diff --git a/libphobos/libdruntime/core/sys/windows/winver.d b/libphobos/libdruntime/core/sys/windows/winver.d index 5099c3f51f2..dc3d881d2c4 100644 --- a/libphobos/libdruntime/core/sys/windows/winver.d +++ b/libphobos/libdruntime/core/sys/windows/winver.d @@ -9,7 +9,6 @@ */ module core.sys.windows.winver; version (Windows): -@system: import core.sys.windows.w32api; import core.sys.windows.winbase; import core.sys.windows.sdkddkver; diff --git a/libphobos/libdruntime/core/sys/windows/wtsapi32.d b/libphobos/libdruntime/core/sys/windows/wtsapi32.d index 13576bdd112..4db697a6501 100644 --- a/libphobos/libdruntime/core/sys/windows/wtsapi32.d +++ b/libphobos/libdruntime/core/sys/windows/wtsapi32.d @@ -8,7 +8,6 @@ */ module core.sys.windows.wtsapi32; version (Windows): -@system: version (ANSI) {} else version = Unicode; pragma(lib, "wtsapi32"); diff --git a/libphobos/libdruntime/core/sys/windows/wtypes.d b/libphobos/libdruntime/core/sys/windows/wtypes.d index c27dd3a3f3a..0206839ebf2 100644 --- a/libphobos/libdruntime/core/sys/windows/wtypes.d +++ b/libphobos/libdruntime/core/sys/windows/wtypes.d @@ -8,7 +8,6 @@ */ module core.sys.windows.wtypes; version (Windows): -@system: import core.sys.windows.rpc, core.sys.windows.rpcndr; import core.sys.windows.windef; diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d index 0739b7451fd..264fdf6204a 100644 --- a/libphobos/libdruntime/rt/dmain2.d +++ b/libphobos/libdruntime/rt/dmain2.d @@ -577,7 +577,7 @@ extern (C) void _d_print_throwable(Throwable t) { WCHAR* ptr; size_t len; - void sink(const scope char[] s) scope nothrow + void sink(in char[] s) scope nothrow { if (!s.length) return; int swlen = MultiByteToWideChar( diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index 4d6382617df..d02f72d5b4f 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -88aa69b14f8a28255a0ac7626f6509a13cfdb67a +3ad507b5125573c5b47736a0913105bfb1249746 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 39eff0d4a2b..9a365d59e2c 100644 --- a/libphobos/src/std/algorithm/iteration.d +++ b/libphobos/src/std/algorithm/iteration.d @@ -7926,7 +7926,13 @@ if (isRandomAccessRange!Range && hasLength!Range) _indices = iota(size_t(r.length)).array; _empty = r.length == 0; } - + private this(size_t[] indices, size_t[] state, Range r, bool empty_) + { + _indices = indices; + _state = state; + _r = r; + _empty = empty_; + } /// Returns: `true` if the range is empty, `false` otherwise. @property bool empty() const pure nothrow @safe @nogc { @@ -7967,6 +7973,11 @@ if (isRandomAccessRange!Range && hasLength!Range) next(2); } + /// Returns: an independent copy of the permutations range. + auto save() + { + return typeof(this)(_indices.dup, _state.dup, _r.save, _empty); + } } /// @@ -7982,3 +7993,15 @@ if (isRandomAccessRange!Range && hasLength!Range) [1, 2, 0], [2, 1, 0]])); } + +@safe unittest +{ + import std.algorithm.comparison : equal; + import std.range : ElementType; + import std.array : array; + auto p = [1, 2, 3].permutations; + auto x = p.save.front; + p.popFront; + auto y = p.front; + assert(x != y); +} diff --git a/libphobos/src/std/algorithm/mutation.d b/libphobos/src/std/algorithm/mutation.d index b0e77076812..839183deea0 100644 --- a/libphobos/src/std/algorithm/mutation.d +++ b/libphobos/src/std/algorithm/mutation.d @@ -1943,6 +1943,7 @@ if (Offset.length >= 1 && allSatisfy!(isValidIntegralTuple, Offset)) return removeImpl!s(range, offset); } +/// ditto deprecated("Use of non-integral tuples is deprecated. Use remove(tuple(start, end).") Range remove (SwapStrategy s = SwapStrategy.stable, Range, Offset ...) diff --git a/libphobos/src/std/array.d b/libphobos/src/std/array.d index f48602e4cd6..3e882003f38 100644 --- a/libphobos/src/std/array.d +++ b/libphobos/src/std/array.d @@ -586,7 +586,7 @@ if (isInputRange!Range) static assert(isMutable!ValueType, "assocArray: value type must be mutable"); ValueType[KeyType] aa; - foreach (t; r) + foreach (ref t; r) aa[t[0]] = t[1]; return aa; } @@ -4676,6 +4676,7 @@ nothrow pure @safe @nogc unittest assert(a == [0, 1]); } +/// ditto pragma(inline, true) U[n] staticArray(U, T, size_t n)(auto ref T[n] a) if (!is(T == U) && is(T : U)) { diff --git a/libphobos/src/std/ascii.d b/libphobos/src/std/ascii.d index 3b6face1dc1..367c981320a 100644 --- a/libphobos/src/std/ascii.d +++ b/libphobos/src/std/ascii.d @@ -187,7 +187,8 @@ else +/ bool isAlphaNum(dchar c) @safe pure nothrow @nogc { - return c <= 'z' && c >= '0' && (c <= '9' || c >= 'a' || (c >= 'A' && c <= 'Z')); + const hc = c | 0x20; + return ('0' <= c && c <= '9') || ('a' <= hc && hc <= 'z'); } /// @@ -377,7 +378,8 @@ bool isOctalDigit(dchar c) @safe pure nothrow @nogc +/ bool isHexDigit(dchar c) @safe pure nothrow @nogc { - return c <= 'f' && c >= '0' && (c <= '9' || c >= 'a' || (c >= 'A' && c <= 'F')); + const hc = c | 0x20; + return ('0' <= c && c <= '9') || ('a' <= hc && hc <= 'f'); } /// diff --git a/libphobos/src/std/base64.d b/libphobos/src/std/base64.d index d971dba1c71..2f7213b737b 100644 --- a/libphobos/src/std/base64.d +++ b/libphobos/src/std/base64.d @@ -922,7 +922,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') * length $(D_PARAM sourceLength). */ @safe - pure nothrow size_t decodeLength(in size_t sourceLength) + pure @nogc nothrow size_t decodeLength(in size_t sourceLength) { static if (Padding == NoPadding) return (sourceLength / 4) * 3 + (sourceLength % 4 < 2 ? 0 : sourceLength % 4 == 2 ? 1 : 2); @@ -946,7 +946,7 @@ template Base64Impl(char Map62th, char Map63th, char Padding = '=') // Used in decode contracts. Calculates the actual size the decoded // result should have, taking into account trailing padding. @safe - pure nothrow private size_t realDecodeLength(R)(R source) + pure @nogc nothrow private size_t realDecodeLength(R)(R source) { auto expect = decodeLength(source.length); static if (Padding != NoPadding) diff --git a/libphobos/src/std/bitmanip.d b/libphobos/src/std/bitmanip.d index de2e0fb262f..f131257f777 100644 --- a/libphobos/src/std/bitmanip.d +++ b/libphobos/src/std/bitmanip.d @@ -784,48 +784,6 @@ if (is(T == class)) static assert(!__traits(compiles, bar(s))); } -/** - Allows manipulating the fraction, exponent, and sign parts of a - `float` separately. The definition is: - ----- -struct FloatRep -{ - union - { - float value; - mixin(bitfields!( - uint, "fraction", 23, - ubyte, "exponent", 8, - bool, "sign", 1)); - } - enum uint bias = 127, fractionBits = 23, exponentBits = 8, signBits = 1; -} ----- -*/ -alias FloatRep = FloatingPointRepresentation!float; - -/** - Allows manipulating the fraction, exponent, and sign parts of a - `double` separately. The definition is: - ----- -struct DoubleRep -{ - union - { - double value; - mixin(bitfields!( - ulong, "fraction", 52, - ushort, "exponent", 11, - bool, "sign", 1)); - } - enum uint bias = 1023, signBits = 1, fractionBits = 52, exponentBits = 11; -} ----- -*/ -alias DoubleRep = FloatingPointRepresentation!double; - private struct FloatingPointRepresentation(T) { static if (is(T == float)) @@ -851,6 +809,27 @@ private struct FloatingPointRepresentation(T) } } +/** + Allows manipulating the fraction, exponent, and sign parts of a + `float` separately. The definition is: + +---- +struct FloatRep +{ + union + { + float value; + mixin(bitfields!( + uint, "fraction", 23, + ubyte, "exponent", 8, + bool, "sign", 1)); + } + enum uint bias = 127, fractionBits = 23, exponentBits = 8, signBits = 1; +} +---- +*/ +alias FloatRep = FloatingPointRepresentation!float; + /// @safe unittest { @@ -899,6 +878,27 @@ private struct FloatingPointRepresentation(T) assert(rep.sign); } +/** + Allows manipulating the fraction, exponent, and sign parts of a + `double` separately. The definition is: + +---- +struct DoubleRep +{ + union + { + double value; + mixin(bitfields!( + ulong, "fraction", 52, + ushort, "exponent", 11, + bool, "sign", 1)); + } + enum uint bias = 1023, signBits = 1, fractionBits = 52, exponentBits = 11; +} +---- +*/ +alias DoubleRep = FloatingPointRepresentation!double; + /// @safe unittest { @@ -986,17 +986,17 @@ private: size_t* _ptr; enum bitsPerSizeT = size_t.sizeof * 8; - @property size_t fullWords() const @nogc pure nothrow + @property size_t fullWords() const scope @safe @nogc pure nothrow { return _len / bitsPerSizeT; } // Number of bits after the last full word - @property size_t endBits() const @nogc pure nothrow + @property size_t endBits() const scope @safe @nogc pure nothrow { return _len % bitsPerSizeT; } // Bit mask to extract the bits after the last full word - @property size_t endMask() const @nogc pure nothrow + @property size_t endMask() const scope @safe @nogc pure nothrow { return (size_t(1) << endBits) - 1; } @@ -1440,15 +1440,15 @@ public: /********************************************** * Counts all the set bits in the `BitArray` */ - size_t count() const @nogc pure nothrow + size_t count() const scope @safe @nogc pure nothrow { if (_ptr) { size_t bitCount; foreach (i; 0 .. fullWords) - bitCount += countBitsSet(_ptr[i]); + bitCount += (() @trusted => countBitsSet(_ptr[i]))(); if (endBits) - bitCount += countBitsSet(_ptr[fullWords] & endMask); + bitCount += (() @trusted => countBitsSet(_ptr[fullWords] & endMask))(); return bitCount; } else @@ -4544,7 +4544,7 @@ if (canSwapEndianness!T && isOutputRange!(R, ubyte)) Counts the number of set bits in the binary representation of `value`. For signed integers, the sign bit is included in the count. */ -private uint countBitsSet(T)(const T value) @nogc pure nothrow +private uint countBitsSet(T)(const T value) if (isIntegral!T) { static if (T.sizeof == 8) diff --git a/libphobos/src/std/container/binaryheap.d b/libphobos/src/std/container/binaryheap.d index e763357a012..723630c89e2 100644 --- a/libphobos/src/std/container/binaryheap.d +++ b/libphobos/src/std/container/binaryheap.d @@ -89,6 +89,8 @@ if (isRandomAccessRange!(Store) || isRandomAccessRange!(typeof(Store.init[]))) Store _store; size_t _length; } + // TODO: migrate to use the SafeRefCounted. The problem is that some member + // functions here become @system with a naive switch. private RefCounted!(Data, RefCountedAutoInitialize.no) _payload; // Comparison predicate private alias comp = binaryFun!(less); diff --git a/libphobos/src/std/digest/murmurhash.d b/libphobos/src/std/digest/murmurhash.d index 533db92181c..b94042f1a0d 100644 --- a/libphobos/src/std/digest/murmurhash.d +++ b/libphobos/src/std/digest/murmurhash.d @@ -38,11 +38,6 @@ $(BR) $(LINK2 https://en.wikipedia.org/wiki/MurmurHash, Wikipedia) */ module std.digest.murmurhash; -version (X86) - version = HaveUnalignedLoads; -else version (X86_64) - version = HaveUnalignedLoads; - /// @safe unittest { @@ -97,6 +92,11 @@ else version (X86_64) assert(hashed == [188, 165, 108, 2]); } +version (X86) + version = HaveUnalignedLoads; +else version (X86_64) + version = HaveUnalignedLoads; + public import std.digest; @safe: diff --git a/libphobos/src/std/exception.d b/libphobos/src/std/exception.d index 94a2e7a0012..129c05d4dcb 100644 --- a/libphobos/src/std/exception.d +++ b/libphobos/src/std/exception.d @@ -799,108 +799,107 @@ enum emptyExceptionMsg = ""; } /** - * Casts a mutable array to an immutable array in an idiomatic - * manner. Technically, `assumeUnique` just inserts a cast, - * but its name documents assumptions on the part of the - * caller. `assumeUnique(arr)` should only be called when - * there are no more active mutable aliases to elements of $(D - * arr). To strengthen this assumption, `assumeUnique(arr)` - * also clears `arr` before returning. Essentially $(D - * assumeUnique(arr)) indicates commitment from the caller that there - * is no more mutable access to any of `arr`'s elements - * (transitively), and that all future accesses will be done through - * the immutable array returned by `assumeUnique`. - * - * Typically, `assumeUnique` is used to return arrays from - * functions that have allocated and built them. - * - * Params: - * array = The array to cast to immutable. - * - * Returns: The immutable array. - * - * Example: - * - * $(RUNNABLE_EXAMPLE - * ---- - * string letters() - * { - * char[] result = new char['z' - 'a' + 1]; - * foreach (i, ref e; result) - * { - * e = cast(char)('a' + i); - * } - * return assumeUnique(result); - * } - * ---- - * ) - * - * The use in the example above is correct because `result` - * was private to `letters` and is inaccessible in writing - * after the function returns. The following example shows an - * incorrect use of `assumeUnique`. - * - * Bad: - * - * $(RUNNABLE_EXAMPLE - * ---- - * private char[] buffer; - * string letters(char first, char last) - * { - * if (first >= last) return null; // fine - * auto sneaky = buffer; - * sneaky.length = last - first + 1; - * foreach (i, ref e; sneaky) - * { - * e = cast(char)('a' + i); - * } - * return assumeUnique(sneaky); // BAD - * } - * ---- - * ) - * - * The example above wreaks havoc on client code because it is - * modifying arrays that callers considered immutable. To obtain an - * immutable array from the writable array `buffer`, replace - * the last line with: - * - * ---- - * return to!(string)(sneaky); // not that sneaky anymore - * ---- - * - * The call will duplicate the array appropriately. - * - * Note that checking for uniqueness during compilation is - * possible in certain cases, especially when a function is - * marked as a pure function. The following example does not - * need to call assumeUnique because the compiler can infer the - * uniqueness of the array in the pure function: - * - * $(RUNNABLE_EXAMPLE - * ---- - * string letters() pure - * { - * char[] result = new char['z' - 'a' + 1]; - * foreach (i, ref e; result) - * { - * e = cast(char)('a' + i); - * } - * return result; - * } - * ---- - * ) - * - * For more on infering uniqueness see the $(B unique) and - * $(B lent) keywords in the - * $(HTTP www.cs.cmu.edu/~aldrich/papers/aldrich-dissertation.pdf, ArchJava) - * language. - * - * The downside of using `assumeUnique`'s - * convention-based usage is that at this time there is no - * formal checking of the correctness of the assumption; - * on the upside, the idiomatic use of `assumeUnique` is - * simple and rare enough to be tolerable. - * +Casts a mutable array to an immutable array in an idiomatic +manner. Technically, `assumeUnique` just inserts a cast, +but its name documents assumptions on the part of the +caller. `assumeUnique(arr)` should only be called when +there are no more active mutable aliases to elements of $(D +arr). To strengthen this assumption, `assumeUnique(arr)` +also clears `arr` before returning. Essentially $(D +assumeUnique(arr)) indicates commitment from the caller that there +is no more mutable access to any of `arr`'s elements +(transitively), and that all future accesses will be done through +the immutable array returned by `assumeUnique`. + +Typically, `assumeUnique` is used to return arrays from +functions that have allocated and built them. + +Params: + array = The array to cast to immutable. + +Returns: The immutable array. + +Example: + +$(RUNNABLE_EXAMPLE +---- +string letters() +{ + char[] result = new char['z' - 'a' + 1]; + foreach (i, ref e; result) + { + e = cast(char)('a' + i); + } + return assumeUnique(result); +} +---- +) + +The use in the example above is correct because `result` +was private to `letters` and is inaccessible in writing +after the function returns. The following example shows an +incorrect use of `assumeUnique`. + +Bad: + +$(RUNNABLE_EXAMPLE +---- +char[] buffer; +string letters(char first, char last) +{ + if (first >= last) return null; // fine + auto sneaky = buffer; + sneaky.length = last - first + 1; + foreach (i, ref e; sneaky) + { + e = cast(char)('a' + i); + } + return assumeUnique(sneaky); // BAD +} +---- +) + +The example above wreaks havoc on client code because it is +modifying arrays that callers considered immutable. To obtain an +immutable array from the writable array `buffer`, replace +the last line with: + +---- +return to!(string)(sneaky); // not that sneaky anymore +---- + +The call will duplicate the array appropriately. + +Note that checking for uniqueness during compilation is +possible in certain cases, especially when a function is +marked as a pure function. The following example does not +need to call `assumeUnique` because the compiler can infer the +uniqueness of the array in the pure function: + +$(RUNNABLE_EXAMPLE +---- +static string letters() pure +{ + char[] result = new char['z' - 'a' + 1]; + foreach (i, ref e; result) + { + e = cast(char)('a' + i); + } + return result; +} +---- +) + +For more on infering uniqueness see the $(B unique) and +$(B lent) keywords in the +$(HTTP www.cs.cmu.edu/~aldrich/papers/aldrich-dissertation.pdf, ArchJava) +language. + +The downside of using `assumeUnique`'s +convention-based usage is that at this time there is no +formal checking of the correctness of the assumption; +on the upside, the idiomatic use of `assumeUnique` is +simple and rare enough to be tolerable. */ immutable(T)[] assumeUnique(T)(T[] array) pure nothrow { diff --git a/libphobos/src/std/experimental/allocator/common.d b/libphobos/src/std/experimental/allocator/common.d index 8acd763b97c..d2efe338d7b 100644 --- a/libphobos/src/std/experimental/allocator/common.d +++ b/libphobos/src/std/experimental/allocator/common.d @@ -11,6 +11,26 @@ Source: $(PHOBOSSRC std/experimental/allocator/common.d) module std.experimental.allocator.common; import std.algorithm.comparison, std.traits; +/** +Is `true` iff `A` is an allocator. + */ +enum isAllocator(A) = (is(typeof(A.allocate(size_t.init)) == void[]) && is(typeof(A.alignment) : size_t)); + +/// +@safe @nogc nothrow pure +unittest +{ + import std.experimental.allocator.building_blocks.null_allocator : NullAllocator; + import std.experimental.allocator.mallocator : Mallocator; + import std.experimental.allocator.gc_allocator : GCAllocator; + import std.experimental.allocator.mmap_allocator : MmapAllocator; + static assert(isAllocator!NullAllocator); + static assert(isAllocator!Mallocator); + static assert(isAllocator!GCAllocator); + static assert(isAllocator!MmapAllocator); + static assert(!isAllocator!int); +} + /** Returns the size in bytes of the state that needs to be allocated to hold an object of type `T`. `stateSize!T` is zero for `struct`s that are not diff --git a/libphobos/src/std/file.d b/libphobos/src/std/file.d index 8957089de89..8d1b431215c 100644 --- a/libphobos/src/std/file.d +++ b/libphobos/src/std/file.d @@ -4465,9 +4465,10 @@ void rmdirRecurse(ref scope DirEntry de) @safe } else { - // dirEntries is @system because it uses a DirIterator with a - // RefCounted variable, but here, no references to the payload is - // escaped to the outside, so this should be @trusted + // dirEntries is @system without DIP1000 because it uses + // a DirIterator with a SafeRefCounted variable, but here, no + // references to the payload are escaped to the outside, so this should + // be @trusted () @trusted { // all children, recursively depth-first foreach (DirEntry e; dirEntries(de.name, SpanMode.depth, false)) @@ -4863,20 +4864,31 @@ private struct DirIteratorImpl } } -struct DirIterator +// Must be a template, because the destructor is unsafe or safe depending on +// whether `-preview=dip1000` is in use. Otherwise, linking errors would +// result. +struct _DirIterator(bool useDIP1000) { -@safe: + static assert(useDIP1000 == dip1000Enabled, + "Please don't override useDIP1000 to disagree with compiler switch."); + private: - RefCounted!(DirIteratorImpl, RefCountedAutoInitialize.no) impl; + SafeRefCounted!(DirIteratorImpl, RefCountedAutoInitialize.no) impl; + this(string pathname, SpanMode mode, bool followSymlink) @trusted { impl = typeof(impl)(pathname, mode, followSymlink); } public: - @property bool empty() { return impl.empty; } - @property DirEntry front() { return impl.front; } - void popFront() { impl.popFront(); } + @property bool empty() @trusted { return impl.empty; } + @property DirEntry front() @trusted { return impl.front; } + void popFront() @trusted { impl.popFront(); } } + +// This has the client code to automatically use and link to the correct +// template instance +alias DirIterator = _DirIterator!dip1000Enabled; + /++ Returns an $(REF_ALTTEXT input range, isInputRange, std,range,primitives) of `DirEntry` that lazily iterates a given directory, @@ -4890,6 +4902,11 @@ public: operating system / filesystem, and may not follow any particular sorting. Params: + useDIP1000 = used to instantiate this function separately for code with + and without -preview=dip1000 compiler switch, because it + affects the ABI of this function. Set automatically - + don't touch. + path = The directory to iterate over. If empty, the current directory will be iterated. @@ -4955,9 +4972,13 @@ foreach (d; dFiles) writeln(d.name); -------------------- +/ -auto dirEntries(string path, SpanMode mode, bool followSymlink = true) + +// For some reason, doing the same alias-to-a-template trick as with DirIterator +// does not work here. +auto dirEntries(bool useDIP1000 = dip1000Enabled) + (string path, SpanMode mode, bool followSymlink = true) { - return DirIterator(path, mode, followSymlink); + return _DirIterator!useDIP1000(path, mode, followSymlink); } /// Duplicate functionality of D1's `std.file.listdir()`: @@ -4976,13 +4997,14 @@ auto dirEntries(string path, SpanMode mode, bool followSymlink = true) .array; } - void main(string[] args) + // Can be safe only with -preview=dip1000 + @safe void main(string[] args) { import std.stdio; string[] files = listdir(args[1]); writefln("%s", files); - } + } } @system unittest @@ -5057,14 +5079,15 @@ auto dirEntries(string path, SpanMode mode, bool followSymlink = true) } /// Ditto -auto dirEntries(string path, string pattern, SpanMode mode, +auto dirEntries(bool useDIP1000 = dip1000Enabled) + (string path, string pattern, SpanMode mode, bool followSymlink = true) { import std.algorithm.iteration : filter; import std.path : globMatch, baseName; bool f(DirEntry de) { return globMatch(baseName(de.name), pattern); } - return filter!f(DirIterator(path, mode, followSymlink)); + return filter!f(_DirIterator!useDIP1000(path, mode, followSymlink)); } @safe unittest @@ -5145,7 +5168,7 @@ auto dirEntries(string path, string pattern, SpanMode mode, // Make sure that dirEntries does not butcher Unicode file names // https://issues.dlang.org/show_bug.cgi?id=17962 -@system unittest +@safe unittest { import std.algorithm.comparison : equal; import std.algorithm.iteration : map; diff --git a/libphobos/src/std/format/internal/write.d b/libphobos/src/std/format/internal/write.d index 2fd6ff72990..8089cfae914 100644 --- a/libphobos/src/std/format/internal/write.d +++ b/libphobos/src/std/format/internal/write.d @@ -3017,33 +3017,31 @@ if (is(T == enum)) import std.array : appender; import std.range.primitives : put; - if (f.spec == 's') + if (f.spec != 's') + return formatValueImpl(w, cast(OriginalType!T) val, f); + + static foreach (e; EnumMembers!T) { - foreach (i, e; EnumMembers!T) + if (val == e) { - if (val == e) - { - formatValueImpl(w, __traits(allMembers, T)[i], f); - return; - } + formatValueImpl(w, __traits(identifier, e), f); + return; } + } - auto w2 = appender!string(); + auto w2 = appender!string(); - // val is not a member of T, output cast(T) rawValue instead. - put(w2, "cast("); - put(w2, T.stringof); - put(w2, ")"); - static assert(!is(OriginalType!T == T), "OriginalType!" ~ T.stringof ~ - "must not be equal to " ~ T.stringof); + // val is not a member of T, output cast(T) rawValue instead. + put(w2, "cast("); + put(w2, T.stringof); + put(w2, ")"); + static assert(!is(OriginalType!T == T), "OriginalType!" ~ T.stringof ~ + "must not be equal to " ~ T.stringof); - FormatSpec!Char f2 = f; - f2.width = 0; - formatValueImpl(w2, cast(OriginalType!T) val, f2); - writeAligned(w, w2.data, f); - return; - } - formatValueImpl(w, cast(OriginalType!T) val, f); + FormatSpec!Char f2 = f; + f2.width = 0; + formatValueImpl(w2, cast(OriginalType!T) val, f2); + writeAligned(w, w2.data, f); } @safe unittest diff --git a/libphobos/src/std/internal/windows/advapi32.d b/libphobos/src/std/internal/windows/advapi32.d index 6f999ba8019..1b26f43c3ea 100644 --- a/libphobos/src/std/internal/windows/advapi32.d +++ b/libphobos/src/std/internal/windows/advapi32.d @@ -36,7 +36,9 @@ pragma(lib, "advapi32.lib"); HMODULE hAdvapi32 = null; extern (Windows) { - LONG function(in HKEY hkey, in LPCWSTR lpSubKey, in REGSAM samDesired, in DWORD reserved) pRegDeleteKeyExW; + LONG function( + scope const HKEY hkey, scope const LPCWSTR lpSubKey, + scope const REGSAM samDesired, scope const DWORD reserved) pRegDeleteKeyExW; } void loadAdvapi32() diff --git a/libphobos/src/std/json.d b/libphobos/src/std/json.d index ac397e5f973..088e77fd66e 100644 --- a/libphobos/src/std/json.d +++ b/libphobos/src/std/json.d @@ -678,6 +678,7 @@ struct JSONValue assert( j["language"].str == "Perl" ); } + /// ditto void opIndexAssign(T)(T arg, size_t i) { auto a = this.arrayNoRef; @@ -754,11 +755,13 @@ struct JSONValue assert(j["author"].str == "Walter"); } + /// bool opEquals(const JSONValue rhs) const @nogc nothrow pure @safe { return opEquals(rhs); } + /// ditto bool opEquals(ref const JSONValue rhs) const @nogc nothrow pure @trusted { // Default doesn't work well since store is a union. Compare only diff --git a/libphobos/src/std/net/curl.d b/libphobos/src/std/net/curl.d index 23182790be7..8745bbd7a07 100644 --- a/libphobos/src/std/net/curl.d +++ b/libphobos/src/std/net/curl.d @@ -28,7 +28,7 @@ to your $(B dub.json) file if you are using $(LINK2 http://code.dlang.org, DUB). Windows x86 note: A DMD compatible libcurl static library can be downloaded from the dlang.org -$(LINK2 http://downloads.dlang.org/other/index.html, download archive page). +$(LINK2 https://downloads.dlang.org/other/index.html, download archive page). This module is not available for iOS, tvOS or watchOS. diff --git a/libphobos/src/std/random.d b/libphobos/src/std/random.d index 70b87ddd59e..9b3c5edfcf0 100644 --- a/libphobos/src/std/random.d +++ b/libphobos/src/std/random.d @@ -107,18 +107,6 @@ module std.random; import std.range.primitives; import std.traits; -version (OSX) - version = Darwin; -else version (iOS) - version = Darwin; -else version (TVOS) - version = Darwin; -else version (WatchOS) - version = Darwin; - -version (D_InlineAsm_X86) version = InlineAsm_X86_Any; -version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any; - /// @safe unittest { @@ -178,6 +166,18 @@ version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any; assert([0, 1, 2, 4, 5].randomShuffle(rnd2).equal([4, 2, 5, 0, 1])); } +version (OSX) + version = Darwin; +else version (iOS) + version = Darwin; +else version (TVOS) + version = Darwin; +else version (WatchOS) + version = Darwin; + +version (D_InlineAsm_X86) version = InlineAsm_X86_Any; +version (D_InlineAsm_X86_64) version = InlineAsm_X86_Any; + version (StdUnittest) { static import std.meta; diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d index cd1a356eda1..ffd6da8c4db 100644 --- a/libphobos/src/std/stdio.d +++ b/libphobos/src/std/stdio.d @@ -145,8 +145,8 @@ version (Windows) // encoded in CP_ACP on Windows instead of UTF-8. /+ Waiting for druntime pull 299 +/ - extern (C) nothrow @nogc FILE* _wfopen(in wchar* filename, in wchar* mode); - extern (C) nothrow @nogc FILE* _wfreopen(in wchar* filename, in wchar* mode, FILE* fp); + extern (C) nothrow @nogc FILE* _wfopen(scope const wchar* filename, scope const wchar* mode); + extern (C) nothrow @nogc FILE* _wfreopen(scope const wchar* filename, scope const wchar* mode, FILE* fp); import core.sys.windows.basetsd : HANDLE; } @@ -5210,7 +5210,7 @@ enum StdFileHandle: string { with (StdFileHandle) assert(_iob == stdin || _iob == stdout || _iob == stderr); - impl.handle = mixin(_iob); + impl.handle = cast() mixin(_iob); result._p = &impl; atomicOp!"+="(spinlock, uint.max / 2); break; diff --git a/libphobos/src/std/string.d b/libphobos/src/std/string.d index 7ed24f7f98d..b1063ee0040 100644 --- a/libphobos/src/std/string.d +++ b/libphobos/src/std/string.d @@ -4845,6 +4845,7 @@ if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range) && assert(detabber(" \n\tx", 9).array == " \n x"); } +/// ditto auto detabber(Range)(auto ref Range r, size_t tabSize = 8) if (isConvertibleToString!Range) { diff --git a/libphobos/src/std/traits.d b/libphobos/src/std/traits.d index cc08ea638be..1cbff8414e3 100644 --- a/libphobos/src/std/traits.d +++ b/libphobos/src/std/traits.d @@ -9136,3 +9136,11 @@ package(std) template DeducedParameterType(T) { static assert(is(DeducedParameterType!(inout(int[])) == inout(int)[])); } + +private auto dip1000Test(int x) {return *&x;} +// We don't use isSafe, because betterC client code needs to instantiate +// core.internal.array.comparison.__cmp in the client side. isSafe uses +// __cmp of two strings, so using it would instantate that here instead. That +// won't do because betterC compilations do not link the Phobos binary in. +package(std) enum dip1000Enabled + = is(typeof(&dip1000Test) : int function(int) @safe); diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index 094628b559c..231ac9302a3 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -22,8 +22,8 @@ $(TR $(TD Flags) $(TD $(LREF Yes) )) $(TR $(TD Memory allocation) $(TD - $(LREF RefCounted) - $(LREF refCounted) + $(LREF SafeRefCounted) + $(LREF safeRefCounted) $(LREF RefCountedAutoInitialize) $(LREF scoped) $(LREF Unique) @@ -2759,6 +2759,9 @@ Nullable!T) object starts in the null state. Assigning it renders it non-null. Calling `nullify` can nullify it again. Practically `Nullable!T` stores a `T` and a `bool`. + +See also: + $(LREF apply), an alternative way to use the payload. */ struct Nullable(T) { @@ -4178,7 +4181,7 @@ Returns: See also: $(HTTPS en.wikipedia.org/wiki/Monad_(functional_programming)#The_Maybe_monad, The `Maybe` monad) - */ +*/ template apply(alias fun) { import std.functional : unaryFun; @@ -6550,8 +6553,8 @@ package template Bind(alias Template, args1...) /** -Options regarding auto-initialization of a `RefCounted` object (see -the definition of `RefCounted` below). +Options regarding auto-initialization of a `SafeRefCounted` object (see +the definition of `SafeRefCounted` below). */ enum RefCountedAutoInitialize { @@ -6572,6 +6575,27 @@ enum RefCountedAutoInitialize int a = 42; } + SafeRefCounted!(Foo, RefCountedAutoInitialize.yes) rcAuto; + SafeRefCounted!(Foo, RefCountedAutoInitialize.no) rcNoAuto; + + assert(rcAuto.refCountedPayload.a == 42); + + assertThrown!AssertError(rcNoAuto.refCountedPayload); + rcNoAuto.refCountedStore.ensureInitialized; + assert(rcNoAuto.refCountedPayload.a == 42); +} + +// Same the above but for old RefCounted and not documented +@system unittest +{ + import core.exception : AssertError; + import std.exception : assertThrown; + + struct Foo + { + int a = 42; + } + RefCounted!(Foo, RefCountedAutoInitialize.yes) rcAuto; RefCounted!(Foo, RefCountedAutoInitialize.no) rcNoAuto; @@ -6586,16 +6610,16 @@ enum RefCountedAutoInitialize Defines a reference-counted object containing a `T` value as payload. -An instance of `RefCounted` is a reference to a structure, +An instance of `SafeRefCounted` is a reference to a structure, which is referred to as the $(I store), or $(I storage implementation struct) in this documentation. The store contains a reference count -and the `T` payload. `RefCounted` uses `malloc` to allocate -the store. As instances of `RefCounted` are copied or go out of +and the `T` payload. `SafeRefCounted` uses `malloc` to allocate +the store. As instances of `SafeRefCounted` are copied or go out of scope, they will automatically increment or decrement the reference -count. When the reference count goes down to zero, `RefCounted` +count. When the reference count goes down to zero, `SafeRefCounted` will call `destroy` against the payload and call `free` to deallocate the store. If the `T` payload contains any references -to GC-allocated memory, then `RefCounted` will add it to the GC memory +to GC-allocated memory, then `SafeRefCounted` will add it to the GC memory that is scanned for pointers, and remove it from GC scanning before `free` is called on the store. @@ -6607,8 +6631,15 @@ still be valid during the destructor call. This allows the `T` to deallocate or clean up any non-GC resources immediately after the reference count has reached zero. -`RefCounted` is unsafe and should be used with care. No references -to the payload should be escaped outside the `RefCounted` object. +Without -preview=dip1000, `SafeRefCounted` is unsafe and should be +used with care. No references to the payload should be escaped outside +the `SafeRefCounted` object. + +With -preview=dip1000, `SafeRefCounted` is safe if it's payload is accessed only +with the $(LREF borrow) function. Scope semantics can also prevent accidental +escaping of `refCountedPayload`, but it's still up to the user to not destroy +the last counted reference while the payload is in use. Due to that, +`refCountedPayload` remains accessible only in `@system` code. The `autoInit` option makes the object ensure the store is automatically initialized. Leaving $(D autoInit == @@ -6621,8 +6652,11 @@ pointer dereference. If `T.this()` is annotated with `@disable` then `autoInit` must be `RefCountedAutoInitialize.no` in order to compile. + +See_Also: + $(LREF RefCounted) */ -struct RefCounted(T, RefCountedAutoInitialize autoInit = +struct SafeRefCounted(T, RefCountedAutoInitialize autoInit = RefCountedAutoInitialize.yes) if (!is(T == class) && !(is(T == interface))) { @@ -6642,7 +6676,20 @@ if (!is(T == class) && !(is(T == interface))) import core.memory : GC; } - /// `RefCounted` storage implementation. + pragma(inline, true) private void checkInit()() + if (autoInit == RefCountedAutoInitialize.yes) + { + _refCounted.ensureInitialized(); + } + + pragma(inline, true) private void checkInit()() inout + if (autoInit == RefCountedAutoInitialize.no) + { + assert(_refCounted.isInitialized, + "Attempted to use an uninitialized payload."); + } + + /// `SafeRefCounted` storage implementation. struct RefCountedStore { private struct Impl @@ -6658,7 +6705,7 @@ if (!is(T == class) && !(is(T == interface))) import core.lifetime : emplace, forward; allocateStore(); - version (D_Exceptions) scope(failure) deallocateStore(); + version (D_Exceptions) scope(failure) () @trusted { deallocateStore(); }(); emplace(&_store._payload, forward!args); _store._count = 1; } @@ -6668,7 +6715,7 @@ if (!is(T == class) && !(is(T == interface))) import std.algorithm.mutation : moveEmplace; allocateStore(); - moveEmplace(source, _store._payload); + () @trusted { moveEmplace(source, _store._payload); }(); _store._count = 1; } @@ -6678,13 +6725,15 @@ if (!is(T == class) && !(is(T == interface))) static if (enableGCScan) { import std.internal.memory : enforceCalloc; - _store = cast(Impl*) enforceCalloc(1, Impl.sizeof); - GC.addRange(&_store._payload, T.sizeof); + auto ptr = enforceCalloc(1, Impl.sizeof); + _store = () @trusted { return cast(Impl*) ptr; }(); + () @trusted { GC.addRange(&_store._payload, T.sizeof); }(); } else { import std.internal.memory : enforceMalloc; - _store = cast(Impl*) enforceMalloc(Impl.sizeof); + auto ptr = enforceMalloc(Impl.sizeof); + _store = () @trusted { return cast(Impl*) ptr; }(); } } @@ -6725,6 +6774,7 @@ if (!is(T == class) && !(is(T == interface))) This function is unavailable if `T.this()` is annotated with `@disable`. */ + @safe pure nothrow void ensureInitialized()() { // By checking for `@disable this()` and failing early we can @@ -6763,7 +6813,7 @@ Postcondition: `refCountedStore.isInitialized` } /// Ditto - this(T val) + this(return scope T val) { _refCounted.move(val); } @@ -6786,18 +6836,30 @@ to deallocate the corresponding resource. */ ~this() { + import std.traits : dip1000Enabled; + + // This prevents the same reference from decrementing the count twice. + scope(exit) _refCounted = _refCounted.init; + if (!_refCounted.isInitialized) return; assert(_refCounted._store._count > 0); - if (--_refCounted._store._count) - return; + if (--_refCounted._store._count) return; // Done, destroy and deallocate .destroy(_refCounted._store._payload); - _refCounted.deallocateStore(); + + static if (dip1000Enabled) + { + () @trusted { _refCounted.deallocateStore(); }(); + } + else _refCounted.deallocateStore(); } /** -Assignment operators - */ +Assignment operators. + +Note: You may not assign a new payload to an uninitialized SafeRefCounted, if +auto initialization is off. Assigning another counted reference is still okay. +*/ void opAssign(typeof(this) rhs) { import std.algorithm.mutation : swap; @@ -6810,14 +6872,7 @@ Assignment operators { import std.algorithm.mutation : move; - static if (autoInit == RefCountedAutoInitialize.yes) - { - _refCounted.ensureInitialized(); - } - else - { - assert(_refCounted.isInitialized); - } + checkInit(); move(rhs, _refCounted._store._payload); } @@ -6829,20 +6884,20 @@ Assignment operators RefCountedAutoInitialize.yes), calls $(D refCountedStore.ensureInitialized). Otherwise, just issues $(D assert(refCountedStore.isInitialized)). Used with $(D alias - refCountedPayload this;), so callers can just use the `RefCounted` + refCountedPayload this;), so callers can just use the `SafeRefCounted` object as a `T`. $(BLUE The first overload exists only if $(D autoInit == RefCountedAutoInitialize.yes).) So if $(D autoInit == RefCountedAutoInitialize.no) or called for a constant or immutable object, then - `refCountedPayload` will also be qualified as safe and nothrow + `refCountedPayload` will also be qualified as nothrow (but will still assert if not initialized). */ - @property @trusted + @property @system ref T refCountedPayload() return; /// ditto - @property nothrow @safe pure @nogc + @property nothrow @system pure @nogc ref inout(T) refCountedPayload() inout return; } else @@ -6850,19 +6905,21 @@ Assignment operators static if (autoInit == RefCountedAutoInitialize.yes) { //Can't use inout here because of potential mutation - @property + @property @system ref T refCountedPayload() return { - _refCounted.ensureInitialized(); + checkInit(); return _refCounted._store._payload; } } - - @property nothrow @safe pure @nogc - ref inout(T) refCountedPayload() inout return + else { - assert(_refCounted.isInitialized, "Attempted to access an uninitialized payload."); - return _refCounted._store._payload; + @property nothrow @system pure @nogc + ref inout(T) refCountedPayload() inout return + { + checkInit(); + return _refCounted._store._payload; + } } } @@ -6898,7 +6955,7 @@ assert(refCountedStore.isInitialized)). { // A pair of an `int` and a `size_t` - the latter being the // reference count - will be dynamically allocated - auto rc1 = RefCounted!int(5); + auto rc1 = SafeRefCounted!int(5); assert(rc1 == 5); // No more allocation, add just one extra reference count auto rc2 = rc1; @@ -6908,46 +6965,66 @@ assert(refCountedStore.isInitialized)). // the pair will be freed when rc1 and rc2 go out of scope } -pure @system unittest +// This test can't be betterC because the test extractor won't see the private +// `initialize` method accessed here +pure @safe nothrow @nogc unittest { - RefCounted!int* p; - { - auto rc1 = RefCounted!int(5); - p = &rc1; - assert(rc1 == 5); - assert(rc1._refCounted._store._count == 1); - auto rc2 = rc1; - assert(rc1._refCounted._store._count == 2); - // Reference semantics - rc2 = 42; - assert(rc1 == 42); - rc2 = rc2; - assert(rc2._refCounted._store._count == 2); - rc1 = rc2; - assert(rc1._refCounted._store._count == 2); - } - assert(p._refCounted._store == null); + auto rc1 = SafeRefCounted!(int, RefCountedAutoInitialize.no)(5); + rc1._refCounted.initialize(); +} - // RefCounted as a member - struct A +pure @system unittest +{ + foreach (MyRefCounted; AliasSeq!(SafeRefCounted, RefCounted)) { - RefCounted!int x; - this(int y) + MyRefCounted!int* p; { - x._refCounted.initialize(y); + auto rc1 = MyRefCounted!int(5); + p = &rc1; + assert(rc1 == 5); + assert(rc1._refCounted._store._count == 1); + auto rc2 = rc1; + assert(rc1._refCounted._store._count == 2); + // Reference semantics + rc2 = 42; + assert(rc1 == 42); + rc2 = rc2; + assert(rc2._refCounted._store._count == 2); + rc1 = rc2; + assert(rc1._refCounted._store._count == 2); } - A copy() + assert(p._refCounted._store == null); + + // [Safe]RefCounted as a member + struct A { - auto another = this; - return another; + MyRefCounted!int x; + this(int y) + { + x._refCounted.initialize(y); + } + A copy() + { + auto another = this; + return another; + } } - } - auto a = A(4); - auto b = a.copy(); - assert(a.x._refCounted._store._count == 2, - "https://issues.dlang.org/show_bug.cgi?id=4356 still unfixed"); + auto a = A(4); + auto b = a.copy(); + assert(a.x._refCounted._store._count == 2, + "https://issues.dlang.org/show_bug.cgi?id=4356 still unfixed"); + } } +@betterC pure @safe nothrow @nogc unittest +{ + import std.algorithm.mutation : swap; + + SafeRefCounted!int p1, p2; + swap(p1, p2); +} + +// Same as above but for old RefCounted and not @safe @betterC pure @system nothrow @nogc unittest { import std.algorithm.mutation : swap; @@ -6968,25 +7045,52 @@ pure @system unittest U u; } + alias SRC = SafeRefCounted!S; +} + +// Same as above but for old RefCounted and not @safe +@betterC @system pure nothrow @nogc unittest +{ + union U { + size_t i; + void* p; + } + + struct S { + U u; + } + alias SRC = RefCounted!S; } // https://issues.dlang.org/show_bug.cgi?id=6436 @betterC @system pure unittest { + import std.meta : AliasSeq; struct S { this(int rval) { assert(rval == 1); } this(ref int lval) { assert(lval == 3); ++lval; } } - auto s1 = RefCounted!S(1); - int lval = 3; - auto s2 = RefCounted!S(lval); - assert(lval == 4); + foreach (MyRefCounted; AliasSeq!(SafeRefCounted, RefCounted)) + { + auto s1 = MyRefCounted!S(1); + int lval = 3; + auto s2 = MyRefCounted!S(lval); + assert(lval == 4); + } } // gc_addRange coverage +@betterC @safe pure unittest +{ + struct S { int* p; } + + auto s = SafeRefCounted!S(null); +} + +// Same as above but for old RefCounted and not @safe @betterC @system pure unittest { struct S { int* p; } @@ -6996,69 +7100,253 @@ pure @system unittest @betterC @system pure nothrow @nogc unittest { - RefCounted!int a; - a = 5; //This should not assert - assert(a == 5); + import std.meta : AliasSeq; + foreach (MyRefCounted; AliasSeq!(SafeRefCounted, RefCounted)) + { + MyRefCounted!int a; + a = 5; //This should not assert + assert(a == 5); - RefCounted!int b; - b = a; //This should not assert either - assert(b == 5); + MyRefCounted!int b; + b = a; //This should not assert either + assert(b == 5); - RefCounted!(int*) c; + MyRefCounted!(int*) c; + } } // https://issues.dlang.org/show_bug.cgi?id=21638 @betterC @system pure nothrow @nogc unittest { + import std.meta : AliasSeq; static struct NoDefaultCtor { @disable this(); this(int x) @nogc nothrow pure { this.x = x; } int x; } - auto rc = RefCounted!(NoDefaultCtor, RefCountedAutoInitialize.no)(5); - assert(rc.x == 5); + + foreach (MyRefCounted; AliasSeq!(SafeRefCounted, RefCounted)) + { + auto rc = MyRefCounted!(NoDefaultCtor, RefCountedAutoInitialize.no)(5); + assert(rc.x == 5); + } } // https://issues.dlang.org/show_bug.cgi?id=20502 @system unittest { - import std.conv : to; - // Check that string conversion is transparent for refcounted - // structs that do not have either toString or alias this. - static struct A { Object a; } - auto a = A(new Object()); - auto r = refCounted(a); - assert(to!string(r) == to!string(a)); - assert(to!string(cast(const) r) == to!string(cast(const) a)); - // Check that string conversion is still transparent for refcounted - // structs that have alias this. - static struct B { int b; alias b this; } - static struct C { B b; alias b this; } - assert(to!string(refCounted(C(B(123)))) == to!string(C(B(123)))); - // https://issues.dlang.org/show_bug.cgi?id=22093 - // Check that uninitialized refcounted structs that previously could be - // converted to strings still can be. - alias R = typeof(r); - R r2; - cast(void) (((const ref R a) => to!string(a))(r2)); - cast(void) to!string(RefCounted!(A, RefCountedAutoInitialize.no).init); + alias Types = AliasSeq!(SafeRefCounted, RefCounted); + alias funcs = AliasSeq!(safeRefCounted, refCounted); + static foreach (aliasI; 0 .. 2) + {{ + alias MyRefCounted = Types[aliasI]; + alias myRefCounted = funcs[aliasI]; + import std.conv : to; + + // Check that string conversion is transparent for refcounted + // structs that do not have either toString or alias this. + static struct A { Object a; } + auto a = A(new Object()); + auto r = myRefCounted(a); + assert(to!string(r) == to!string(a)); + assert(to!string(cast(const) r) == to!string(cast(const) a)); + // Check that string conversion is still transparent for refcounted + // structs that have alias this. + static struct B { int b; alias b this; } + static struct C { B b; alias b this; } + assert(to!string(myRefCounted(C(B(123)))) == to!string(C(B(123)))); + // https://issues.dlang.org/show_bug.cgi?id=22093 + // Check that uninitialized refcounted structs that previously could be + // converted to strings still can be. + alias R = typeof(r); + R r2; + cast(void) (((const ref R a) => to!string(a))(r2)); + cast(void) to!string(MyRefCounted!(A, RefCountedAutoInitialize.no).init); + }} +} + +// We tried to make `refCountedPayload` `@safe` in +// https://github.com/dlang/phobos/pull/8368 . It proved impossible, but it may +// be possible in the future. This test checks for false `@safe` issues we +// encountered. +@safe unittest +{ + struct Container + { + int[] data; + } + + int[] getArr1 (scope Container local) + { + // allowed because the argument is inferred as return scope. + return local.data; + } + + int[] getArr2 (scope Container local) + { + SafeRefCounted!Container rc = local; + // Escapes a reference to expired reference counted struct + // don't do this! + return rc.refCountedPayload().data; + } + + int destroyFirstAndUseLater() + { + auto rc = SafeRefCounted!int(123); + int* ptr = &rc.refCountedPayload(); + destroy(rc); + return *ptr; + } + + // This is here mainly to test that safety gets inferred correctly for the + // next tests + static assert(isSafe!getArr1); + // https://github.com/dlang/phobos/pull/8101#issuecomment-843017282 + // This got apparently fixed automatically by compiler updates. + static assert(!isSafe!getArr2); + // As of writing, this is the issue that is still preventing payload access + // from being `@safe` + static assert(!isSafe!destroyFirstAndUseLater); +} + +/** +Borrows the payload of $(LREF SafeRefCounted) for use in `fun`. Inferred as `@safe` +if `fun` is `@safe` and does not escape a reference to the payload. +The reference count will be incremented for the duration of the operation, +so destroying the last reference will not leave dangling references in +`fun`. + +Params: + fun = A callable accepting the payload either by value or by reference. + refCount = The counted reference to the payload. +Returns: + The return value of `fun`, if any. `ref` in the return value will be + forwarded. +Issues: + For yet unknown reason, code that uses this function with UFCS syntax + will not be inferred as `@safe`. It will still compile if the code is + explicitly marked `@safe` and nothing in `fun` prevents that. +*/ +template borrow(alias fun) +{ + import std.functional : unaryFun; + + auto ref borrow(RC)(RC refCount) if + ( + isInstanceOf!(SafeRefCounted, RC) + && is(typeof(unaryFun!fun(refCount.refCountedPayload))) + ) + { + refCount.checkInit(); + + // If `fun` escapes a reference to the payload, it will be inferred + // as unsafe due to the scope storage class here. + scope plPtr = &refCount._refCounted._store._payload; + return unaryFun!fun(*plPtr); + + // We destroy our copy of the reference here, automatically destroying + // the payload if `fun` destroyed the last reference outside. + } +} + +/// This example can be marked `@safe` with `-preview=dip1000`. +@safe pure nothrow unittest +{ + auto rcInt = safeRefCounted(5); + assert(rcInt.borrow!(theInt => theInt) == 5); + auto sameInt = rcInt; + assert(sameInt.borrow!"a" == 5); + + // using `ref` in the function + auto arr = [0, 1, 2, 3, 4, 5, 6]; + sameInt.borrow!(ref (x) => arr[x]) = 10; + assert(arr == [0, 1, 2, 3, 4, 10, 6]); + + // modifying the payload via an alias + sameInt.borrow!"a*=2"; + assert(rcInt.borrow!"a" == 10); +} + +// Some memory safety penetration testing. +@system unittest +{ + int* globalPtr; + int torpedoesFired = 0; + struct Destroyer { ~this() @safe { torpedoesFired++; } } + + alias RcInt = typeof(safeRefCounted(0)); + auto standardUsage(RcInt arg) + { + return borrow!((ref x) => x)(arg); + } + ref harmlessRefReturn(RcInt arg) + { + return borrow!(ref (ref x) => *globalPtr = x)(arg); + } + ref problematicRefReturn(RcInt arg) + { + return borrow!(ref (ref x) => x)(arg); + } + auto sideChannelEscape(RcInt arg) + { + return borrow!((ref x) + { + globalPtr = &x; + return x; + })(arg); + } + auto destroyDuringApply() + { + auto rc = safeRefCounted(Destroyer()); + return borrow!((ref x) + { + // Destroys the last reference to the payload, decrementing it's + // reference count. + rc.__dtor(); + // Destroy again! rc should be set to it's init value so that this + // won't decrement the reference count of the original payload. + rc.__dtor(); + // The internal reference count increment done for duration of + // `apply` should make sure that the payload destructor is not yet + // run, and this value thus not incremented. + return torpedoesFired; + })(rc); + } + + // First, let's verify the dangerous functions really do what they are + // supposed to do. + auto testRc = safeRefCounted(42); + assert(sideChannelEscape(testRc) == 42); + assert(&problematicRefReturn(testRc) == globalPtr); + + // Now, are the @safe attributes inferred correctly? + assert(isSafe!standardUsage); + assert(isSafe!harmlessRefReturn); + assert(!isSafe!problematicRefReturn); + assert(!isSafe!sideChannelEscape); + assert(isSafe!destroyDuringApply); + + // Finally, we test protection against early destruction during `apply`. + auto torpedoesUpToReturn = destroyDuringApply(); + assert(torpedoesFired == torpedoesUpToReturn + 1); } /** - * Initializes a `RefCounted` with `val`. The template parameter - * `T` of `RefCounted` is inferred from `val`. + * Initializes a `SafeRefCounted` with `val`. The template parameter + * `T` of `SafeRefCounted` is inferred from `val`. * This function can be used to move non-copyable values to the heap. - * It also disables the `autoInit` option of `RefCounted`. + * It also disables the `autoInit` option of `SafeRefCounted`. * * Params: * val = The value to be reference counted * Returns: - * An initialized `RefCounted` containing `val`. + * An initialized `SafeRefCounted` containing `val`. * See_Also: + * $(LREF refCounted) * $(HTTP en.cppreference.com/w/cpp/memory/shared_ptr/make_shared, C++'s make_shared) */ -RefCounted!(T, RefCountedAutoInitialize.no) refCounted(T)(T val) +SafeRefCounted!(T, RefCountedAutoInitialize.no) safeRefCounted(T)(T val) { typeof(return) res; res._refCounted.move(val); @@ -7083,13 +7371,13 @@ RefCounted!(T, RefCountedAutoInitialize.no) refCounted(T)(T val) assert(File.nDestroyed == 0); - // make the file refcounted to share ownership + // make the file ref counted to share ownership // Note: - // We write a compound statement (brace-delimited scope) in which all `RefCounted!File` handles are created and deleted. + // We write a compound statement (brace-delimited scope) in which all `SafeRefCounted!File` handles are created and deleted. // This allows us to see (after the scope) what happens after all handles have been destroyed. { // We move the content of `file` to a separate (and heap-allocated) `File` object, - // managed-and-accessed via one-or-multiple (initially: one) `RefCounted!File` objects ("handles"). + // managed-and-accessed via one-or-multiple (initially: one) `SafeRefCounted!File` objects ("handles"). // This "moving": // (1) invokes `file`'s destructor (=> `File.nDestroyed` is incremented from 0 to 1 and `file.name` becomes `null`); // (2) overwrites `file` with `File.init` (=> `file.name` becomes `null`). @@ -7097,18 +7385,18 @@ RefCounted!(T, RefCountedAutoInitialize.no) refCounted(T)(T val) // but please note that (2) is only performed if `File` defines a destructor (or post-blit operator), // and in the absence of the `nDestroyed` instrumentation there would have been no reason to define a destructor. import std.algorithm.mutation : move; - auto rcFile = refCounted(move(file)); + auto rcFile = safeRefCounted(move(file)); assert(rcFile.name == "name"); assert(File.nDestroyed == 1); assert(file.name == null); - // We create another `RefCounted!File` handle to the same separate `File` object. + // We create another `SafeRefCounted!File` handle to the same separate `File` object. // While any of the handles is still alive, the `File` object is kept alive (=> `File.nDestroyed` is not modified). auto rcFile2 = rcFile; assert(rcFile.refCountedStore.refCount == 2); assert(File.nDestroyed == 1); } - // The separate `File` object is deleted when the last `RefCounted!File` handle is destroyed + // The separate `File` object is deleted when the last `SafeRefCounted!File` handle is destroyed // (i.e. at the closing brace of the compound statement above, which destroys both handles: `rcFile` and `rcFile2`) // (=> `File.nDestroyed` is incremented again, from 1 to 2): assert(File.nDestroyed == 2); @@ -9823,3 +10111,265 @@ unittest Nullable!S s2 = s1; assert(s2.get().b == 3); } + +/// The old version of $(LREF SafeRefCounted), before $(LREF borrow) existed. +/// Old code may be relying on `@safe`ty of some of the member functions which +/// cannot be safe in the new scheme, and +/// can avoid breakage by continuing to use this. `SafeRefCounted` should be +/// preferred, as this type is outdated and unrecommended for new code. +struct RefCounted(T, RefCountedAutoInitialize autoInit = + RefCountedAutoInitialize.yes) +{ + version (D_BetterC) + { + private enum enableGCScan = false; + } + else + { + private enum enableGCScan = hasIndirections!T; + } + + extern(C) private pure nothrow @nogc static + { + pragma(mangle, "free") void pureFree( void *ptr ); + static if (enableGCScan) + import core.memory : GC; + } + + struct RefCountedStore + { + private struct Impl + { + T _payload; + size_t _count; + } + + private Impl* _store; + + private void initialize(A...)(auto ref A args) + { + import core.lifetime : emplace, forward; + + allocateStore(); + version (D_Exceptions) scope(failure) deallocateStore(); + emplace(&_store._payload, forward!args); + _store._count = 1; + } + + private void move(ref T source) nothrow pure + { + import std.algorithm.mutation : moveEmplace; + + allocateStore(); + moveEmplace(source, _store._payload); + _store._count = 1; + } + + // 'nothrow': can only generate an Error + private void allocateStore() nothrow pure + { + static if (enableGCScan) + { + import std.internal.memory : enforceCalloc; + _store = cast(Impl*) enforceCalloc(1, Impl.sizeof); + GC.addRange(&_store._payload, T.sizeof); + } + else + { + import std.internal.memory : enforceMalloc; + _store = cast(Impl*) enforceMalloc(Impl.sizeof); + } + } + + private void deallocateStore() nothrow pure + { + static if (enableGCScan) + { + GC.removeRange(&this._store._payload); + } + pureFree(_store); + _store = null; + } + + @property nothrow @safe pure @nogc + bool isInitialized() const + { + return _store !is null; + } + + @property nothrow @safe pure @nogc + size_t refCount() const + { + return isInitialized ? _store._count : 0; + } + + void ensureInitialized()() + { + // By checking for `@disable this()` and failing early we can + // produce a clearer error message. + static assert(__traits(compiles, { static T t; }), + "Cannot automatically initialize `" ~ fullyQualifiedName!T ~ + "` because `" ~ fullyQualifiedName!T ~ + ".this()` is annotated with `@disable`."); + if (!isInitialized) initialize(); + } + + } + RefCountedStore _refCounted; + + @property nothrow @safe + ref inout(RefCountedStore) refCountedStore() inout + { + return _refCounted; + } + + this(A...)(auto ref A args) if (A.length > 0) + out + { + assert(refCountedStore.isInitialized); + } + do + { + import core.lifetime : forward; + _refCounted.initialize(forward!args); + } + + this(T val) + { + _refCounted.move(val); + } + + this(this) @safe pure nothrow @nogc + { + if (!_refCounted.isInitialized) return; + ++_refCounted._store._count; + } + + ~this() + { + if (!_refCounted.isInitialized) return; + assert(_refCounted._store._count > 0); + if (--_refCounted._store._count) + return; + // Done, destroy and deallocate + .destroy(_refCounted._store._payload); + _refCounted.deallocateStore(); + } + + void opAssign(typeof(this) rhs) + { + import std.algorithm.mutation : swap; + + swap(_refCounted._store, rhs._refCounted._store); + } + + void opAssign(T rhs) + { + import std.algorithm.mutation : move; + + static if (autoInit == RefCountedAutoInitialize.yes) + { + _refCounted.ensureInitialized(); + } + else + { + assert(_refCounted.isInitialized); + } + move(rhs, _refCounted._store._payload); + } + + static if (autoInit == RefCountedAutoInitialize.yes) + { + //Can't use inout here because of potential mutation + @property + ref T refCountedPayload() return + { + _refCounted.ensureInitialized(); + return _refCounted._store._payload; + } + } + + @property nothrow @safe pure @nogc + ref inout(T) refCountedPayload() inout return + { + assert(_refCounted.isInitialized, "Attempted to access an uninitialized payload."); + return _refCounted._store._payload; + } + + alias refCountedPayload this; + + static if (is(T == struct) && !is(typeof((ref T t) => t.toString()))) + { + string toString(this This)() + { + import std.conv : to; + + static if (autoInit) + return to!string(refCountedPayload); + else + { + if (!_refCounted.isInitialized) + return This.stringof ~ "(RefCountedStore(null))"; + else + return to!string(_refCounted._store._payload); + } + } + } +} + +/// +@betterC pure @system nothrow @nogc unittest +{ + auto rc1 = RefCounted!int(5); + assert(rc1 == 5); + auto rc2 = rc1; + rc2 = 42; + assert(rc1 == 42); +} + +// More unit tests below SafeRefCounted + +/** + * Like $(LREF safeRefCounted) but used to initialize $(LREF RefCounted) + * instead. Intended for backwards compatibility, otherwise it is preferable + * to use `safeRefCounted`. + */ +RefCounted!(T, RefCountedAutoInitialize.no) refCounted(T)(T val) +{ + typeof(return) res; + res._refCounted.move(val); + return res; +} + +/// +@system unittest +{ + static struct File + { + static size_t nDestroyed; + string name; + @disable this(this); // not copyable + ~this() { name = null; ++nDestroyed; } + } + + auto file = File("name"); + assert(file.name == "name"); + static assert(!__traits(compiles, {auto file2 = file;})); + assert(File.nDestroyed == 0); + + { + import std.algorithm.mutation : move; + auto rcFile = refCounted(move(file)); + assert(rcFile.name == "name"); + assert(File.nDestroyed == 1); + assert(file.name == null); + + auto rcFile2 = rcFile; + assert(rcFile.refCountedStore.refCount == 2); + assert(File.nDestroyed == 1); + } + + assert(File.nDestroyed == 2); +} + +// More unit tests below safeRefCounted diff --git a/libphobos/src/std/uni/package.d b/libphobos/src/std/uni/package.d index 8a032aaa514..81b949e97f8 100644 --- a/libphobos/src/std/uni/package.d +++ b/libphobos/src/std/uni/package.d @@ -10193,16 +10193,7 @@ bool isAlpha(dchar c) // optimization if (c < 0xAA) { - size_t x = c - 'A'; - if (x <= 'Z' - 'A') - return true; - else - { - x = c - 'a'; - if (x <= 'z'-'a') - return true; - } - return false; + return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'); } return alphaTrie[c];