From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mout-p-102.mailbox.org (mout-p-102.mailbox.org [IPv6:2001:67c:2050:0:465::102]) by sourceware.org (Postfix) with ESMTPS id 66C8538582A1 for ; Sun, 20 Aug 2023 09:21:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 66C8538582A1 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=gdcproject.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gdcproject.org Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:b231:465::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-102.mailbox.org (Postfix) with ESMTPS id 4RT9891bRwz9tHB; Sun, 20 Aug 2023 11:20:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gdcproject.org; s=MBO0001; t=1692523257; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=mr0Lg7s6UX8U9fpZ6JV2Mh7SjI89UK7n/F+jk9tcYEM=; b=Ryg+BkR+6snyALiZp+JPvk2ZQphTdFjtapFIStqebGCLYZPGGGPB3zucTY/L0ME373F8ys IuPKAUcrgWc6vcfU8Cx+pLjQk4bHzJbwxwpgZyu6UUdo9M9W0BELhMm0ckEP7H9/RMU/xg Zz5oP6F2K42zfmnlaoDohRspM52UIo8+MBHR0uNmSlJNLIo7Jfghlo5Kw1U7NPIPiivp// DGkO9ZccPG94UjUDo2XBOqblZOyvq+Dfu46H+J3zddFytl8YfwH9X7bAfOftT3xMFgn5kb 3u3ba/hI3MB3UPc+scc2VN8oWKxiq9ZTtLcm6puj3Bw4ET6fy+mCIXDDOudrhg== From: Iain Buclaw To: gcc-patches@gcc.gnu.org Cc: Iain Buclaw Subject: [committed] d: Merge upstream dmd, druntime 26f049fb26, phobos 330d6a4fd. Date: Sun, 20 Aug 2023 11:20:54 +0200 Message-Id: <20230820092054.380256-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 4RT9891bRwz9tHB X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_LOTSOFHASH,RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Hi, This patch merges the D front-end and run-time library with upstream dmd 26f049fb26, and standard library with phobos 330d6a4fd. Synchronizing with the latest bug fixes in the v2.105.0-beta.1 release. D front-end changes: - Import dmd v2.105.0-beta.1. - Added predefined version identifier VisionOS (ignored by GDC). - Functions can no longer have `enum` storage class. - The deprecation of the `body` keyword has been reverted, it is now an obsolete feature. - The error for `scope class` has been reverted, it is now an obsolete feature. D runtime changes: - Import druntime v2.105.0-beta.1. Phobos changes: - Import phobos v2.105.0-beta.1. - AliasSeq has been removed from std.math. - extern(C) getdelim and getline have been removed from std.stdio. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 26f049fb26. * dmd/VERSION: Bump version to v2.105.0-beta.1. * d-codegen.cc (get_frameinfo): Check useGC in condition. * d-lang.cc (d_handle_option): Set obsolete parameter when compiling with -Wall. (d_post_options): Set useGC to false when compiling with -fno-druntime. Propagate obsolete flag to compileEnv. * expr.cc (ExprVisitor::visit (CatExp *)): Check useGC in condition. Bootstrapped and regression tested on x86_64-linux-gnu/-m32, committed to mainline. Regards, Iain. --- libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 26f049fb26. * src/MERGE: Merge upstream phobos 330d6a4fd. --- gcc/d/d-codegen.cc | 2 +- gcc/d/d-lang.cc | 3 + gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/VERSION | 2 +- gcc/d/dmd/clone.d | 2 +- gcc/d/dmd/common/string.d | 2 +- gcc/d/dmd/cond.d | 1 + gcc/d/dmd/cparse.d | 10 +- gcc/d/dmd/dsymbolsem.d | 194 ++++++++++-------- gcc/d/dmd/errors.d | 34 +-- gcc/d/dmd/expression.d | 24 ++- gcc/d/dmd/expression.h | 6 +- gcc/d/dmd/expressionsem.d | 4 +- gcc/d/dmd/func.d | 18 +- gcc/d/dmd/globals.d | 10 +- gcc/d/dmd/globals.h | 11 +- gcc/d/dmd/initsem.d | 25 ++- gcc/d/dmd/lexer.d | 1 + gcc/d/dmd/nogc.d | 2 +- gcc/d/dmd/parse.d | 86 +++++--- gcc/d/dmd/semantic3.d | 3 +- gcc/d/dmd/target.d | 4 +- gcc/d/dmd/target.h | 2 +- gcc/d/dmd/traits.d | 23 ++- gcc/d/expr.cc | 2 +- gcc/testsuite/gdc.test/compilable/cppmangle.d | 1 - .../gdc.test/compilable/deprecate14283.d | 8 +- .../gdc.test/compilable/emptystatement.d | 19 ++ .../gdc.test/compilable/imports/imp24022.c | 5 + .../gdc.test/compilable/parens_inc.d | 23 +++ gcc/testsuite/gdc.test/compilable/test23951.d | 10 + gcc/testsuite/gdc.test/compilable/test23966.d | 19 ++ gcc/testsuite/gdc.test/compilable/test24022.d | 30 +++ gcc/testsuite/gdc.test/compilable/test7172.d | 6 +- .../gdc.test/fail_compilation/biterrors3.d | 2 +- .../gdc.test/fail_compilation/body.d | 11 + .../gdc.test/fail_compilation/ccast.d | 21 +- .../gdc.test/fail_compilation/diag4596.d | 4 +- .../gdc.test/fail_compilation/enum_function.d | 13 ++ .../gdc.test/fail_compilation/fail10285.d | 12 +- .../gdc.test/fail_compilation/fail13116.d | 2 +- .../gdc.test/fail_compilation/fail15896.d | 1 + .../gdc.test/fail_compilation/fail22729.d | 2 +- .../gdc.test/fail_compilation/fail22780.d | 2 +- .../gdc.test/fail_compilation/fail4559.d | 22 -- .../gdc.test/fail_compilation/format.d | 21 +- .../fail_compilation/reserved_version.d | 2 + .../gdc.test/fail_compilation/scope_class.d | 2 +- .../gdc.test/fail_compilation/scope_type.d | 16 -- .../gdc.test/fail_compilation/test23279.d | 14 ++ .../gdc.test/fail_compilation/typeerrors.d | 2 +- gcc/testsuite/gdc.test/runnable/betterc.d | 11 + gcc/testsuite/gdc.test/runnable/sctor2.d | 5 - gcc/testsuite/gdc.test/runnable/test24029.c | 23 +++ .../gdc.test/runnable/testcontracts.d | 16 -- libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/core/int128.d | 8 +- .../core/internal/array/comparison.d | 25 ++- libphobos/libdruntime/core/lifetime.d | 6 +- libphobos/src/MERGE | 2 +- libphobos/src/std/algorithm/searching.d | 17 ++ libphobos/src/std/bigint.d | 23 ++- libphobos/src/std/json.d | 4 + libphobos/src/std/math/package.d | 6 - libphobos/src/std/stdio.d | 15 -- 65 files changed, 598 insertions(+), 308 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/emptystatement.d create mode 100644 gcc/testsuite/gdc.test/compilable/imports/imp24022.c create mode 100644 gcc/testsuite/gdc.test/compilable/parens_inc.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23951.d create mode 100644 gcc/testsuite/gdc.test/compilable/test23966.d create mode 100644 gcc/testsuite/gdc.test/compilable/test24022.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/body.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/enum_function.d delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail4559.d delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/scope_type.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test23279.d create mode 100644 gcc/testsuite/gdc.test/runnable/test24029.c diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc index 2738958fde1..155f5d0d618 100644 --- a/gcc/d/d-codegen.cc +++ b/gcc/d/d-codegen.cc @@ -2850,7 +2850,7 @@ get_frameinfo (FuncDeclaration *fd) /* This can shift due to templates being expanded that access alias symbols, give it a decent error for now. */ if (requiresClosure != fd->requiresClosure - && (fd->nrvo_var || global.params.betterC)) + && (fd->nrvo_var || !global.params.useGC)) fd->checkClosure (); /* Set-up a closure frame, this will be allocated on the heap. */ diff --git a/gcc/d/d-lang.cc b/gcc/d/d-lang.cc index 7cb86bf268f..10b9000119e 100644 --- a/gcc/d/d-lang.cc +++ b/gcc/d/d-lang.cc @@ -779,6 +779,7 @@ d_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value, case OPT_Wall: if (value) global.params.warnings = DIAGNOSTICinform; + global.params.obsolete = value; break; case OPT_Wdeprecated: @@ -894,6 +895,7 @@ d_post_options (const char ** fn) flag_exceptions = false; } + global.params.useGC = false; global.params.checkAction = CHECKACTION_C; } @@ -939,6 +941,7 @@ d_post_options (const char ** fn) global.compileEnv.previewIn = global.params.previewIn; global.compileEnv.ddocOutput = global.params.ddoc.doOutput; global.compileEnv.shortenedMethods = global.params.shortenedMethods; + global.compileEnv.obsolete = global.params.obsolete; /* Add in versions given on the command line. */ if (global.params.versionids) diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 308d51b55d0..a02a8cbaba5 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -a88e1335f7ea767ef438c34998f5d1f26008c586 +26f049fb26e755096dea3f1474decea7c0fef187 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 9c46eea2d8c..6faa8d801e6 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.104.1 +v2.105.0-beta.1 diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d index 3586f20ddbe..4cff1ecf49c 100644 --- a/gcc/d/dmd/clone.d +++ b/gcc/d/dmd/clone.d @@ -1263,7 +1263,7 @@ FuncDeclaration buildPostBlit(StructDeclaration sd, Scope* sc) // block to destroy any prior successfully postblitted fields should // this field's postblit fail. // Don't generate it for betterC code since it cannot throw exceptions. - if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow && !global.params.betterC) + if (fieldsToDestroy.length > 0 && !(cast(TypeFunction)sdv.postblit.type).isnothrow && global.params.useExceptions) { // create a list of destructors that need to be called Expression[] dtorCalls; diff --git a/gcc/d/dmd/common/string.d b/gcc/d/dmd/common/string.d index a1614fd907c..6de921e3d7a 100644 --- a/gcc/d/dmd/common/string.d +++ b/gcc/d/dmd/common/string.d @@ -48,7 +48,7 @@ struct SmallBuffer(Element) } else { - assert(len < sizeof.max / Element.sizeof); + assert(len < sizeof.max / (2 * Element.sizeof)); _extent = (cast(typeof(_extent.ptr)) malloc(len * Element.sizeof))[0 .. len]; _extent.ptr || assert(0, "Out of memory."); needsFree = true; diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d index fcb50e0a648..467f9f1a990 100644 --- a/gcc/d/dmd/cond.d +++ b/gcc/d/dmd/cond.d @@ -733,6 +733,7 @@ extern (C++) final class VersionCondition : DVCondition case "SysV4": case "TVOS": case "unittest": + case "VisionOS": case "WASI": case "WatchOS": case "WebAssembly": diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d index 1b6b2bb4b1b..03383d13fd5 100644 --- a/gcc/d/dmd/cparse.d +++ b/gcc/d/dmd/cparse.d @@ -1911,14 +1911,12 @@ final class CParser(AST) : Parser!AST if (tt.id || tt.tok == TOK.enum_) { if (!tt.id && id) + /* This applies for enums declared as + * typedef enum {A} E; + */ tt.id = id; Specifier spec; - auto stag = declareTag(tt, spec); - if (tt.tok == TOK.enum_) - { - isalias = false; - s = new AST.AliasDeclaration(token.loc, id, stag); - } + declareTag(tt, spec); } } if (isalias) diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index 622e28691a6..7a800bddd02 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -1459,9 +1459,12 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (sym) { import dmd.access : symbolIsVisible; - if (!symbolIsVisible(sc, sym)) + if (!symbolIsVisible(sc, sym) && !sym.errors) + { imp.mod.error(imp.loc, "member `%s` is not visible from module `%s`", imp.names[i].toChars(), sc._module.toChars()); + sym.errors = true; + } ad.dsymbolSemantic(sc); // If the import declaration is in non-root module, // analysis of the aliased symbol is deferred. @@ -2231,11 +2234,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (!(sc.flags & SCOPE.Cfile)) // C enum remains incomplete until members are done ed.semanticRun = PASS.semanticdone; - // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint - // Deprecated in 2.100 - // Make an error in 2.110 - if (sc.stc & STC.scope_) - deprecation(ed.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + version (none) + { + // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint + // Deprecated in 2.100 + // Make an error in 2.110 + if (sc.stc & STC.scope_) + deprecation(ed.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + } Scope* sce; if (ed.isAnonymous()) @@ -3176,6 +3182,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor funcdecl.skipCodegen = true; funcdecl._linkage = sc.linkage; + if (sc.flags & SCOPE.Cfile && funcdecl.isFuncLiteralDeclaration()) + funcdecl._linkage = LINK.d; // so they are uniquely mangled + if (auto fld = funcdecl.isFuncLiteralDeclaration()) { if (fld.treq) @@ -3460,77 +3469,10 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor if (funcdecl.isAbstract() && funcdecl.isFinalFunc()) funcdecl.error("cannot be both `final` and `abstract`"); - version (none) - { - if (funcdecl.isAbstract() && funcdecl.fbody) - funcdecl.error("`abstract` functions cannot have bodies"); - } - - version (none) - { - if (funcdecl.isStaticConstructor() || funcdecl.isStaticDestructor()) - { - if (!funcdecl.isStatic() || funcdecl.type.nextOf().ty != Tvoid) - funcdecl.error("static constructors / destructors must be `static void`"); - if (f.arguments && f.arguments.length) - funcdecl.error("static constructors / destructors must have empty parameter list"); - // BUG: check for invalid storage classes - } - } if (funcdecl.printf || funcdecl.scanf) { - /* printf/scanf-like functions must be of the form: - * extern (C/C++) T printf([parameters...], const(char)* format, ...); - * or: - * extern (C/C++) T vprintf([parameters...], const(char)* format, va_list); - */ - - static bool isPointerToChar(Parameter p) - { - if (auto tptr = p.type.isTypePointer()) - { - return tptr.next.ty == Tchar; - } - return false; - } - - bool isVa_list(Parameter p) - { - return p.type.equals(target.va_listType(funcdecl.loc, sc)); - } - - const nparams = f.parameterList.length; - if ((f.linkage == LINK.c || f.linkage == LINK.cpp) && - - (f.parameterList.varargs == VarArg.variadic && - nparams >= 1 && - isPointerToChar(f.parameterList[nparams - 1]) || - - f.parameterList.varargs == VarArg.none && - nparams >= 2 && - isPointerToChar(f.parameterList[nparams - 2]) && - isVa_list(f.parameterList[nparams - 1]) - ) - ) - { - // the signature is valid for printf/scanf, no error - } - else - { - 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)*, ...)`" - ~ " not `%s`", - p, f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars()); - } - else - { - funcdecl.error("`pragma(%s)` functions must be `extern(C) %s %s([parameters...], const(char)*, va_list)`", - p, f.next.toChars(), funcdecl.toChars()); - } - } + checkPrintfScanfSignature(funcdecl, f, sc); } if (auto id = parent.isInterfaceDeclaration()) @@ -4869,11 +4811,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor sd.deferred.semantic3(sc); } - // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint - // Deprecated in 2.100 - // Make an error in 2.110 - if (sd.storage_class & STC.scope_) - deprecation(sd.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + version (none) + { + // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint + // Deprecated in 2.100 + // Make an error in 2.110 + if (sd.storage_class & STC.scope_) + deprecation(sd.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + } //printf("-StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", sd, sd.toPrettyChars(), sd.sizeok); } @@ -5538,12 +5483,15 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } //printf("-ClassDeclaration.dsymbolSemantic(%s), type = %p, sizeok = %d, this = %p\n", toChars(), type, sizeok, this); - // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint - // Deprecated in 2.100 - // Make an error in 2.110 - // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036 - if (cldec.storage_class & STC.scope_) - deprecation(cldec.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + version (none) + { + // @@@DEPRECATED_2.110@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint + // Deprecated in 2.100 + // Make an error in 2.110 + // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036 + if (cldec.storage_class & STC.scope_) + deprecation(cldec.loc, "`scope` as a type constraint is deprecated. Use `scope` at the usage site."); + } } override void visit(InterfaceDeclaration idec) @@ -5844,12 +5792,15 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor } assert(idec.type.ty != Tclass || (cast(TypeClass)idec.type).sym == idec); - // @@@DEPRECATED_2.120@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint - // Deprecated in 2.087 - // Made an error in 2.100, but removal depends on `scope class` being removed too - // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036 - if (idec.storage_class & STC.scope_) - error(idec.loc, "`scope` as a type constraint is obsolete. Use `scope` at the usage site."); + version (none) + { + // @@@DEPRECATED_2.120@@@ https://dlang.org/deprecate.html#scope%20as%20a%20type%20constraint + // Deprecated in 2.087 + // Made an error in 2.100, but removal depends on `scope class` being removed too + // Don't forget to remove code at https://github.com/dlang/dmd/blob/b2f8274ba76358607fc3297a1e9f361480f9bcf9/src/dmd/dsymbolsem.d#L1032-L1036 + if (idec.storage_class & STC.scope_) + error(idec.loc, "`scope` as a type constraint is obsolete. Use `scope` at the usage site."); + } } } @@ -7386,3 +7337,64 @@ private void writeMixin(const(char)[] s, ref const Loc loc, ref int lines, ref O buf.writenl(); ++lines; } + +/** + * Check signature of `pragma(printf)` function, print error if invalid. + * + * printf/scanf-like functions must be of the form: + * extern (C/C++) T printf([parameters...], const(char)* format, ...); + * or: + * extern (C/C++) T vprintf([parameters...], const(char)* format, va_list); + * + * Params: + * funcdecl = function to check + * f = function type + * sc = scope + */ +void checkPrintfScanfSignature(FuncDeclaration funcdecl, TypeFunction f, Scope* sc) +{ + static bool isPointerToChar(Parameter p) + { + if (auto tptr = p.type.isTypePointer()) + { + return tptr.next.ty == Tchar; + } + return false; + } + + bool isVa_list(Parameter p) + { + return p.type.equals(target.va_listType(funcdecl.loc, sc)); + } + + const nparams = f.parameterList.length; + const p = (funcdecl.printf ? Id.printf : Id.scanf).toChars(); + if (!(f.linkage == LINK.c || f.linkage == LINK.cpp)) + { + .error(funcdecl.loc, "`pragma(%s)` function `%s` must have `extern(C)` or `extern(C++)` linkage," + ~" not `extern(%s)`", + p, funcdecl.toChars(), f.linkage.linkageToChars()); + } + if (f.parameterList.varargs == VarArg.variadic) + { + if (!(nparams >= 1 && isPointerToChar(f.parameterList[nparams - 1]))) + { + .error(funcdecl.loc, "`pragma(%s)` function `%s` must have" + ~ " signature `%s %s([parameters...], const(char)*, ...)` not `%s`", + p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars()); + } + } + else if (f.parameterList.varargs == VarArg.none) + { + if(!(nparams >= 2 && isPointerToChar(f.parameterList[nparams - 2]) && + isVa_list(f.parameterList[nparams - 1]))) + .error(funcdecl.loc, "`pragma(%s)` function `%s` must have"~ + " signature `%s %s([parameters...], const(char)*, va_list)`", + p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars()); + } + else + { + .error(funcdecl.loc, "`pragma(%s)` function `%s` must have C-style variadic `...` or `va_list` parameter", + p, funcdecl.toChars()); + } +} diff --git a/gcc/d/dmd/errors.d b/gcc/d/dmd/errors.d index 287dc4963e9..1f7a78eb6a2 100644 --- a/gcc/d/dmd/errors.d +++ b/gcc/d/dmd/errors.d @@ -119,22 +119,32 @@ else package auto previewErrorFunc(bool isDeprecated, FeatureState featureState) @safe @nogc pure nothrow { - if (featureState == FeatureState.enabled) - return &error; - else if (featureState == FeatureState.disabled || isDeprecated) - return &noop; - else - return &deprecation; + with (FeatureState) final switch (featureState) + { + case enabled: + return &error; + + case disabled: + return &noop; + + case default_: + return isDeprecated ? &noop : &deprecation; + } } package auto previewSupplementalFunc(bool isDeprecated, FeatureState featureState) @safe @nogc pure nothrow { - if (featureState == FeatureState.enabled) - return &errorSupplemental; - else if (featureState == FeatureState.disabled || isDeprecated) - return &noop; - else - return &deprecationSupplemental; + with (FeatureState) final switch (featureState) + { + case enabled: + return &errorSupplemental; + + case disabled: + return &noop; + + case default_: + return isDeprecated ? &noop : &deprecationSupplemental; + } } diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index 35f11afdc93..9477867e929 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -2468,19 +2468,13 @@ extern (C++) class ThisExp : Expression return typeof(return)(true); } - override final bool isLvalue() + override bool isLvalue() { - // Class `this` should be an rvalue; struct `this` should be an lvalue. - return type.toBasetype().ty != Tclass; + return true; } - override final Expression toLvalue(Scope* sc, Expression e) + override Expression toLvalue(Scope* sc, Expression e) { - if (type.toBasetype().ty == Tclass) - { - // Class `this` is an rvalue; struct `this` is an lvalue. - return Expression.toLvalue(sc, e); - } return this; } @@ -2500,6 +2494,18 @@ extern (C++) final class SuperExp : ThisExp super(loc, EXP.super_); } + override bool isLvalue() + { + // Class `super` should be an rvalue + return false; + } + + override Expression toLvalue(Scope* sc, Expression e) + { + // Class `super` is an rvalue + return Expression.toLvalue(sc, e); + } + override void accept(Visitor v) { v.visit(this); diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index 770c3e7ae3d..8c6393fb6e1 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -348,8 +348,8 @@ public: ThisExp *syntaxCopy() override; Optional toBool() override; - bool isLvalue() override final; - Expression *toLvalue(Scope *sc, Expression *e) override final; + bool isLvalue() override; + Expression *toLvalue(Scope *sc, Expression *e) override; void accept(Visitor *v) override { v->visit(this); } }; @@ -357,6 +357,8 @@ public: class SuperExp final : public ThisExp { public: + bool isLvalue() override; + Expression* toLvalue(Scope* sc, Expression* e) final override; void accept(Visitor *v) override { v->visit(this); } }; diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index be597dfa90f..25f755bdf0e 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -3556,7 +3556,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor */ private void tryLowerToNewItem(NewExp ne) { - if (global.params.betterC || !sc.needsCodegen()) + if (!global.params.useGC || !sc.needsCodegen()) return; auto hook = global.params.tracegc ? Id._d_newitemTTrace : Id._d_newitemT; @@ -11069,7 +11069,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor /* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be * used with `-betterC`, but only during CTFE. */ - if (global.params.betterC || !sc.needsCodegen()) + if (!global.params.useGC || !sc.needsCodegen()) return; if (auto ce = exp.isCatExp()) diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d index a714d2d281a..60457351af6 100644 --- a/gcc/d/dmd/func.d +++ b/gcc/d/dmd/func.d @@ -2019,7 +2019,8 @@ extern (C++) class FuncDeclaration : Declaration overloadApply(cast() this, (Dsymbol s) { auto f = s.isFuncDeclaration(); - if (!f) + auto td = s.isTemplateDeclaration(); + if (!f && !td) return 0; if (result) { @@ -2243,7 +2244,7 @@ extern (C++) class FuncDeclaration : Declaration if (global.gag) // need not report supplemental errors return true; } - else if (global.params.betterC) + else if (!global.params.useGC) { error("is `-betterC` yet allocates closure for `%s()` with the GC", toChars()); if (global.gag) // need not report supplemental errors @@ -4605,16 +4606,15 @@ bool setUnsafe(Scope* sc, 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) + with (FeatureState) final switch (fs) { + case disabled: return false; - } - else if (fs == FeatureState.enabled) - { + + case enabled: return sc.setUnsafe(gag, loc, msg, arg0, arg1, arg2); - } - else - { + + case default_: if (!sc.func) return false; if (sc.func.isSafeBypassingInference()) diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d index 0ac60420ef7..9071e6a58ca 100644 --- a/gcc/d/dmd/globals.d +++ b/gcc/d/dmd/globals.d @@ -81,11 +81,11 @@ enum CppStdRevision : uint } /// Trivalent boolean to represent the state of a `revert`able change -enum FeatureState : byte +enum FeatureState : ubyte { - default_ = -1, /// Not specified by the user - disabled = 0, /// Specified as `-revert=` - enabled = 1 /// Specified as `-preview=` + default_ = 0, /// Not specified by the user + disabled = 1, /// Specified as `-revert=` + enabled = 2, /// Specified as `-preview=` } extern(C++) struct Output @@ -124,6 +124,7 @@ extern (C++) struct Param bool release; // build release version bool preservePaths; // true means don't strip path from source file DiagnosticReporting warnings = DiagnosticReporting.off; // how compiler warnings are handled + bool obsolete; // enable warnings about use of obsolete messages bool color; // use ANSI colors in console output bool cov; // generate code coverage data ubyte covPercent; // 0..100 code coverage percentage required @@ -132,6 +133,7 @@ extern (C++) struct Param bool useModuleInfo = true; // generate runtime module information bool useTypeInfo = true; // generate runtime type information bool useExceptions = true; // support exception handling + bool useGC = true; // support features that require the GC bool betterC; // be a "better C" compiler; no dependency on D runtime bool addMain; // add a default main() function bool allInst; // generate code for all template instantiations diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h index 66345acc88b..0dad5dd12e7 100644 --- a/gcc/d/dmd/globals.h +++ b/gcc/d/dmd/globals.h @@ -75,11 +75,11 @@ enum CppStdRevision }; /// Trivalent boolean to represent the state of a `revert`able change -enum class FeatureState : signed char +enum class FeatureState : unsigned char { - default_ = -1, /// Not specified by the user - disabled = 0, /// Specified as `-revert=` - enabled = 1 /// Specified as `-preview=` + default_ = 0, /// Not specified by the user + disabled = 1, /// Specified as `-revert=` + enabled = 2, /// Specified as `-preview=` }; struct Output @@ -119,6 +119,7 @@ struct Param d_bool release; // build release version d_bool preservePaths; // true means don't strip path from source file Diagnostic warnings; + d_bool obsolete; // warn about use of obsolete features d_bool color; // use ANSI colors in console output d_bool cov; // generate code coverage data unsigned char covPercent; // 0..100 code coverage percentage required @@ -127,6 +128,7 @@ struct Param d_bool useModuleInfo; // generate runtime module information d_bool useTypeInfo; // generate runtime type information d_bool useExceptions; // support exception handling + d_bool useGC; // support features that require the GC d_bool betterC; // be a "better C" compiler; no dependency on D runtime d_bool addMain; // add a default main() function d_bool allInst; // generate code for all template instantiations @@ -263,6 +265,7 @@ struct CompileEnv bool previewIn; bool ddocOutput; bool shortenedMethods; + bool obsolete; }; struct Global diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d index ee288d1e474..c60b4311ff5 100644 --- a/gcc/d/dmd/initsem.d +++ b/gcc/d/dmd/initsem.d @@ -772,10 +772,13 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ const nfields = sd.fields.length; size_t fieldi = 0; + Loop1: for (size_t index = 0; index < ci.initializerList.length; ) { - auto di = ci.initializerList[index]; - auto dlist = di.designatorList; + CInitializer cprev; + L1: + DesigInit di = ci.initializerList[index]; + Designators* dlist = di.designatorList; if (dlist) { const length = (*dlist).length; @@ -798,9 +801,19 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ si.addInit(id, di.initializer); ++fieldi; ++index; - break; + continue Loop1; } } + if (cprev) + { + /* The peeling didn't work, so unpeel it + */ + ci = cprev; + di = ci.initializerList[index]; + goto L2; + } + error(ci.loc, "`.%s` is not a field of `%s`\n", id.toChars(), sd.toChars()); + return err(); } else { @@ -808,10 +821,14 @@ extern(C++) Initializer initializerSemantic(Initializer init, Scope* sc, ref Typ break; if (index == 0 && ci.initializerList.length == 1 && di.initializer.isCInitializer()) { + /* Try peeling off this set of { } and see if it works + */ + cprev = ci; ci = di.initializer.isCInitializer(); - continue; + goto L1; } + L2: VarDeclaration field; while (1) // skip field if it overlaps with previously seen fields { diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index add1ce68468..9cce7c56723 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -51,6 +51,7 @@ struct CompileEnv bool previewIn; /// `in` means `[ref] scope const`, accepts rvalues bool ddocOutput; /// collect embedded documentation comments bool shortenedMethods = true; /// allow => in normal function declarations + bool obsolete; /// warn on use of legacy code } /*********************************************************** diff --git a/gcc/d/dmd/nogc.d b/gcc/d/dmd/nogc.d index 9a8f2422746..d7a28209b3e 100644 --- a/gcc/d/dmd/nogc.d +++ b/gcc/d/dmd/nogc.d @@ -219,7 +219,7 @@ Expression checkGC(Scope* sc, Expression e) * Just don't generate code for it. * Detect non-CTFE use of the GC in betterC code. */ - const betterC = global.params.betterC; + const betterC = !global.params.useGC; FuncDeclaration f = sc.func; if (e && e.op != EXP.error && f && sc.intypeof != 1 && (!(sc.flags & SCOPE.ctfe) || betterC) && diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d index eeaef8d7d8b..d15e448150f 100644 --- a/gcc/d/dmd/parse.d +++ b/gcc/d/dmd/parse.d @@ -718,13 +718,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer tk.value == TOK.out_ || tk.value == TOK.do_ || tk.value == TOK.goesTo || tk.value == TOK.identifier && tk.ident == Id._body)) { - // @@@DEPRECATED_2.117@@@ - // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md - // Deprecated in 2.097 - Can be removed from 2.117 - // The deprecation period is longer than usual as `body` - // was quite widely used. if (tk.value == TOK.identifier && tk.ident == Id._body) - deprecation("usage of the `body` keyword is deprecated. Use `do` instead."); + usageOfBodyKeyword(); a = parseDeclarations(true, pAttrs, pAttrs.comment); if (a && a.length) @@ -1163,7 +1158,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer a = parseDeclDefs(0, pLastDecl); if (token.value != TOK.rightCurly) { - /* { */ + /* left curly brace */ error("matching `}` expected, not `%s`", token.toChars()); eSink.errorSupplemental(lcLoc, "unmatched `{`"); } @@ -1505,7 +1500,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer if (token.value != TOK.leftCurly) { - error("`{` expected after template parameter list, not `%s`", token.toChars()); + error("`{` expected after template parameter list, not `%s`", token.toChars()); /* } */ goto Lerr; } decldefs = parseBlock(null); @@ -2724,7 +2719,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer nextToken(); - const(char)* begPtr = token.ptr + 1; // skip '{' + const(char)* begPtr = token.ptr + 1; // skip left curly brace const(char)* endPtr = null; AST.Statement sbody = parseStatement(ParseStatementFlags.curly, &endPtr); @@ -3041,6 +3036,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } e = new AST.EnumDeclaration(loc, id, memtype); + // opaque type if (token.value == TOK.semicolon && id) nextToken(); else if (token.value == TOK.leftCurly) @@ -3073,7 +3069,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer && token.value != TOK.comma && token.value != TOK.assign) { - switch(token.value) + switch (token.value) { case TOK.at: if (StorageClass _stc = parseAttribute(udas)) @@ -3109,12 +3105,23 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } else { - goto default; + if (isAnonymousEnum) + goto default; // maybe `Type identifier` + + prevTOK = token.value; + nextToken(); + error("expected `,` or `=` after identifier, not `%s`", token.toChars()); } break; default: if (isAnonymousEnum) { + if (type) + { + error("expected identifier after type, not `%s`", token.toChars()); + type = null; + break; + } type = parseType(&ident, null); if (type == AST.Type.terror) { @@ -3125,6 +3132,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer else { prevTOK = TOK.identifier; + const tv = token.value; + if (ident && tv != TOK.assign && tv != TOK.comma && tv != TOK.rightCurly) + { + error("expected `,` or `=` after identifier, not `%s`", token.toChars()); + } } } else @@ -3166,7 +3178,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer { value = null; if (type && type != AST.Type.terror && isAnonymousEnum) - error("if type, there must be an initializer"); + error("initializer required after `%s` when type is specified", ident.toChars()); } AST.DeprecatedDeclaration dd; @@ -3471,6 +3483,11 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer return decldefs; } + /* Parse a type and optional identifier + * Params: + * pident = set to Identifier if there is one, null if not + * ptpl = if !null, then set to TemplateParameterList + */ AST.Type parseType(Identifier* pident = null, AST.TemplateParameters** ptpl = null) { /* Take care of the storage class prefixes that @@ -4450,13 +4467,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer (tk.value == TOK.leftParenthesis || tk.value == TOK.leftCurly || tk.value == TOK.in_ || tk.value == TOK.out_ || tk.value == TOK.goesTo || tk.value == TOK.do_ || tk.value == TOK.identifier && tk.ident == Id._body)) { - // @@@DEPRECATED_2.117@@@ - // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md - // Deprecated in 2.097 - Can be removed from 2.117 - // The deprecation period is longer than usual as `body` - // was quite widely used. if (tk.value == TOK.identifier && tk.ident == Id._body) - deprecation("usage of the `body` keyword is deprecated. Use `do` instead."); + usageOfBodyKeyword(); ts = null; } @@ -4569,6 +4581,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer } else if (t.ty == Tfunction) { + if (storage_class & STC.manifest) + error("function cannot have enum storage class"); + AST.Expression constraint = null; //printf("%s funcdecl t = %s, storage_class = x%lx\n", loc.toChars(), t.toChars(), storage_class); auto f = new AST.FuncDeclaration(loc, Loc.initial, ident, storage_class | (disable ? STC.disable : 0), t); @@ -5193,12 +5208,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer case TOK.identifier: if (token.ident == Id._body) { - // @@@DEPRECATED_2.117@@@ - // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md - // Deprecated in 2.097 - Can be removed from 2.117 - // The deprecation period is longer than usual as `body` - // was quite widely used. - deprecation("usage of the `body` keyword is deprecated. Use `do` instead."); + usageOfBodyKeyword(); goto case TOK.do_; } goto default; @@ -6027,7 +6037,7 @@ LagainStc: auto statements = new AST.Statements(); while (token.value != TOK.rightCurly && token.value != TOK.endOfFile) { - statements.push(parseStatement(ParseStatementFlags.curlyScope)); + statements.push(parseStatement(ParseStatementFlags.curlyScope | ParseStatementFlags.semiOk)); } if (endPtr) *endPtr = token.ptr; @@ -7572,12 +7582,7 @@ LagainStc: case TOK.identifier: if (t.ident == Id._body) { - // @@@DEPRECATED_2.117@@@ - // https://github.com/dlang/DIPs/blob/1f5959abe482b1f9094f6484a7d0a3ade77fc2fc/DIPs/accepted/DIP1003.md - // Deprecated in 2.097 - Can be removed from 2.117 - // The deprecation period is longer than usual as `body` - // was quite widely used. - deprecation("usage of the `body` keyword is deprecated. Use `do` instead."); + usageOfBodyKeyword(); goto case TOK.do_; } goto default; @@ -8806,6 +8811,7 @@ LagainStc: { // (type) una_exp nextToken(); + // Note: `t` may be an expression that looks like a type auto t = parseType(); check(TOK.rightParenthesis); @@ -8823,6 +8829,16 @@ LagainStc: te.parens = true; e = parsePostExp(te); } + else if (token.value == TOK.leftParenthesis || + token.value == TOK.plusPlus || token.value == TOK.minusMinus) + { + // (type)(expr) + // (callable)(args) + // (expr)++ + auto te = new AST.TypeExp(loc, t); + te.parens = true; + e = parsePostExp(te); + } else { e = parseUnaryExp(); @@ -9526,6 +9542,14 @@ LagainStc: STC.live | /*STC.future |*/ // probably should be included STC.disable; + + void usageOfBodyKeyword() + { + if (compileEnv.obsolete) + { + eSink.warning(token.loc, "usage of identifer `body` as a keyword is obsolete. Use `do` instead."); + } + } } enum PREC : int diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d index e4ca22a98b5..c7d12194820 100644 --- a/gcc/d/dmd/semantic3.d +++ b/gcc/d/dmd/semantic3.d @@ -1422,7 +1422,8 @@ private extern(C++) final class Semantic3Visitor : Visitor * https://issues.dlang.org/show_bug.cgi?id=14246 */ AggregateDeclaration ad = ctor.isMemberDecl(); - if (!ctor.fbody || !ad || !ad.fieldDtor || !global.params.dtorFields || !global.params.useExceptions || ctor.type.toTypeFunction.isnothrow) + if (!ctor.fbody || !ad || !ad.fieldDtor || + global.params.dtorFields == FeatureState.disabled || !global.params.useExceptions || ctor.type.toTypeFunction.isnothrow) return visit(cast(FuncDeclaration)ctor); /* Generate: diff --git a/gcc/d/dmd/target.d b/gcc/d/dmd/target.d index fddfd546742..81ff84f361e 100644 --- a/gcc/d/dmd/target.d +++ b/gcc/d/dmd/target.d @@ -25,7 +25,7 @@ module dmd.target; -import dmd.globals : Param; +import dmd.globals : Param, CHECKENABLE; enum CPU : ubyte { @@ -111,7 +111,7 @@ extern (C++) struct Target /// Architecture name const(char)[] architectureName; CPU cpu = CPU.baseline; // CPU instruction set to target - bool is64bit; // generate 64 bit code for x86_64; true by default for 64 bit dmd + bool isX86_64; // generate 64 bit code for x86_64; true by default for 64 bit dmd bool isLP64; // pointers are 64 bits // Environmental diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h index 561afa18d42..ca0e09c88e0 100644 --- a/gcc/d/dmd/target.h +++ b/gcc/d/dmd/target.h @@ -156,7 +156,7 @@ struct Target DString architectureName; // name of the platform architecture (e.g. X86_64) CPU cpu; // CPU instruction set to target - d_bool is64bit; // generate 64 bit code for x86_64; true by default for 64 bit dmd + d_bool isX86_64; // generate 64 bit code for x86_64; true by default for 64 bit dmd d_bool isLP64; // pointers are 64 bits // Environmental diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d index caebf1cee25..0d9c95ff173 100644 --- a/gcc/d/dmd/traits.d +++ b/gcc/d/dmd/traits.d @@ -947,15 +947,24 @@ Expression semanticTraits(TraitsExp e, Scope* sc) */ Dsymbol sym = getDsymbol(o); + + if (sym && e.ident == Id.hasMember) + { + if (auto sm = sym.search(e.loc, id)) + return True(); + + // https://issues.dlang.org/show_bug.cgi?id=23951 + if (auto decl = sym.isDeclaration()) + { + ex = typeDotIdExp(e.loc, decl.type, id); + goto doSemantic; + } + } + if (auto t = isType(o)) ex = typeDotIdExp(e.loc, t, id); else if (sym) { - if (e.ident == Id.hasMember) - { - if (auto sm = sym.search(e.loc, id)) - return True(); - } ex = new DsymbolExp(e.loc, sym); ex = new DotIdExp(e.loc, ex, id); } @@ -966,7 +975,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) e.error("invalid first argument"); return ErrorExp.get(); } - + doSemantic: // ignore symbol visibility and disable access checks for these traits Scope* scx = sc.push(); scx.flags |= SCOPE.ignoresymbolvisibility | SCOPE.noaccesscheck; @@ -1223,7 +1232,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) // @@@DEPRECATION 2.100.2 if (auto td = s.isTemplateDeclaration()) { - if (td.overnext || td.funcroot) + if (td.overnext || td.overroot) { deprecation(e.loc, "`__traits(getAttributes)` may only be used for individual functions, not the overload set `%s`", td.ident.toChars()); deprecationSupplemental(e.loc, "the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from"); diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 8fb1eea65a6..7038655bc94 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -695,7 +695,7 @@ public: { /* This error is only emitted during the code generation pass because concatentation is allowed in CTFE. */ - if (global.params.betterC) + if (!global.params.useGC) { error_at (make_location_t (e->loc), "array concatenation of expression %qs requires the GC and " diff --git a/gcc/testsuite/gdc.test/compilable/cppmangle.d b/gcc/testsuite/gdc.test/compilable/cppmangle.d index fc74c944cad..264b374dd55 100644 --- a/gcc/testsuite/gdc.test/compilable/cppmangle.d +++ b/gcc/testsuite/gdc.test/compilable/cppmangle.d @@ -528,7 +528,6 @@ version (CppMangle_Itanium) static assert(basic_ostream!(char, char_traits!char).food.mangleof == "_ZNSo4foodEv"); static assert(basic_iostream!(char, char_traits!char).fooe.mangleof == "_ZNSd4fooeEv"); - static assert(func_18957_2.mangleof == `_Z12func_18957_2PSaIiE`); static assert(func_18957_2!(allocator!int).mangleof == `_Z12func_18957_2ISaIiEET_PS1_`); static assert(func_20413.mangleof == `_Z10func_20413St4pairIifES_IfiE`); diff --git a/gcc/testsuite/gdc.test/compilable/deprecate14283.d b/gcc/testsuite/gdc.test/compilable/deprecate14283.d index e91db649cee..fc51cf3f0b6 100644 --- a/gcc/testsuite/gdc.test/compilable/deprecate14283.d +++ b/gcc/testsuite/gdc.test/compilable/deprecate14283.d @@ -1,12 +1,12 @@ -// REQUIRED_ARGS: -dw +// REQUIRED_ARGS: // PERMUTE_ARGS: class C { void bug() { - autoref(this); // 'auto ref' becomes non-ref parameter - autoref(super); // 'auto ref' becomes non-ref parameter + autoref!(true, C)(this); // 'auto ref' becomes ref parameter + autoref!(false, Object)(super); // 'auto ref' becomes non-ref parameter } } -void autoref(T)(auto ref T t) { static assert(__traits(isRef, t) == false); } +void autoref(bool result, T)(auto ref T t) { static assert(__traits(isRef, t) == result); } diff --git a/gcc/testsuite/gdc.test/compilable/emptystatement.d b/gcc/testsuite/gdc.test/compilable/emptystatement.d new file mode 100644 index 00000000000..e6bfc27caa4 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/emptystatement.d @@ -0,0 +1,19 @@ +/* +REQUIRED_ARGS: +TEST_OUTPUT: +--- +--- +*/ + +void foo() +{ + int x;; + enum A + { + a, + b, + c + }; + + void bar() {}; +} diff --git a/gcc/testsuite/gdc.test/compilable/imports/imp24022.c b/gcc/testsuite/gdc.test/compilable/imports/imp24022.c new file mode 100644 index 00000000000..b65e4e155bf --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/imp24022.c @@ -0,0 +1,5 @@ +// https://issues.dlang.org/show_bug.cgi?id=24022 +typedef enum { + A = 1, + B, +} E; diff --git a/gcc/testsuite/gdc.test/compilable/parens_inc.d b/gcc/testsuite/gdc.test/compilable/parens_inc.d new file mode 100644 index 00000000000..b9d11eb9b8e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/parens_inc.d @@ -0,0 +1,23 @@ +// Test UnaryExp (expr)++ parsing + +void main(){ + int[2] y; + int *x = y.ptr; + *(x)++=0; + (*(x)--)=0; + (*x++)=0; // ok + int*[] z; + *(z[0])++=0; //ok + (y[0])--; + *x++=0; +} + +void f() +{ + int b; + (b)++; + int[] a; + b = (a)[0]++; //ok + (a[0])--; + b = (int).init; //ok +} diff --git a/gcc/testsuite/gdc.test/compilable/test23951.d b/gcc/testsuite/gdc.test/compilable/test23951.d new file mode 100644 index 00000000000..e09a3d7b5d1 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23951.d @@ -0,0 +1,10 @@ +// https://issues.dlang.org/show_bug.cgi?id=23951 + +struct S { int x; } +struct T { S a; alias a this; } +struct U { T t; } +static assert(__traits(hasMember, T, "x")); +static assert(__traits(hasMember, T.init, "x")); +static assert(__traits(hasMember, U.init.t, "x")); +static assert(__traits(hasMember, U.t, "a")); +static assert(__traits(hasMember, U.t, "x")); diff --git a/gcc/testsuite/gdc.test/compilable/test23966.d b/gcc/testsuite/gdc.test/compilable/test23966.d new file mode 100644 index 00000000000..71aa8ca229e --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test23966.d @@ -0,0 +1,19 @@ +// https://issues.dlang.org/show_bug.cgi?id=23966 +module test23966; + +@("gigi") +void fun() {} +@("mimi") +void fun(int) {} +@("hihi") +void fun(int, int) {} +@("bibi") +void fun()(int, ulong) {} + +void main() +{ + static foreach (t; __traits(getOverloads, test23966, "fun", true)) + static foreach(attr; __traits(getAttributes, t)) + {} + +} diff --git a/gcc/testsuite/gdc.test/compilable/test24022.d b/gcc/testsuite/gdc.test/compilable/test24022.d new file mode 100644 index 00000000000..f499636f126 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test24022.d @@ -0,0 +1,30 @@ +// https://issues.dlang.org/show_bug.cgi?id=24022 +// EXTRA_FILES: imports/imp24022.c +import imports.imp24022; + +auto some_d_func(E v) { + return v; +} + +auto some_d_other_func() { + const struct R { + E r; + this(in E vparam) { r = vparam; } + } + return R(A); +} + +void main(string[] args) { + E expected = E.A; + E res = some_d_func(A); + assert (res == A); + assert (res == expected); + + res = some_d_func(E.B); + assert (res == B); + assert (res == E.B); + + auto res2 = some_d_other_func(); + assert (res2.r == A); + assert (res2.r == expected); +} diff --git a/gcc/testsuite/gdc.test/compilable/test7172.d b/gcc/testsuite/gdc.test/compilable/test7172.d index 013630bd483..49142d78988 100644 --- a/gcc/testsuite/gdc.test/compilable/test7172.d +++ b/gcc/testsuite/gdc.test/compilable/test7172.d @@ -1,8 +1,4 @@ -/* TEST_OUTPUT: ---- -compilable/test7172.d(14): Deprecation: `scope` as a type constraint is deprecated. Use `scope` at the usage site. ---- -*/ + void main() { abstract class AbstractC{} diff --git a/gcc/testsuite/gdc.test/fail_compilation/biterrors3.d b/gcc/testsuite/gdc.test/fail_compilation/biterrors3.d index f9e1df2b7b2..c5031a4db10 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/biterrors3.d +++ b/gcc/testsuite/gdc.test/fail_compilation/biterrors3.d @@ -2,7 +2,7 @@ * TEST_OUTPUT: --- fail_compilation/biterrors3.d(103): Error: storage class not allowed for bit-field declaration -fail_compilation/biterrors3.d(106): Error: `d` is not a valid attribute for enum members +fail_compilation/biterrors3.d(106): Error: expected `,` or `=` after identifier, not `:` fail_compilation/biterrors3.d(106): Error: `:` is not a valid attribute for enum members fail_compilation/biterrors3.d(106): Error: `3` is not a valid attribute for enum members --- diff --git a/gcc/testsuite/gdc.test/fail_compilation/body.d b/gcc/testsuite/gdc.test/fail_compilation/body.d new file mode 100644 index 00000000000..7b718c25060 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/body.d @@ -0,0 +1,11 @@ +/* REQUIRED_ARGS: -wo -w +TEST_OUTPUT: +--- +fail_compilation/body.d(11): Warning: usage of identifer `body` as a keyword is obsolete. Use `do` instead. +Error: warnings are treated as errors + Use -wi if you wish to treat warnings only as informational. +--- +*/ + +void test() +in { } body { } diff --git a/gcc/testsuite/gdc.test/fail_compilation/ccast.d b/gcc/testsuite/gdc.test/fail_compilation/ccast.d index dab29844158..f1ca6c0fada 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ccast.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ccast.d @@ -1,9 +1,28 @@ /* TEST_OUTPUT: --- -fail_compilation/ccast.d(9): Error: C style cast illegal, use `cast(byte)i` +fail_compilation/ccast.d(11): Error: C style cast illegal, use `cast(byte)i` +fail_compilation/ccast.d(24): Error: C style cast illegal, use `cast(foo)5` +fail_compilation/ccast.d(26): Error: C style cast illegal, use `cast(void*)5` --- */ int i; byte b = (byte)i; + +void bar(int x); + +void main() +{ + (&bar)(5); // ok + auto foo = &bar; + (foo = foo)(5); // ok + (*foo)(5); // ok + + (foo)(5); // ok + (bar)(5); // ok + (foo)5; + + (void*)5; + (void*)(5); // semantic implicit cast error +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag4596.d b/gcc/testsuite/gdc.test/fail_compilation/diag4596.d index f6b49d6bd13..517b328e8d6 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag4596.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag4596.d @@ -1,13 +1,13 @@ /* TEST_OUTPUT: --- -fail_compilation/diag4596.d(15): Error: `this` is not an lvalue and cannot be modified -fail_compilation/diag4596.d(16): Error: conditional expression `1 ? this : this` is not a modifiable lvalue fail_compilation/diag4596.d(18): Error: `super` is not an lvalue and cannot be modified fail_compilation/diag4596.d(19): Error: conditional expression `1 ? super : super` is not a modifiable lvalue --- */ + + class NoGo4596 { void fun() diff --git a/gcc/testsuite/gdc.test/fail_compilation/enum_function.d b/gcc/testsuite/gdc.test/fail_compilation/enum_function.d new file mode 100644 index 00000000000..b22f2ceccef --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/enum_function.d @@ -0,0 +1,13 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/enum_function.d(10): Error: function cannot have enum storage class +fail_compilation/enum_function.d(11): Error: function cannot have enum storage class +fail_compilation/enum_function.d(12): Error: function cannot have enum storage class +fail_compilation/enum_function.d(13): Error: function cannot have enum storage class +--- +*/ +enum void f1() { return; } +enum f2() { return 5; } +enum f3() => 5; +enum int f4()() => 5; diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10285.d b/gcc/testsuite/gdc.test/fail_compilation/fail10285.d index 3277b19e2aa..c88e30688f7 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail10285.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail10285.d @@ -1,10 +1,18 @@ /* TEST_OUTPUT: --- -fail_compilation/fail10285.d(9): Error: no identifier for declarator `int` +fail_compilation/fail10285.d(13): Error: no identifier for declarator `int` +fail_compilation/fail10285.d(14): Error: expected `,` or `=` after identifier, not `y` +fail_compilation/fail10285.d(15): Error: expected identifier after type, not `bool` +fail_compilation/fail10285.d(16): Error: expected identifier after type, not `int` +fail_compilation/fail10285.d(18): Error: initializer required after `z` when type is specified --- */ enum { - int = 5 + int = 5, + int x y, + int bool i = 3, + j int k = 3, + int z } diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13116.d b/gcc/testsuite/gdc.test/fail_compilation/fail13116.d index ac520d79997..077fa75ac77 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail13116.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail13116.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail13116.d(14): Error: `this` is not an lvalue and cannot be modified +fail_compilation/fail13116.d(14): Error: returning `this` escapes a reference to parameter `this` fail_compilation/fail13116.d(23): Error: `super` is not an lvalue and cannot be modified --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail15896.d b/gcc/testsuite/gdc.test/fail_compilation/fail15896.d index e52503d0975..3fdbf4e9f98 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail15896.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail15896.d @@ -14,5 +14,6 @@ int func() { thebar +=1; packagebar += 1; + thebar +=1; return 0; } diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22729.d b/gcc/testsuite/gdc.test/fail_compilation/fail22729.d index 38bbfeeed2b..d0c8aa9c2f3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail22729.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22729.d @@ -22,7 +22,7 @@ class Form : WidgetI template Tuple(Specs) { - enum areCompatibleTuples(Tup2)(Tuple tup1, Tup2 tup2) + auto areCompatibleTuples(Tup2)(Tuple tup1, Tup2 tup2) { tup1.field == tup2; } diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22780.d b/gcc/testsuite/gdc.test/fail_compilation/fail22780.d index e22be9fe047..8d4c8a891f0 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail22780.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22780.d @@ -1,10 +1,10 @@ // https://issues.dlang.org/show_bug.cgi?id=22780 /* TEST_OUTPUT: --- -fail_compilation/fail22780.d(8): Deprecation: `scope` as a type constraint is deprecated. Use `scope` at the usage site. fail_compilation/fail22780.d(12): Error: variable `fail22780.test10717.c` reference to `scope class` must be `scope` --- */ + scope class C10717 { } void test10717() diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail4559.d b/gcc/testsuite/gdc.test/fail_compilation/fail4559.d deleted file mode 100644 index 657c184d787..00000000000 --- a/gcc/testsuite/gdc.test/fail_compilation/fail4559.d +++ /dev/null @@ -1,22 +0,0 @@ -/* -REQUIRED_ARGS: -TEST_OUTPUT: ---- -fail_compilation/fail4559.d(13): Error: use `{ }` for an empty statement, not `;` -fail_compilation/fail4559.d(19): Error: use `{ }` for an empty statement, not `;` -fail_compilation/fail4559.d(21): Error: use `{ }` for an empty statement, not `;` ---- -*/ - -void foo() -{ - int x;; - enum A - { - a, - b, - c - }; - - void bar() {}; -} diff --git a/gcc/testsuite/gdc.test/fail_compilation/format.d b/gcc/testsuite/gdc.test/fail_compilation/format.d index bc40d9a527a..cfd30bfc82e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/format.d +++ b/gcc/testsuite/gdc.test/fail_compilation/format.d @@ -1,10 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/format.d(101): Error: function `format.printf1` `pragma(printf)` functions must be `extern(C) void printf1([parameters...], const(char)*, ...)` not `void(const(char)*, ...)` -fail_compilation/format.d(102): Error: function `format.printf2` `pragma(printf)` functions must be `extern(C) int printf2([parameters...], const(char)*, ...)` not `extern (C) int(const(int)*, ...)` -fail_compilation/format.d(103): Error: function `format.printf3` `pragma(printf)` functions must be `extern(C) int printf3([parameters...], const(char)*, va_list)` -fail_compilation/format.d(104): Error: function `format.printf4` `pragma(printf)` functions must be `extern(C) int printf4([parameters...], const(char)*, ...)` not `extern (C) int(const(char)*, int, ...)` +fail_compilation/format.d(101): Error: `pragma(printf)` function `printf1` must have `extern(C)` or `extern(C++)` linkage, not `extern(D)` +fail_compilation/format.d(102): Error: `pragma(printf)` function `printf2` must have signature `int printf2([parameters...], const(char)*, ...)` not `extern (C) int(const(int)*, ...)` +fail_compilation/format.d(103): Error: `pragma(printf)` function `printf3` must have signature `int printf3([parameters...], const(char)*, va_list)` +fail_compilation/format.d(104): Error: `pragma(printf)` function `printf4` must have signature `int printf4([parameters...], const(char)*, ...)` not `extern (C) int(const(char)*, int, ...)` --- */ @@ -22,10 +22,13 @@ pragma(printf) extern (C) int printf7(char*, ...); /* TEST_OUTPUT: --- -fail_compilation/format.d(203): Error: function `format.vprintf1` `pragma(printf)` functions must be `extern(C) void vprintf1([parameters...], const(char)*, va_list)` -fail_compilation/format.d(204): Error: function `format.vprintf2` `pragma(printf)` functions must be `extern(C) int vprintf2([parameters...], const(char)*, va_list)` -fail_compilation/format.d(205): Error: function `format.vprintf3` `pragma(printf)` functions must be `extern(C) int vprintf3([parameters...], const(char)*, va_list)` -fail_compilation/format.d(206): Error: function `format.vprintf4` `pragma(printf)` functions must be `extern(C) int vprintf4([parameters...], const(char)*, va_list)` +fail_compilation/format.d(203): Error: `pragma(printf)` function `vprintf1` must have `extern(C)` or `extern(C++)` linkage, not `extern(D)` +fail_compilation/format.d(204): Error: `pragma(printf)` function `vprintf2` must have signature `int vprintf2([parameters...], const(char)*, va_list)` +fail_compilation/format.d(205): Error: `pragma(printf)` function `vprintf3` must have signature `int vprintf3([parameters...], const(char)*, va_list)` +fail_compilation/format.d(206): Error: `pragma(printf)` function `vprintf4` must have signature `int vprintf4([parameters...], const(char)*, va_list)` +fail_compilation/format.d(207): Error: `pragma(printf)` function `vprintf5` must have C-style variadic `...` or `va_list` parameter +fail_compilation/format.d(208): Error: `pragma(scanf)` function `vscanf1` must have `extern(C)` or `extern(C++)` linkage, not `extern(Windows)` +fail_compilation/format.d(208): Error: `pragma(scanf)` function `vscanf1` must have signature `int vscanf1([parameters...], const(char)*, va_list)` --- */ @@ -37,6 +40,8 @@ pragma(printf) void vprintf1(const(char)*, va_list); pragma(printf) extern (C) int vprintf2(const(int )*, va_list); pragma(printf) extern (C) int vprintf3(const(char)*); pragma(printf) extern (C) int vprintf4(const(char)*, int, va_list); +pragma(printf) extern (C) int vprintf5(char*, int[] a...); +pragma(scanf) extern (Windows) int vscanf1(); pragma(printf) extern (C) int vprintf5(const(char)*, va_list); pragma(printf) extern (C) int vprintf6(immutable(char)*, va_list); diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d index 29f96ece787..f7a554ce729 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d +++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d @@ -118,6 +118,7 @@ fail_compilation/reserved_version.d(219): Error: version identifier `D_PostCondi 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 +fail_compilation/reserved_version.d(223): Error: version identifier `VisionOS` is reserved and cannot be set --- */ @@ -242,6 +243,7 @@ version = D_PostConditions; version = D_ProfileGC; version = D_Invariants; version = D_Optimized; +version = VisionOS; // This should work though debug = DigitalMars; diff --git a/gcc/testsuite/gdc.test/fail_compilation/scope_class.d b/gcc/testsuite/gdc.test/fail_compilation/scope_class.d index bba14908833..b5e1a54d71b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/scope_class.d +++ b/gcc/testsuite/gdc.test/fail_compilation/scope_class.d @@ -1,12 +1,12 @@ /* TEST_OUTPUT: --- -fail_compilation/scope_class.d(10): Deprecation: `scope` as a type constraint is deprecated. Use `scope` at the usage site. fail_compilation/scope_class.d(12): Error: functions cannot return `scope scope_class.C` --- */ + scope class C { int i; } // Notice the use of `scope` here C increment(C c) diff --git a/gcc/testsuite/gdc.test/fail_compilation/scope_type.d b/gcc/testsuite/gdc.test/fail_compilation/scope_type.d deleted file mode 100644 index e0550138b7e..00000000000 --- a/gcc/testsuite/gdc.test/fail_compilation/scope_type.d +++ /dev/null @@ -1,16 +0,0 @@ -/* -REQUIRED_ARGS: -de -TEST_OUTPUT: ---- -fail_compilation/scope_type.d(13): Deprecation: `scope` as a type constraint is deprecated. Use `scope` at the usage site. -fail_compilation/scope_type.d(14): Error: `scope` as a type constraint is obsolete. Use `scope` at the usage site. -fail_compilation/scope_type.d(15): Deprecation: `scope` as a type constraint is deprecated. Use `scope` at the usage site. -fail_compilation/scope_type.d(16): Deprecation: `scope` as a type constraint is deprecated. Use `scope` at the usage site. ---- -*/ - - -scope class C { } -scope interface I { } -scope struct S { } -scope enum E { e } diff --git a/gcc/testsuite/gdc.test/fail_compilation/test23279.d b/gcc/testsuite/gdc.test/fail_compilation/test23279.d new file mode 100644 index 00000000000..43f2d44a071 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test23279.d @@ -0,0 +1,14 @@ +// https://issues.dlang.org/show_bug.cgi?id=23279 + +/* +TEST_OUTPUT: +--- +fail_compilation/test23279.d(13): Error: undefined identifier `Sth` +--- +*/ + +class Tester +{ + enum a = __traits(hasMember, Tester, "setIt"); + void setIt(Sth sth){} +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d b/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d index 404a4c0e3fe..4c8576c88d9 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d +++ b/gcc/testsuite/gdc.test/fail_compilation/typeerrors.d @@ -1,7 +1,6 @@ /* TEST_OUTPUT: --- -fail_compilation/typeerrors.d(32): Deprecation: `scope` as a type constraint is deprecated. Use `scope` at the usage site. fail_compilation/typeerrors.d(37): Error: sequence index `4` out of bounds `[0 .. 4]` fail_compilation/typeerrors.d(39): Error: variable `x` cannot be read at compile time fail_compilation/typeerrors.d(40): Error: cannot have array of `void()` @@ -25,6 +24,7 @@ fail_compilation/typeerrors.d(57): Error: slice `[2..1]` is out of range of [0.. + template tuple(T...) { alias T tuple; } void bar(); diff --git a/gcc/testsuite/gdc.test/runnable/betterc.d b/gcc/testsuite/gdc.test/runnable/betterc.d index 3d8f7da0fcc..0fc32c75a1f 100644 --- a/gcc/testsuite/gdc.test/runnable/betterc.d +++ b/gcc/testsuite/gdc.test/runnable/betterc.d @@ -210,3 +210,14 @@ int test20737() tlsVar = 123; return 0; } + +/*******************************************/ +// https://issues.dlang.org/show_bug.cgi?id=22427 +void test22427() +{ + if("a" == "a") + return; + + char[] p; + auto a = cast(int[])p; +} diff --git a/gcc/testsuite/gdc.test/runnable/sctor2.d b/gcc/testsuite/gdc.test/runnable/sctor2.d index bd820e498f4..a574c3e55f5 100644 --- a/gcc/testsuite/gdc.test/runnable/sctor2.d +++ b/gcc/testsuite/gdc.test/runnable/sctor2.d @@ -1,10 +1,5 @@ // REQUIRED_ARGS: -w -dw // PERMUTE_ARGS: -/* TEST_OUTPUT: ---- -runnable/sctor2.d(12): Deprecation: `scope` as a type constraint is deprecated. Use `scope` at the usage site. ---- -*/ /***************************************************/ // 15665 diff --git a/gcc/testsuite/gdc.test/runnable/test24029.c b/gcc/testsuite/gdc.test/runnable/test24029.c new file mode 100644 index 00000000000..145f2c28725 --- /dev/null +++ b/gcc/testsuite/gdc.test/runnable/test24029.c @@ -0,0 +1,23 @@ +// https://issues.dlang.org/show_bug.cgi?id=24029 + +int x = 0; +int y = 0; + +void a() +{ + (__extension__ ({ x += 2; })); // test.a.__dgliteral1 +} + +void b() +{ + (__extension__ ({ y += 1; })); // test.b.__dgliteral1 +} + +int main(void) +{ + a(); + b(); + __check(x == 2); + __check(y == 1); + return 0; +} diff --git a/gcc/testsuite/gdc.test/runnable/testcontracts.d b/gcc/testsuite/gdc.test/runnable/testcontracts.d index 439040b7b38..63d18fcc627 100644 --- a/gcc/testsuite/gdc.test/runnable/testcontracts.d +++ b/gcc/testsuite/gdc.test/runnable/testcontracts.d @@ -1,20 +1,4 @@ /* PERMUTE_ARGS: -inline -g -O -TEST_OUTPUT: ---- -runnable/testcontracts.d(323): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(324): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(325): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(326): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(328): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(329): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(330): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(331): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(502): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(503): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(504): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(505): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. -runnable/testcontracts.d(505): Deprecation: usage of the `body` keyword is deprecated. Use `do` instead. ---- */ extern(C) int printf(const char*, ...); diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 308d51b55d0..a02a8cbaba5 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -a88e1335f7ea767ef438c34998f5d1f26008c586 +26f049fb26e755096dea3f1474decea7c0fef187 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/int128.d b/libphobos/libdruntime/core/int128.d index 20fa7dea170..4c88f15abfb 100644 --- a/libphobos/libdruntime/core/int128.d +++ b/libphobos/libdruntime/core/int128.d @@ -14,8 +14,8 @@ nothrow: @safe: @nogc: -alias I = long; -alias U = ulong; +private alias I = long; +private alias U = ulong; enum Ubits = uint(U.sizeof * 8); version (DigitalMars) @@ -36,6 +36,10 @@ else else private enum Cent_alignment = (size_t.sizeof * 2); } +/** + * 128 bit integer type. + * See_also: $(REF Int128, std,int128). + */ align(Cent_alignment) struct Cent { version (LittleEndian) diff --git a/libphobos/libdruntime/core/internal/array/comparison.d b/libphobos/libdruntime/core/internal/array/comparison.d index 821f96e25c0..94fa2433da8 100644 --- a/libphobos/libdruntime/core/internal/array/comparison.d +++ b/libphobos/libdruntime/core/internal/array/comparison.d @@ -83,7 +83,7 @@ int __cmp(T)(scope const T[] lhs, scope const T[] rhs) @trusted // This function is called by the compiler when dealing with array // comparisons in the semantic analysis phase of CmpExp. The ordering // comparison is lowered to a call to this template. -int __cmp(T1, T2)(T1[] s1, T2[] s2) +auto __cmp(T1, T2)(T1[] s1, T2[] s2) if (!__traits(isScalar, T1) && !__traits(isScalar, T2)) { import core.internal.traits : Unqual; @@ -237,3 +237,26 @@ if (!__traits(isScalar, T1) && !__traits(isScalar, T2)) auto vb = [cast(void[])b[0], b[1]]; assert(less2(va, vb)); } + +// custom aggregate types +@safe unittest +{ + // https://issues.dlang.org/show_bug.cgi?id=24044 + // Support float opCmp(...) with array + static struct F + { + float f; + float opCmp(F other) const { return this.f - other.f; } + } + + F[2] a = [F(1.0f), F(float.nan)]; + F[2] b = [F(1.0f), F(1.0f)]; + F[1] c = [F(1.0f)]; + + bool isNan(float f) { return f != f; } + + assert(isNan(__cmp(a, b))); + assert(isNan(__cmp(a, a))); + assert(__cmp(b, b) == 0); + assert(__cmp(a, c) > 0); +} diff --git a/libphobos/libdruntime/core/lifetime.d b/libphobos/libdruntime/core/lifetime.d index 89236dbf4c1..3a55ca916c2 100644 --- a/libphobos/libdruntime/core/lifetime.d +++ b/libphobos/libdruntime/core/lifetime.d @@ -1570,7 +1570,11 @@ template forward(args...) alias fwd = arg; // (r)value else - @property auto fwd(){ pragma(inline, true); return move(arg); } + @property auto fwd() + { + version (DigitalMars) { /* @@BUG 23890@@ */ } else pragma(inline, true); + return move(arg); + } } alias Result = AliasSeq!(); diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index e0011d7e7f7..a5414f16cd3 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -1921d29df25f2b44d6014c224e2018ce63ac2b71 +330d6a4fdbe82683e081959d0aeb53597b025bc4 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/searching.d b/libphobos/src/std/algorithm/searching.d index f061915d582..37a08de7a8f 100644 --- a/libphobos/src/std/algorithm/searching.d +++ b/libphobos/src/std/algorithm/searching.d @@ -1528,6 +1528,23 @@ if (isInputRange!Range && !isInfinite!Range && assert([S(5), S(6)].extremum!"a.value" == S(5)); } +// https://issues.dlang.org/show_bug.cgi?id=24027 +@safe nothrow unittest +{ + class A + { + int a; + this(int a) + { + this.a = a; + } + } + + auto test = new A(5); + A[] arr = [test]; + assert(maxElement!"a.a"(arr) is test); +} + // find /** Finds an individual element in an $(REF_ALTTEXT input range, isInputRange, std,range,primitives). diff --git a/libphobos/src/std/bigint.d b/libphobos/src/std/bigint.d index 50f88da6055..0240ea1d179 100644 --- a/libphobos/src/std/bigint.d +++ b/libphobos/src/std/bigint.d @@ -323,7 +323,15 @@ public: else static if (op=="^^") { sign = (y & 1) ? sign : false; - data = BigUint.pow(data, u); + if (y < 0) + { + checkDivByZero(); + data = cast(ulong) (data == 1); + } + else + { + data = BigUint.pow(data, u); + } } else static if (op=="&") { @@ -411,6 +419,19 @@ public: )); } + // https://issues.dlang.org/show_bug.cgi?id=24028 + @system unittest + { + import std.exception : assertThrown; + import core.exception : AssertError; + + assert(BigInt(100) ^^ -1 == BigInt(0)); + assert(BigInt(1) ^^ -1 == BigInt(1)); + assert(BigInt(-1) ^^ -1 == BigInt(-1)); + assert(BigInt(-1) ^^ -2 == BigInt(1)); + assertThrown!AssertError(BigInt(0) ^^ -1); + } + /** * Implements assignment operators of the form `BigInt op= BigInt`. */ diff --git a/libphobos/src/std/json.d b/libphobos/src/std/json.d index 219af714373..7d48890501f 100644 --- a/libphobos/src/std/json.d +++ b/libphobos/src/std/json.d @@ -6,6 +6,10 @@ Implements functionality to read and write JavaScript Object Notation values. JavaScript Object Notation is a lightweight data interchange format commonly used in web services and configuration files. It's easy for humans to read and write, and it's easy for machines to parse and generate. +$(RED Warning: While $(LREF JSONValue) is fine for small-scale use, at the range of hundreds of megabytes it is +known to cause and exacerbate GC problems. If you encounter problems, try replacing it with a stream parser. See +also $(LINK https://forum.dlang.org/post/dzfyaxypmkdrpakmycjv@forum.dlang.org).) + Copyright: Copyright Jeremie Pelletier 2008 - 2009. License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0). Authors: Jeremie Pelletier, David Herberth diff --git a/libphobos/src/std/math/package.d b/libphobos/src/std/math/package.d index 19982ec216a..b5f914acf7c 100644 --- a/libphobos/src/std/math/package.d +++ b/libphobos/src/std/math/package.d @@ -168,12 +168,6 @@ public import std.math.rounding; public import std.math.traits; public import std.math.trigonometry; -// @@@DEPRECATED_2.102@@@ -// Note: Exposed accidentally, should be deprecated / removed -deprecated("std.meta.AliasSeq was unintentionally available from std.math " - ~ "and will be removed after 2.102. Please import std.meta instead") -public import std.meta : AliasSeq; - package(std): // Not public yet /* Return the value that lies halfway between x and y on the IEEE number line. * diff --git a/libphobos/src/std/stdio.d b/libphobos/src/std/stdio.d index 19ce9880b89..d9291b11bde 100644 --- a/libphobos/src/std/stdio.d +++ b/libphobos/src/std/stdio.d @@ -425,21 +425,6 @@ private extern (C) @nogc nothrow pragma(mangle, _FPUTWC.mangleof) int trustedFPUTWC(wchar_t ch, _iobuf* h) @trusted; } -static if (__traits(compiles, core.sys.posix.stdio.getdelim)) -{ - extern(C) nothrow @nogc - { - // @@@DEPRECATED_2.104@@@ - deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getdelim instead.") - ptrdiff_t getdelim(char**, size_t*, int, FILE*); - - // @@@DEPRECATED_2.104@@@ - // getline() always comes together with getdelim() - deprecated("To be removed after 2.104. Use core.sys.posix.stdio.getline instead.") - ptrdiff_t getline(char**, size_t*, FILE*); - } -} - //------------------------------------------------------------------------------ private struct ByRecordImpl(Fields...) { -- 2.39.2