From patchwork Sun Mar 17 11:15:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1912897 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gdcproject.org header.i=@gdcproject.org header.a=rsa-sha256 header.s=MBO0001 header.b=ns6UtcRz; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TyFmr6G0rz1yWy for ; Sun, 17 Mar 2024 22:16:42 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 61386385842C for ; Sun, 17 Mar 2024 11:16:40 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-201.mailbox.org (mout-p-201.mailbox.org [IPv6:2001:67c:2050:0:465::201]) by sourceware.org (Postfix) with ESMTPS id ED7D03858D37 for ; Sun, 17 Mar 2024 11:16:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org ED7D03858D37 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=gdcproject.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gdcproject.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org ED7D03858D37 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2001:67c:2050:0:465::201 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710674174; cv=none; b=JvFQD3FHp4430m5VYRMaRk1NRZoVd6TAfsJYqNTYmNlWOO1IEPnpQqzb1ROmiulpLIpfi0ndwVapVW6YOC0Yzdx+vnHJK7ZHJt0H5N6DH4Wpv13KCIlAlzyUOE3vXT1YDIYuG4Nzpy8vD6naoUifjIG7NEkXzr0Yd/J/QiCqci8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1710674174; c=relaxed/simple; bh=xIbcBlARqIIdDD97A2+pM5oXfpiL25pc5khml7bUWDI=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=csxhpMih4ZMWRXaoIA6A/xD9VmTwTr+PjL8bcN+ct1cqRBQULdkmzdTNYMj+pjMgoX8kOvMiJo3vU4ba1ld5dLYHt/X2mcAG2YMd7U3VOQDpFttLdBGrjotrjLuBHRCTHrNF9TpcyYY/HlrREyI7sl/WVTznDHqIfGmG9Baryis= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-201.mailbox.org (Postfix) with ESMTPS id 4TyFm45Lpmz9tWn; Sun, 17 Mar 2024 12:16:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gdcproject.org; s=MBO0001; t=1710674164; 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=ZUf0o9aihmSJYr/hl+JMHXcfGgMeHy0VREYwEnFRUJs=; b=ns6UtcRzcKNTWz33EEQ4f7nvhBTQkSUTG8S5LPCew6478mipBcxLpt372kf1/rLWQWqqMm oFvhrrNh9b+D8qfchYsmZPTl1aQPSm85UIjureQcgLcehKFJm3no8wko9b4RpM1M1cbTd7 dX+JTNG6+nOn2MeODZd2Wbx31EkVdpIvvI+2gfho1jk9XV6USHl4cv/nzDN1IjVtOH7uDi ULK39+uMyUPGcmr8oW5OKvymGV7wS3J9SxsJCuiUH9XY3kwTVmHp5YAtusHcUuL5RzAuvv udyn34wv+S1VJPIFe7VlwzdGGBAYm6B2RoZ8ef8V/uEasxI2TD2Sg2EMbglCCA== From: Iain Buclaw To: gcc-patches@gcc.gnu.org Cc: Iain Buclaw Subject: [committed] d: Merge upstream dmd, druntime 855353a1d9 Date: Sun, 17 Mar 2024 12:15:59 +0100 Message-Id: <20240317111559.463023-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_LOTSOFHASH, KAM_NUMSUBJECT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Hi, This patch merges the D front-end and runtime library with upstream dmd 855353a1d9. D front-end changes: - Import dmd v2.108.0-rc.1. - Add support for Named Arguments for functions. - Hex strings now convert to integer arrays. D runtime changes: - Import druntime v2.108.0-rc.1. Bootstrapped and regression tested on x86_64-linux-gnu/-m32, committed to mainline. Regards, Iain. --- gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 855353a1d9. * dmd/VERSION: libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 855353a1d9. --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/VERSION | 2 +- gcc/d/dmd/cxxfrontend.d | 10 +++ gcc/d/dmd/dcast.d | 31 ++++--- gcc/d/dmd/dinterpret.d | 2 +- gcc/d/dmd/dsymbolsem.d | 7 +- gcc/d/dmd/dtemplate.d | 48 +++++++++-- gcc/d/dmd/enum.h | 6 ++ gcc/d/dmd/expression.h | 15 ++++ gcc/d/dmd/expressionsem.d | 9 +- gcc/d/dmd/hdrgen.d | 3 +- gcc/d/dmd/lexer.d | 1 - gcc/d/dmd/mtype.d | 17 ++-- gcc/d/dmd/mtype.h | 5 +- gcc/d/dmd/root/filename.d | 2 +- gcc/d/dmd/root/filename.h | 2 +- gcc/d/dmd/template.h | 16 +--- gcc/d/dmd/templatesem.d | 85 ++++++++++++------- gcc/d/dmd/typesem.d | 16 +++- .../compilable/named_arguments_auto_ref.d | 39 +++++++++ .../compilable/named_arguments_ifti.d | 27 ++++++ .../gdc.test/fail_compilation/hexstring.d | 5 +- .../fail_compilation/named_arguments_error.d | 11 ++- .../named_arguments_ifti_error.d | 20 +++++ gcc/testsuite/gdc.test/runnable/literal.d | 10 ++- libphobos/libdruntime/MERGE | 2 +- .../core/internal/gc/impl/conservative/gc.d | 4 +- .../core/internal/gc/impl/manual/gc.d | 2 +- .../core/internal/gc/impl/proto/gc.d | 2 +- 29 files changed, 294 insertions(+), 107 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/named_arguments_auto_ref.d create mode 100644 gcc/testsuite/gdc.test/compilable/named_arguments_ifti.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/named_arguments_ifti_error.d diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 4c0a0bc2aac..a00872ef864 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -f8bae0455851a1dfc8113d69323415f6de549e39 +855353a1d9e16d43e85b6cf2b03aef388619bd16 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 416807683f5..8ca452f8912 100644 --- a/gcc/d/dmd/VERSION +++ b/gcc/d/dmd/VERSION @@ -1 +1 @@ -v2.108.0-beta.1 +v2.108.0-rc.1 diff --git a/gcc/d/dmd/cxxfrontend.d b/gcc/d/dmd/cxxfrontend.d index 8c046343468..a0432d2e1b4 100644 --- a/gcc/d/dmd/cxxfrontend.d +++ b/gcc/d/dmd/cxxfrontend.d @@ -14,6 +14,7 @@ import dmd.aggregate : AggregateDeclaration; import dmd.arraytypes; import dmd.astenums; import dmd.common.outbuffer : OutBuffer; +import dmd.denum : EnumDeclaration; import dmd.dmodule /*: Module*/; import dmd.dscope : Scope; import dmd.dstruct /*: StructDeclaration*/; @@ -213,6 +214,15 @@ void genCppHdrFiles(ref Modules ms) return dmd.dtoh.genCppHdrFiles(ms); } +/*********************************************************** + * enumsem.d + */ +Expression getDefaultValue(EnumDeclaration ed, const ref Loc loc) +{ + import dmd.enumsem; + return dmd.enumsem.getDefaultValue(ed, loc); +} + /*********************************************************** * expression.d */ diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d index a49bd575f4b..8a713f424d6 100644 --- a/gcc/d/dmd/dcast.d +++ b/gcc/d/dmd/dcast.d @@ -629,7 +629,7 @@ MATCH implicitConvTo(Expression e, Type t) TY tyn = e.type.nextOf().ty; - if (!tyn.isSomeChar) + if (!tyn.isSomeChar && !e.hexString) return visit(e); switch (t.ty) @@ -703,6 +703,11 @@ MATCH implicitConvTo(Expression e, Type t) return MATCH.nomatch; m = MATCH.constant; } + if (e.hexString && tn.isintegral && (tn.size == e.sz || (!e.committed && (e.len % tn.size) == 0))) + { + m = MATCH.convert; + return m; + } if (!e.committed) { switch (tn.ty) @@ -719,9 +724,6 @@ MATCH implicitConvTo(Expression e, Type t) if (e.postfix != 'd') m = MATCH.convert; return m; - case Tint8: - case Tuns8: - break; case Tenum: if (tn.isTypeEnum().sym.isSpecial()) { @@ -735,14 +737,6 @@ MATCH implicitConvTo(Expression e, Type t) break; } } - if (e.hexString) - { - if (tn.isintegral && tn.size == e.sz) - { - m = MATCH.convert; - return m; - } - } break; default: @@ -1884,6 +1878,19 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null) Type tb = t.toBasetype(); Type typeb = e.type.toBasetype(); + if (e.hexString && !e.committed) + { + const szx = cast(ubyte) tb.nextOf().size(); + if (szx != se.sz && (e.len % szx) == 0) + { + import dmd.utils: arrayCastBigEndian; + const data = e.peekData(); + se.setData(arrayCastBigEndian(data, szx).ptr, data.length / szx, szx); + se.type = t; + return se; + } + } + //printf("\ttype = %s\n", e.type.toChars()); if (tb.ty == Tdelegate && typeb.ty != Tdelegate) { diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d index c4924903f25..5493fc18881 100644 --- a/gcc/d/dmd/dinterpret.d +++ b/gcc/d/dmd/dinterpret.d @@ -6118,7 +6118,7 @@ public: return; } - auto str = arrayCastBigEndian((cast(const ubyte[]) se.peekString()), sz); + auto str = arrayCastBigEndian(se.peekData(), sz); emplaceExp!(StringExp)(pue, e1.loc, str, se.len / sz, cast(ubyte) sz); result = pue.exp(); result.type = e.to; diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d index bb0a1d6e2cc..b13f98aee73 100644 --- a/gcc/d/dmd/dsymbolsem.d +++ b/gcc/d/dmd/dsymbolsem.d @@ -4621,12 +4621,11 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList return aliasInstanceSemantic(tempinst, sc, tempdecl); } - Expressions* fargs = argumentList.arguments; // TODO: resolve named args /* See if there is an existing TemplateInstantiation that already * implements the typeargs. If so, just refer to that one instead. */ - tempinst.inst = tempdecl.findExistingInstance(tempinst, fargs); + tempinst.inst = tempdecl.findExistingInstance(tempinst, argumentList); TemplateInstance errinst = null; if (!tempinst.inst) { @@ -4874,7 +4873,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList /* If function template declaration */ - if (fargs && tempinst.aliasdecl) + if (argumentList.length > 0 && tempinst.aliasdecl) { if (auto fd = tempinst.aliasdecl.isFuncDeclaration()) { @@ -4883,7 +4882,7 @@ void templateInstanceSemantic(TemplateInstance tempinst, Scope* sc, ArgumentList */ if (fd.type) if (auto tf = fd.type.isTypeFunction()) - tf.fargs = fargs; + tf.inferenceArguments = argumentList; } } diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d index 165a010059f..d181facfc24 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -828,16 +828,24 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol } /**************************************************** - * Given a new instance tithis of this TemplateDeclaration, + * Given a new instance `tithis` of this TemplateDeclaration, * see if there already exists an instance. - * If so, return that existing instance. + * + * Params: + * tithis = template instance to check + * argumentList = For function templates, needed because different + * `auto ref` resolutions create different instances, + * even when template parameters are identical + * + * Returns: that existing instance, or `null` when it doesn't exist */ - extern (D) TemplateInstance findExistingInstance(TemplateInstance tithis, Expressions* fargs) + extern (D) TemplateInstance findExistingInstance(TemplateInstance tithis, ArgumentList argumentList) { //printf("findExistingInstance() %s\n", tithis.toChars()); - tithis.fargs = fargs; + tithis.fargs = argumentList.arguments; + tithis.fnames = argumentList.names; auto tibox = TemplateInstanceBox(tithis); - auto p = tibox in instances; + auto p = tibox in this.instances; debug (FindExistingInstance) ++(p ? nFound : nNotFound); //if (p) printf("\tfound %p\n", *p); else printf("\tnot found\n"); return p ? *p : null; @@ -3674,7 +3682,12 @@ extern (C++) class TemplateInstance : ScopeDsymbol TemplateInstance inst; // refer to existing instance ScopeDsymbol argsym; // argument symbol table size_t hash; // cached result of toHash() - Expressions* fargs; // for function template, these are the function arguments + + /// For function template, these are the function names and arguments + /// Relevant because different resolutions of `auto ref` parameters + /// create different template instances even with the same template arguments + Expressions* fargs; + Identifiers* fnames; TemplateInstances* deferred; @@ -3974,6 +3987,19 @@ extern (C++) class TemplateInstance : ScopeDsymbol { if (!fd.errors) { + auto resolvedArgs = fd.type.isTypeFunction().resolveNamedArgs( + ArgumentList(this.fargs, this.fnames), null); + + // resolvedArgs can be null when there's an error: fail_compilation/fail14669.d + // In that case, equalsx returns true to prevent endless template instantiations + // However, it can also mean the function was explicitly instantiated + // without function arguments: fail_compilation/fail14669 + // Hence the following check: + if (this.fargs && !resolvedArgs) + return true; + + Expression[] args = resolvedArgs ? (*resolvedArgs)[] : []; + auto fparameters = fd.getParameterList(); size_t nfparams = fparameters.length; // Num function parameters for (size_t j = 0; j < nfparams; j++) @@ -3981,7 +4007,12 @@ extern (C++) class TemplateInstance : ScopeDsymbol Parameter fparam = fparameters[j]; if (fparam.storageClass & STC.autoref) // if "auto ref" { - Expression farg = fargs && j < fargs.length ? (*fargs)[j] : fparam.defaultArg; + Expression farg = (j < args.length) ? args[j] : fparam.defaultArg; + // resolveNamedArgs strips trailing nulls / default params + // when it doesn't anymore, the ternary can be replaced with: + // assert(j < resolvedArgs.length); + if (!farg) + farg = fparam.defaultArg; if (!farg) goto Lnotequals; if (farg.isLvalue()) @@ -5723,8 +5754,7 @@ extern (C++) final class TemplateMixin : TemplateInstance /************************************ * This struct is needed for TemplateInstance to be the key in an associative array. - * Fixing https://issues.dlang.org/show_bug.cgi?id=15812 and - * https://issues.dlang.org/show_bug.cgi?id=15813 would make it unnecessary. + * Fixing https://issues.dlang.org/show_bug.cgi?id=15813 would make it unnecessary. */ struct TemplateInstanceBox { diff --git a/gcc/d/dmd/enum.h b/gcc/d/dmd/enum.h index 650bf3e2c7c..4e6fbe2cacf 100644 --- a/gcc/d/dmd/enum.h +++ b/gcc/d/dmd/enum.h @@ -17,6 +17,12 @@ class Identifier; class Type; class Expression; +namespace dmd +{ + // in enumsem.d + Expression *getDefaultValue(EnumDeclaration *ed, const Loc &loc); +} + class EnumDeclaration final : public ScopeDsymbol { public: diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h index 9cd73a965ba..2f6bb84acb9 100644 --- a/gcc/d/dmd/expression.h +++ b/gcc/d/dmd/expression.h @@ -800,6 +800,21 @@ public: void accept(Visitor *v) override { v->visit(this); } }; +struct ArgumentList final +{ + Expressions* arguments; + Identifiers* names; + ArgumentList() : + arguments(), + names() + { + } + ArgumentList(Expressions* arguments, Identifiers* names = nullptr) : + arguments(arguments), + names(names) + {} +}; + class CallExp final : public UnaExp { public: diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d index db40ae01dec..7ae7f400d16 100644 --- a/gcc/d/dmd/expressionsem.d +++ b/gcc/d/dmd/expressionsem.d @@ -2984,6 +2984,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc, foreach (u; 0 .. elements.length) { Expression a = (*arguments)[i + u]; + assert(a); if (tret && a.implicitConvTo(tret)) { // p is a lazy array of delegates, tret is return type of the delegates @@ -4245,18 +4246,21 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (e.hexString) { - const data = cast(const ubyte[]) e.peekString(); switch (e.postfix) { case 'd': + e.committed = true; e.sz = 4; e.type = Type.tdstring; break; case 'w': + e.committed = true; e.sz = 2; e.type = Type.twstring; break; case 'c': + e.committed = true; + goto default; default: e.type = Type.tstring; e.sz = 1; @@ -4266,8 +4270,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor error(e.loc, "hex string with `%s` type needs to be multiple of %d bytes, not %d", e.type.toChars(), e.sz, cast(int) e.len); - e.setData(arrayCastBigEndian(data, e.sz).ptr, e.len / e.sz, e.sz); - e.committed = true; + e.setData(arrayCastBigEndian(e.peekData(), e.sz).ptr, e.len / e.sz, e.sz); } else switch (e.postfix) { diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d index 8eef7992e2a..41da11dedbe 100644 --- a/gcc/d/dmd/hdrgen.d +++ b/gcc/d/dmd/hdrgen.d @@ -2281,7 +2281,8 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt { buf.writeByte('x'); buf.writeByte('"'); - buf.writeHexString(e.peekData, true); + foreach (i; 0 .. e.len) + buf.printf("%0*llX", e.sz, e.getIndex(i)); buf.writeByte('"'); if (e.postfix) buf.writeByte(e.postfix); diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index 937597cdf89..c9c506e9cf3 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -1568,7 +1568,6 @@ class Lexer stringbuffer.writeByte(v); } t.setString(stringbuffer); - t.postfix = 'h'; stringPostfix(t); return TOK.hexadecimalString; default: diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d index 2c9e058bf32..715ee12159c 100644 --- a/gcc/d/dmd/mtype.d +++ b/gcc/d/dmd/mtype.d @@ -3073,7 +3073,7 @@ extern (C++) final class TypeFunction : TypeNext TRUST trust; // level of trust PURE purity = PURE.impure; byte inuse; - Expressions* fargs; // function arguments + ArgumentList inferenceArguments; // function arguments to determine `auto ref` in type semantic extern (D) this(ParameterList pl, Type treturn, LINK linkage, StorageClass stc = 0) @safe { @@ -3146,7 +3146,7 @@ extern (C++) final class TypeFunction : TypeNext t.isInOutParam = isInOutParam; t.isInOutQual = isInOutQual; t.trust = trust; - t.fargs = fargs; + t.inferenceArguments = inferenceArguments; t.isctor = isctor; return t; } @@ -3197,10 +3197,12 @@ extern (C++) final class TypeFunction : TypeNext { Expression[] args = argumentList.arguments ? (*argumentList.arguments)[] : null; Identifier[] names = argumentList.names ? (*argumentList.names)[] : null; - auto newArgs = new Expressions(parameterList.length); + const nParams = parameterList.length(); // cached because O(n) + auto newArgs = new Expressions(nParams); newArgs.zero(); size_t ci = 0; bool hasNamedArgs = false; + const bool isVariadic = parameterList.varargs != VarArg.none; foreach (i, arg; args) { if (!arg) @@ -3223,7 +3225,7 @@ extern (C++) final class TypeFunction : TypeNext } if (ci >= newArgs.length) { - if (!parameterList.varargs) + if (!isVariadic) { // Without named args, let the caller diagnose argument overflow if (hasNamedArgs && pMessage) @@ -3247,7 +3249,12 @@ extern (C++) final class TypeFunction : TypeNext if (arg || parameterList[i].defaultArg) continue; - if (parameterList.varargs != VarArg.none && i + 1 == newArgs.length) + if (isVariadic && i + 1 == newArgs.length) + continue; + + // dtemplate sets `defaultArg=null` to avoid semantic on default arguments, + // don't complain about missing arguments in that case + if (this.incomplete) continue; if (pMessage) diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h index 2f8bfa68d22..ad64b120f40 100644 --- a/gcc/d/dmd/mtype.h +++ b/gcc/d/dmd/mtype.h @@ -14,6 +14,7 @@ #include "arraytypes.h" #include "ast_node.h" +#include "expression.h" #include "globals.h" #include "visitor.h" @@ -254,8 +255,6 @@ public: bool isSharedWild() const { return (mod & (MODshared | MODwild)) == (MODshared | MODwild); } bool isNaked() const { return mod == 0; } Type *nullAttributes() const; - Type *arrayOf(); - Type *sarrayOf(dinteger_t dim); bool hasDeprecatedAliasThis(); virtual Type *makeConst(); virtual Type *makeImmutable(); @@ -567,7 +566,7 @@ public: TRUST trust; // level of trust PURE purity; // PURExxxx char inuse; - Expressions *fargs; // function arguments + ArgumentList inferenceArguments; // function arguments static TypeFunction *create(Parameters *parameters, Type *treturn, VarArg varargs, LINK linkage, StorageClass stc = 0); const char *kind() override; diff --git a/gcc/d/dmd/root/filename.d b/gcc/d/dmd/root/filename.d index 41c2050057d..d9f1a04057d 100644 --- a/gcc/d/dmd/root/filename.d +++ b/gcc/d/dmd/root/filename.d @@ -665,7 +665,7 @@ nothrow: * Returns: * if found, filename combined with path, otherwise null */ - extern (C++) static const(char)* searchPath(const ref Strings path, const char* name, bool cwd) + extern (C++) static const(char)* searchPath(const ref Strings path, const(char)* name, bool cwd) { return searchPath(path[], name.toDString, cwd).ptr; } diff --git a/gcc/d/dmd/root/filename.h b/gcc/d/dmd/root/filename.h index 0e52b982323..e8c8b11fffd 100644 --- a/gcc/d/dmd/root/filename.h +++ b/gcc/d/dmd/root/filename.h @@ -38,7 +38,7 @@ public: bool equalsExt(const char *ext); - static const char *searchPath(Strings& path, const char *name, bool cwd); + static const char *searchPath(const Strings &path, const char *name, bool cwd); static int exists(const char *name); static bool ensurePathExists(const char *path); static const char *canonicalName(const char *name); diff --git a/gcc/d/dmd/template.h b/gcc/d/dmd/template.h index 0f96a1b3b09..bccec1a68c1 100644 --- a/gcc/d/dmd/template.h +++ b/gcc/d/dmd/template.h @@ -12,6 +12,7 @@ #include "arraytypes.h" #include "dsymbol.h" +#include "expression.h" class Identifier; class TemplateInstance; @@ -46,20 +47,6 @@ struct TemplatePrevious Objects *dedargs; }; -struct ArgumentList final -{ - Expressions* arguments; - Identifiers* names; - ArgumentList() : - arguments(), - names() - { - } - ArgumentList(Expressions* arguments, Identifiers* names = nullptr) : - arguments(arguments), - names(names) - {} -}; class TemplateDeclaration final : public ScopeDsymbol { @@ -271,6 +258,7 @@ public: ScopeDsymbol *argsym; // argument symbol table hash_t hash; // cached result of toHash() Expressions *fargs; // for function template, these are the function arguments + Identifiers *fnames; // for function template, argument names TemplateInstances* deferred; diff --git a/gcc/d/dmd/templatesem.d b/gcc/d/dmd/templatesem.d index 0a36838e167..bd3cd89588f 100644 --- a/gcc/d/dmd/templatesem.d +++ b/gcc/d/dmd/templatesem.d @@ -250,7 +250,7 @@ MATCH matchWithInstance(Scope* sc, TemplateDeclaration td, TemplateInstance ti, return MATCH.nomatch; size_t parameters_dim = td.parameters.length; - int variadic = td.isVariadic() !is null; + const bool variadic = td.isVariadic() !is null; // If more arguments than parameters, no match if (ti.tiargs.length > parameters_dim && !variadic) @@ -338,12 +338,6 @@ MATCH matchWithInstance(Scope* sc, TemplateDeclaration td, TemplateInstance ti, if (fd) { TypeFunction tf = fd.type.isTypeFunction().syntaxCopy(); - if (argumentList.hasNames) - return nomatch(); - Expressions* fargs = argumentList.arguments; - // TODO: Expressions* fargs = tf.resolveNamedArgs(argumentList, null); - // if (!fargs) - // return nomatch(); fd = new FuncDeclaration(fd.loc, fd.endloc, fd.ident, fd.storage_class, tf); fd.parent = ti; @@ -357,7 +351,7 @@ MATCH matchWithInstance(Scope* sc, TemplateDeclaration td, TemplateInstance ti, tf.incomplete = true; // Resolve parameter types and 'auto ref's. - tf.fargs = fargs; + tf.inferenceArguments = argumentList; uint olderrors = global.startGagging(); fd.type = tf.typeSemantic(td.loc, paramscope); global.endGagging(olderrors); @@ -762,7 +756,7 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat } size_t ntargs = 0; // array size of tiargs - size_t inferStart = 0; // index of first parameter to infer + size_t inferStart = 0; // index of first template parameter to infer from function argument const Loc instLoc = ti.loc; MATCH matchTiargs = MATCH.exact; @@ -834,9 +828,6 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat ParameterList fparameters = fd.getParameterList(); // function parameter list const nfparams = fparameters.length; // number of function parameters - if (argumentList.hasNames) - return matcherror(); // TODO: resolve named args - Expression[] fargs = argumentList.arguments ? (*argumentList.arguments)[] : null; /* Check for match of function arguments with variadic template * parameter, such as: @@ -950,9 +941,14 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat { //printf("%s\n\tnfargs = %d, nfparams = %d, tuple_dim = %d\n", toChars(), nfargs, nfparams, declaredTuple ? declaredTuple.objects.length : 0); //printf("\ttp = %p, fptupindex = %d, found = %d, declaredTuple = %s\n", tp, fptupindex, fptupindex != IDX_NOTFOUND, declaredTuple ? declaredTuple.toChars() : NULL); - size_t argi = 0; - size_t nfargs2 = fargs.length; // nfargs + supplied defaultArgs + enum DEFAULT_ARGI = size_t.max - 10; // pseudo index signifying the parameter is expected to be assigned its default argument + size_t argi = 0; // current argument index + size_t argsConsumed = 0; // to ensure no excess arguments + size_t nfargs2 = argumentList.length; // total number of arguments including applied defaultArgs uint inoutMatch = 0; // for debugging only + Expression[] fargs = argumentList.arguments ? (*argumentList.arguments)[] : null; + Identifier[] fnames = argumentList.names ? (*argumentList.names)[] : null; + for (size_t parami = 0; parami < nfparams; parami++) { Parameter fparam = fparameters[parami]; @@ -961,11 +957,28 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat Type prmtype = fparam.type.addStorageClass(fparam.storageClass); Expression farg; + Identifier fname = argi < fnames.length ? fnames[argi] : null; + bool foundName = false; + if (fparam.ident) + { + foreach (i; 0 .. fnames.length) + { + if (fparam.ident == fnames[i]) + { + argi = i; + foundName = true; + } + } + } + if (fname && !foundName) + { + argi = DEFAULT_ARGI; + } /* See function parameters which wound up * as part of a template tuple parameter. */ - if (fptupindex != IDX_NOTFOUND && parami == fptupindex) + if (fptupindex != IDX_NOTFOUND && parami == fptupindex && argi != DEFAULT_ARGI) { TypeIdentifier tid = prmtype.isTypeIdentifier(); assert(tid); @@ -986,7 +999,12 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat Parameter p = fparameters[j]; if (p.defaultArg) { - break; + break; + } + foreach(name; fnames) + { + if (p.ident == name) + break; } if (!reliesOnTemplateParameters(p.type, (*td.parameters)[inferStart .. td.parameters.length])) { @@ -1055,6 +1073,7 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat } assert(declaredTuple); argi += declaredTuple.objects.length; + argsConsumed += declaredTuple.objects.length; continue; } @@ -1068,7 +1087,7 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat if (TypeTuple tt = prmtype.isTypeTuple()) { const tt_dim = tt.arguments.length; - for (size_t j = 0; j < tt_dim; j++, ++argi) + for (size_t j = 0; j < tt_dim; j++, ++argi, ++argsConsumed) { Parameter p = (*tt.arguments)[j]; if (j == tt_dim - 1 && fparameters.varargs == VarArg.typesafe && @@ -1171,7 +1190,9 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat } } } - nfargs2 = argi + 1; + + if (argi != DEFAULT_ARGI) + nfargs2 = argi + 1; /* If prmtype does not depend on any template parameters: * @@ -1189,7 +1210,11 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat */ if (prmtype.deco || prmtype.syntaxCopy().trySemantic(td.loc, paramscope)) { - ++argi; + if (argi != DEFAULT_ARGI) + { + ++argi; + ++argsConsumed; + } continue; } @@ -1203,6 +1228,7 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat farg = fargs[argi]; } { + assert(farg); // Check invalid arguments to detect errors early. if (farg.op == EXP.error || farg.type.ty == Terror) return nomatch(); @@ -1350,7 +1376,11 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat { if (m < match) match = m; // pick worst match - argi++; + if (argi != DEFAULT_ARGI) + { + argi++; + argsConsumed++; + } continue; } } @@ -1490,8 +1520,8 @@ extern (D) MATCHpair deduceFunctionTemplateMatch(TemplateDeclaration td, Templat } assert(0); } - //printf(". argi = %d, nfargs = %d, nfargs2 = %d\n", argi, nfargs, nfargs2); - if (argi != nfargs2 && fparameters.varargs == VarArg.none) + // printf(". argi = %d, nfargs = %d, nfargs2 = %d, argsConsumed = %d\n", cast(int) argi, cast(int) nfargs, cast(int) nfargs2, cast(int) argsConsumed); + if (argsConsumed != nfargs2 && fparameters.varargs == VarArg.none) return nomatch(); } @@ -1618,7 +1648,7 @@ Lmatch: sc2.minst = sc.minst; sc2.stc |= fd.storage_class & STC.deprecated_; - fd = doHeaderInstantiation(td, ti, sc2, fd, tthis, argumentList.arguments); + fd = doHeaderInstantiation(td, ti, sc2, fd, tthis, argumentList); sc2 = sc2.pop(); sc2 = sc2.pop(); @@ -1650,7 +1680,7 @@ Lmatch: * Limited function template instantiation for using fd.leastAsSpecialized() */ private -FuncDeclaration doHeaderInstantiation(TemplateDeclaration td, TemplateInstance ti, Scope* sc2, FuncDeclaration fd, Type tthis, Expressions* fargs) +FuncDeclaration doHeaderInstantiation(TemplateDeclaration td, TemplateInstance ti, Scope* sc2, FuncDeclaration fd, Type tthis, ArgumentList inferenceArguments) { assert(fd); version (none) @@ -1667,7 +1697,7 @@ FuncDeclaration doHeaderInstantiation(TemplateDeclaration td, TemplateInstance t assert(fd.type.ty == Tfunction); auto tf = fd.type.isTypeFunction(); - tf.fargs = fargs; + tf.inferenceArguments = inferenceArguments; if (tthis) { @@ -2084,11 +2114,6 @@ void functionResolve(ref MatchAccumulator m, Dsymbol dstart, Loc loc, Scope* sc, } //printf("td = %s\n", td.toChars()); - if (argumentList.hasNames) - { - .error(loc, "named arguments with Implicit Function Template Instantiation are not supported yet"); - goto Lerror; - } auto f = td.onemember ? td.onemember.isFuncDeclaration() : null; if (!f) { diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d index ad87ea0baeb..b2b9e38ead4 100644 --- a/gcc/d/dmd/typesem.d +++ b/gcc/d/dmd/typesem.d @@ -2187,6 +2187,12 @@ Type typeSemantic(Type type, const ref Loc loc, Scope* sc) } } + Expressions* fargs = mtype.inferenceArguments.arguments; + + // mtype.argumentList only provided for Implicit Function Template Instantiation + if (mtype.inferenceArguments.length > 0) + fargs = tf.resolveNamedArgs(mtype.inferenceArguments, null); + // Now that we completed semantic for the argument types, // run semantic on their default values, // bearing in mind tuples have been expanded. @@ -2236,8 +2242,10 @@ Type typeSemantic(Type type, const ref Loc loc, Scope* sc) */ if (eparam.storageClass & STC.auto_) { - Expression farg = mtype.fargs && eidx < mtype.fargs.length ? - (*mtype.fargs)[eidx] : eparam.defaultArg; + Expression farg = (fargs && eidx < fargs.length) ? (*fargs)[eidx] : null; + if (!farg) + farg = eparam.defaultArg; + if (farg && (eparam.storageClass & STC.ref_)) { if (!farg.isLvalue()) @@ -5681,7 +5689,7 @@ Type addStorageClass(Type type, StorageClass stc) // Klunky to change these auto tf = new TypeFunction(t.parameterList, t.next, t.linkage, 0); tf.mod = t.mod; - tf.fargs = tf_src.fargs; + tf.inferenceArguments = tf_src.inferenceArguments; tf.purity = t.purity; tf.isnothrow = t.isnothrow; tf.isnogc = t.isnogc; @@ -6775,7 +6783,7 @@ Type substWildTo(Type type, uint mod) t.isInOutParam = false; t.isInOutQual = false; t.trust = tf.trust; - t.fargs = tf.fargs; + t.inferenceArguments = tf.inferenceArguments; t.isctor = tf.isctor; return t.merge(); } diff --git a/gcc/testsuite/gdc.test/compilable/named_arguments_auto_ref.d b/gcc/testsuite/gdc.test/compilable/named_arguments_auto_ref.d new file mode 100644 index 00000000000..aa1ab7191c6 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/named_arguments_auto_ref.d @@ -0,0 +1,39 @@ +/** +TEST_OUTPUT: +--- +Call 0 +(x: true, y: false) +Call 1 +Call 2 +(x: false, y: false) +Call 3 +(x: false, y: true) +Call 4 +--- + +As of writing this test, template function instances store the function arguments from the call site. +When looking in cache for an existing template instantiation, matching template arguments isn't +sufficient: `auto ref` parameters being ref or not also create different template instances. +This test checks that the special logic for it still works with named arguments. +*/ + +void autoref()(auto ref int x, auto ref int y) +{ + pragma(msg, "(x: ", __traits(isRef, x), ", y: ", __traits(isRef, y), ")"); +} + +void main() +{ + int REF = 0; + enum NOT = 0; + pragma(msg, "Call 0"); + autoref(y: NOT, x: REF); // new instance + pragma(msg, "Call 1"); + autoref(x: REF, y: NOT); // existing instance + pragma(msg, "Call 2"); + autoref(x: NOT, y: NOT); // new instance + pragma(msg, "Call 3"); + autoref(x: NOT, y: REF); // new instance + pragma(msg, "Call 4"); + autoref(y: REF, x: NOT); // existing instance +} diff --git a/gcc/testsuite/gdc.test/compilable/named_arguments_ifti.d b/gcc/testsuite/gdc.test/compilable/named_arguments_ifti.d new file mode 100644 index 00000000000..3a35d799e63 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/named_arguments_ifti.d @@ -0,0 +1,27 @@ +// Basic out-of-order test +int f0(T0, T1)(T0 t0, T1 t1) +{ + static assert(is(T0 == int)); + static assert(is(T1 == string)); + return t0; +} + +static assert(f0(t1: "a", t0: 10) == 10); + +// Default argument at beginning instead of end +int f1(T0, T1)(T0 t0 = 20, T1 t1) { return t0; } +static assert(f1(t1: "a") == 20); + +// Two default arguments +int f2(T0, T1)(T0 t0 = 20, T1 t1, T2 t2 = 30) { return t2; } + +// Selecting overload based on name +string f3(T)(T x) { return "x"; } +string f3(T)(T y) { return "y"; } +static assert(f3(x: 0) == "x"); +static assert(f3(y: 0) == "y"); + +// Variadic tuple cut short by named argument +int f4(T...)(T x, int y, int z) { assert(y == 30); assert(z == 50); return T.length; } +static assert(f4(10, 10, 10, y: 30, z: 50) == 3); +static assert(f4(10, 10, 30, z: 50) == 2); diff --git a/gcc/testsuite/gdc.test/fail_compilation/hexstring.d b/gcc/testsuite/gdc.test/fail_compilation/hexstring.d index 95b07e763ff..0f23f444389 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/hexstring.d +++ b/gcc/testsuite/gdc.test/fail_compilation/hexstring.d @@ -12,11 +12,11 @@ fail_compilation/hexstring.d(38): Error: array cast from `string` to `immutable( fail_compilation/hexstring.d(39): Error: array cast from `string` to `immutable(uint[])` is not supported at compile time fail_compilation/hexstring.d(39): perhaps remove postfix `c` from hex string fail_compilation/hexstring.d(40): Error: hex string with `dstring` type needs to be multiple of 4 bytes, not 5 -fail_compilation/hexstring.d(41): Error: cannot implicitly convert expression `x"44332211"d` of type `dstring` to `immutable(float[])` +fail_compilation/hexstring.d(41): Error: cannot implicitly convert expression `x"11223344"d` of type `dstring` to `immutable(float[])` +fail_compilation/hexstring.d(42): Error: cannot implicitly convert expression `x"1122"w` of type `wstring` to `immutable(ubyte[])` fail_compilation/hexstring.d(28): Error: cannot implicitly convert expression `x"123F"` of type `string` to `ubyte[]` --- */ - immutable ubyte[] s0 = x"123F"; static assert(s0[0] == 0x12); static assert(s0[1] == 0x3F); @@ -39,3 +39,4 @@ immutable ushort[] f10 = cast(immutable ushort[]) (x"1122" ~ ""); immutable uint[] f11 = cast(immutable uint[]) x"AABBCCDD"c; immutable uint[] f12 = x"1122334455"d; immutable float[] f13 = x"11223344"d; +immutable ubyte[] f14 = x"1122"w; diff --git a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d index b634a119564..125ebcc926e 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d +++ b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_error.d @@ -19,15 +19,15 @@ fail_compilation/named_arguments_error.d(33): `named_arguments_error.g(in fail_compilation/named_arguments_error.d(43): Error: no named argument `element` allowed for array dimension fail_compilation/named_arguments_error.d(44): Error: no named argument `number` allowed for scalar fail_compilation/named_arguments_error.d(45): Error: cannot implicitly convert expression `g(x: 3, y: 4, z: 5)` of type `int` to `string` -fail_compilation/named_arguments_error.d(46): Error: named arguments with Implicit Function Template Instantiation are not supported yet -fail_compilation/named_arguments_error.d(46): Error: template `tempfun` is not callable using argument types `!()(string, int)` -fail_compilation/named_arguments_error.d(50): Candidate is: `tempfun(T, U)(T t, U u)` +fail_compilation/named_arguments_error.d(46): Error: template `tempfun` is not callable using argument types `!()(int, int)` +fail_compilation/named_arguments_error.d(49): Candidate is: `tempfun(T, U)(T t, U u)` --- */ + void f(int x, int y, int z); int g(int x, int y, int z = 3); @@ -43,11 +43,10 @@ void main() auto g0 = new int[](element: 3); auto g1 = new int(number: 3); string s = g(x: 3, y: 4, z: 5); - enum x = tempfun(u: "u", t: 0); + enum x = tempfun(u: 0, 1); } -// template arguments int tempfun(T, U)(T t, U u) { - return 3; + return 3; } diff --git a/gcc/testsuite/gdc.test/fail_compilation/named_arguments_ifti_error.d b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_ifti_error.d new file mode 100644 index 00000000000..6d8a70a2c46 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/named_arguments_ifti_error.d @@ -0,0 +1,20 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/named_arguments_ifti_error.d(17): Error: template `f` is not callable using argument types `!()(int, int)` +fail_compilation/named_arguments_ifti_error.d(13): Candidate is: `f(T, U)(T x, U y)` +fail_compilation/named_arguments_ifti_error.d(18): Error: template `f` is not callable using argument types `!()(int, int)` +fail_compilation/named_arguments_ifti_error.d(13): Candidate is: `f(T, U)(T x, U y)` +fail_compilation/named_arguments_ifti_error.d(19): Error: template `f` is not callable using argument types `!()(int)` +fail_compilation/named_arguments_ifti_error.d(13): Candidate is: `f(T, U)(T x, U y)` +--- +*/ + +void f(T, U)(T x, U y) {} + +void main() +{ + f(x: 3, x: 3); // double assignment of x + f(y: 3, 3); // overflow past last parameter + f(y: 3); // skipping parameter x +} diff --git a/gcc/testsuite/gdc.test/runnable/literal.d b/gcc/testsuite/gdc.test/runnable/literal.d index 27b5543b6fc..3cc7e51197b 100644 --- a/gcc/testsuite/gdc.test/runnable/literal.d +++ b/gcc/testsuite/gdc.test/runnable/literal.d @@ -243,23 +243,27 @@ void test12950() void testHexstring() { - static immutable uint[] x = cast(immutable uint[]) x"FFAADDEE"; + static immutable uint[] x = cast(immutable uint[]) x"FFAADDEE"d; static assert(x[0] == 0xFFAADDEE); assert(x[0] == 0xFFAADDEE); - static immutable ulong[] y = cast(immutable ulong[]) x"1122334455667788AABBCCDDEEFF0099"; + static immutable ulong[] y = x"1122334455667788AABBCCDDEEFF0099"; static assert(y[0] == 0x1122334455667788); static assert(y[1] == 0xAABBCCDDEEFF0099); assert(y[0] == 0x1122334455667788); assert(y[1] == 0xAABBCCDDEEFF0099); + immutable long[] c = x"1122334455667788AABBCCDDEEFF0099"; + assert(c[0] == 0x1122334455667788); + assert(c[1] == 0xAABBCCDDEEFF0099); + // Test that mangling of StringExp with size 8 is the same as array literal mangling: void f(immutable ulong[] a)() {} static assert(f!y.mangleof == f!([0x1122334455667788, 0xAABBCCDDEEFF0099]).mangleof); // Test printing StringExp with size 8 enum toStr(immutable ulong[] v) = v.stringof; - static assert(toStr!y == `x"88776655443322119900FFEEDDCCBBAA"`); + static assert(toStr!y == `x"1122334455667788AABBCCDDEEFF0099"`); // Hex string postfixes // https://issues.dlang.org/show_bug.cgi?id=24363 diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 4c0a0bc2aac..a00872ef864 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -f8bae0455851a1dfc8113d69323415f6de549e39 +855353a1d9e16d43e85b6cf2b03aef388619bd16 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d index 56433b49302..cb8df47507f 100644 --- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d +++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d @@ -94,8 +94,8 @@ private // Declared as an extern instead of importing core.exception // to avoid inlining - see https://issues.dlang.org/show_bug.cgi?id=13725. - void onInvalidMemoryOperationError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc; - void onOutOfMemoryError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted nothrow @nogc; + noreturn onInvalidMemoryOperationError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc; + noreturn onOutOfMemoryError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc; version (COLLECT_FORK) version (OSX) diff --git a/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d b/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d index 570781e2fdc..b820adda1a2 100644 --- a/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d +++ b/libphobos/libdruntime/core/internal/gc/impl/manual/gc.d @@ -26,7 +26,7 @@ import core.internal.container.array; import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc; static import core.memory; -extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */ +extern (C) noreturn onOutOfMemoryError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */ // register GC in C constructor (_STI_) private pragma(crt_constructor) void gc_manual_ctor() diff --git a/libphobos/libdruntime/core/internal/gc/impl/proto/gc.d b/libphobos/libdruntime/core/internal/gc/impl/proto/gc.d index ff044d9a9b2..2286d17d9ce 100644 --- a/libphobos/libdruntime/core/internal/gc/impl/proto/gc.d +++ b/libphobos/libdruntime/core/internal/gc/impl/proto/gc.d @@ -8,7 +8,7 @@ import core.internal.container.array; import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc; static import core.memory; -extern (C) void onOutOfMemoryError(void* pretend_sideffect = null) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */ +extern (C) noreturn onOutOfMemoryError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */ private {