From patchwork Wed Mar 2 17:26:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1599896 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=ugNBV/OC; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (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 bilbo.ozlabs.org (Postfix) with ESMTPS id 4K81JR356pz9sGD for ; Thu, 3 Mar 2022 04:27:02 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 380203858403 for ; Wed, 2 Mar 2022 17:27:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 380203858403 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1646242020; bh=3h9vpwGyykXC3VY8hnqe66qt8cJMZGkhFAezX9PaxMo=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=ugNBV/OCquuhsm2Giio8u5AeQSDhp/MwKhtZi6izaby+JFaFHtRzgqh+I8AuQHW5U Pe3ucQvKug/p2muJ45ImMfh9RBU0jaAakfzI4Hoj6ghEQzywwYtP8/1Qi2lNxG8fgb QcmbAI/4VM68zuEqgyTXIk2gUqqeQ9aN/SEejhVw= 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::465:201]) by sourceware.org (Postfix) with ESMTPS id 94D043858C83 for ; Wed, 2 Mar 2022 17:26:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 94D043858C83 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:105:465:1:3:0]) (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-201.mailbox.org (Postfix) with ESMTPS id 4K81HR6Y04z9sbj; Wed, 2 Mar 2022 18:26:11 +0100 (CET) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Merge upstream dmd 423f19b41, druntime 100a608c, phobos a1f8c4c07. Date: Wed, 2 Mar 2022 18:26:04 +0100 Message-Id: <20220302172604.1111746-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.5 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, T_FILL_THIS_FORM_SHORT, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch merges the D front-end implementation with upstream dmd 423f19b41, as well as the D runtime libraries with druntime 100a608c, and phobos a1f8c4c07. D Runtime changes: - Fix stdc.stdio bindings to not depend on druntime (PR104729). - Implement stdc.math for Solaris (PR104735). Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, committed to mainline. Regards, Iain. --- gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 423f19b41. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 100a608c. * src/MERGE: Merge upstream phobos a1f8c4c07. --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/dtemplate.d | 9 +- gcc/d/dmd/expression.d | 161 +++++++++++++++++- gcc/d/dmd/lexer.d | 71 +++++++- gcc/d/dmd/optimize.d | 21 ++- gcc/d/dmd/statementsem.d | 2 + gcc/d/dmd/tokens.d | 2 + gcc/d/dmd/tokens.h | 1 + gcc/testsuite/gdc.test/compilable/test21975.d | 15 ++ .../runnable_cxx/extra-files/cppb.cpp | 47 ++--- libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/core/memory.d | 9 +- libphobos/libdruntime/core/stdc/math.d | 133 ++++++++++++++- libphobos/libdruntime/core/stdc/stdio.d | 16 +- libphobos/libdruntime/core/stdcpp/exception.d | 10 +- libphobos/libdruntime/core/stdcpp/typeinfo.d | 40 +++-- libphobos/libdruntime/core/sys/posix/locale.d | 2 +- libphobos/libdruntime/object.d | 18 +- libphobos/src/MERGE | 2 +- libphobos/src/std/datetime/systime.d | 35 ++-- libphobos/src/std/sumtype.d | 41 +---- 21 files changed, 503 insertions(+), 136 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/test21975.d diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index f08d53aa3cd..71dc2b0a155 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -cf63dd8e5a77ecb68cf5e7c43bf7b6c4c1154bbe +423f19b41089f627808bf16ff21c60c0791712ba 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/dtemplate.d b/gcc/d/dmd/dtemplate.d index 457c5d12892..6abe69a9c4f 100644 --- a/gcc/d/dmd/dtemplate.d +++ b/gcc/d/dmd/dtemplate.d @@ -4295,8 +4295,13 @@ MATCH deduceType(RootObject o, Scope* sc, Type tparam, TemplateParameters* param if (ti && ti.toAlias() == t.sym) { auto tx = new TypeInstance(Loc.initial, ti); - result = deduceType(tx, sc, tparam, parameters, dedtypes, wm); - return; + auto m = deduceType(tx, sc, tparam, parameters, dedtypes, wm); + // if we have a no match we still need to check alias this + if (m != MATCH.nomatch) + { + result = m; + return; + } } /* Match things like: diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d index b3aa0b268b4..2b41219846a 100644 --- a/gcc/d/dmd/expression.d +++ b/gcc/d/dmd/expression.d @@ -83,7 +83,7 @@ void emplaceExp(T : UnionExp)(T* p, Expression e) memcpy(p, cast(void*)e, e.size); } -// Return value for `checkModifiable` +/// Return value for `checkModifiable` enum Modifiable { /// Not modifiable @@ -1766,6 +1766,7 @@ extern (C++) abstract class Expression : ASTNode } /*********************************************************** + * A compile-time known integer value */ extern (C++) final class IntegerExp : Expression { @@ -1982,6 +1983,7 @@ extern (C++) final class IntegerExp : Expression /*********************************************************** * Use this expression for error recovery. + * * It should behave as a 'sink' to prevent further cascaded error messages. */ extern (C++) final class ErrorExp : Expression @@ -2026,6 +2028,8 @@ extern (C++) final class ErrorExp : Expression /*********************************************************** * An uninitialized value, * generated from void initializers. + * + * https://dlang.org/spec/declaration.html#void_init */ extern (C++) final class VoidInitExp : Expression { @@ -2052,6 +2056,7 @@ extern (C++) final class VoidInitExp : Expression /*********************************************************** + * A compile-time known floating point number */ extern (C++) final class RealExp : Expression { @@ -2127,6 +2132,7 @@ extern (C++) final class RealExp : Expression } /*********************************************************** + * A compile-time complex number (deprecated) */ extern (C++) final class ComplexExp : Expression { @@ -2202,6 +2208,12 @@ extern (C++) final class ComplexExp : Expression } /*********************************************************** + * An identifier in the context of an expression (as opposed to a declaration) + * + * --- + * int x; // VarDeclaration with Identifier + * x++; // PostExp with IdentifierExp + * --- */ extern (C++) class IdentifierExp : Expression { @@ -2235,6 +2247,9 @@ extern (C++) class IdentifierExp : Expression } /*********************************************************** + * The dollar operator used when indexing or slicing an array. E.g `a[$]`, `a[1 .. $]` etc. + * + * https://dlang.org/spec/arrays.html#array-length */ extern (C++) final class DollarExp : IdentifierExp { @@ -2353,6 +2368,8 @@ extern (C++) final class SuperExp : ThisExp } /*********************************************************** + * A compile-time known `null` value + * * https://dlang.org/spec/expression.html#null */ extern (C++) final class NullExp : Expression @@ -2791,6 +2808,12 @@ extern (C++) final class StringExp : Expression } /*********************************************************** + * A sequence of expressions + * + * --- + * alias AliasSeq(T...) = T; + * alias Tup = AliasSeq!(3, int, "abc"); + * --- */ extern (C++) final class TupleExp : Expression { @@ -4127,6 +4150,9 @@ extern (C++) final class TraitsExp : Expression } /*********************************************************** + * Generates a halt instruction + * + * `assert(0)` gets rewritten to this with `CHECKACTION.halt` */ extern (C++) final class HaltExp : Expression { @@ -4185,6 +4211,9 @@ extern (C++) final class IsExp : Expression } /*********************************************************** + * Base class for unary operators + * + * https://dlang.org/spec/expression.html#unary-expression */ extern (C++) abstract class UnaExp : Expression { @@ -4255,6 +4284,7 @@ alias fp_t = UnionExp function(const ref Loc loc, Type, Expression, Expression); alias fp2_t = bool function(const ref Loc loc, EXP, Expression, Expression); /*********************************************************** + * Base class for binary operators */ extern (C++) abstract class BinExp : Expression { @@ -4550,6 +4580,7 @@ extern (C++) abstract class BinExp : Expression } /*********************************************************** + * Binary operator assignment, `+=` `-=` `*=` etc. */ extern (C++) class BinAssignExp : BinExp { @@ -4582,6 +4613,8 @@ extern (C++) class BinAssignExp : BinExp } /*********************************************************** + * A string mixin, `mixin("x")` + * * https://dlang.org/spec/expression.html#mixin_expressions */ extern (C++) final class MixinExp : Expression @@ -4628,6 +4661,11 @@ extern (C++) final class MixinExp : Expression } /*********************************************************** + * An import expression, `import("file.txt")` + * + * Not to be confused with module imports, `import std.stdio`, which is an `ImportStatement` + * + * https://dlang.org/spec/expression.html#import_expressions */ extern (C++) final class ImportExp : UnaExp { @@ -4643,6 +4681,8 @@ extern (C++) final class ImportExp : UnaExp } /*********************************************************** + * An assert expression, `assert(x == y)` + * * https://dlang.org/spec/expression.html#assert_expressions */ extern (C++) final class AssertExp : UnaExp @@ -5153,6 +5193,7 @@ FuncDeclaration isFuncAddress(Expression e, bool* hasOverloads = null) } /*********************************************************** + * The 'address of' operator, `&p` */ extern (C++) final class AddrExp : UnaExp { @@ -5174,6 +5215,7 @@ extern (C++) final class AddrExp : UnaExp } /*********************************************************** + * The pointer dereference operator, `*p` */ extern (C++) final class PtrExp : UnaExp { @@ -5226,6 +5268,7 @@ extern (C++) final class PtrExp : UnaExp } /*********************************************************** + * The negation operator, `-x` */ extern (C++) final class NegExp : UnaExp { @@ -5241,6 +5284,7 @@ extern (C++) final class NegExp : UnaExp } /*********************************************************** + * The unary add operator, `+x` */ extern (C++) final class UAddExp : UnaExp { @@ -5256,6 +5300,7 @@ extern (C++) final class UAddExp : UnaExp } /*********************************************************** + * The bitwise complement operator, `~x` */ extern (C++) final class ComExp : UnaExp { @@ -5271,6 +5316,7 @@ extern (C++) final class ComExp : UnaExp } /*********************************************************** + * The logical not operator, `!x` */ extern (C++) final class NotExp : UnaExp { @@ -5286,6 +5332,9 @@ extern (C++) final class NotExp : UnaExp } /*********************************************************** + * The delete operator, `delete x` (deprecated) + * + * https://dlang.org/spec/expression.html#delete_expressions */ extern (C++) final class DeleteExp : UnaExp { @@ -5304,7 +5353,11 @@ extern (C++) final class DeleteExp : UnaExp } /*********************************************************** - * Possible to cast to one type while painting to another type + * The type cast operator, `cast(T) x` + * + * It's possible to cast to one type while painting to another type + * + * https://dlang.org/spec/expression.html#cast_expressions */ extern (C++) final class CastExp : UnaExp { @@ -5500,6 +5553,7 @@ extern (C++) final class SliceExp : UnaExp } /*********************************************************** + * The `.length` property of an array */ extern (C++) final class ArrayLengthExp : UnaExp { @@ -5684,6 +5738,11 @@ extern (C++) final class IntervalExp : Expression } } +/*********************************************************** + * The `dg.ptr` property, pointing to the delegate's 'context' + * + * c.f.`DelegateFuncptrExp` for the delegate's function pointer `dg.funcptr` + */ extern (C++) final class DelegatePtrExp : UnaExp { extern (D) this(const ref Loc loc, Expression e1) @@ -5719,6 +5778,9 @@ extern (C++) final class DelegatePtrExp : UnaExp } /*********************************************************** + * The `dg.funcptr` property, pointing to the delegate's function + * + * c.f.`DelegatePtrExp` for the delegate's function pointer `dg.ptr` */ extern (C++) final class DelegateFuncptrExp : UnaExp { @@ -5835,7 +5897,7 @@ extern (C++) final class IndexExp : BinExp } /*********************************************************** - * For both i++ and i-- + * The postfix increment/decrement operator, `i++` / `i--` */ extern (C++) final class PostExp : BinExp { @@ -5852,7 +5914,7 @@ extern (C++) final class PostExp : BinExp } /*********************************************************** - * For both ++i and --i + * The prefix increment/decrement operator, `++i` / `--i` */ extern (C++) final class PreExp : UnaExp { @@ -5876,6 +5938,9 @@ enum MemorySet } /*********************************************************** + * The assignment / initialization operator, `=` + * + * Note: operator assignment `op=` has a different base class, `BinAssignExp` */ extern (C++) class AssignExp : BinExp { @@ -5953,6 +6018,7 @@ extern (C++) final class ConstructExp : AssignExp } /*********************************************************** + * A bit-for-bit copy from `e2` to `e1` */ extern (C++) final class BlitExp : AssignExp { @@ -5981,6 +6047,7 @@ extern (C++) final class BlitExp : AssignExp } /*********************************************************** + * `x += y` */ extern (C++) final class AddAssignExp : BinAssignExp { @@ -5996,6 +6063,7 @@ extern (C++) final class AddAssignExp : BinAssignExp } /*********************************************************** + * `x -= y` */ extern (C++) final class MinAssignExp : BinAssignExp { @@ -6011,6 +6079,7 @@ extern (C++) final class MinAssignExp : BinAssignExp } /*********************************************************** + * `x *= y` */ extern (C++) final class MulAssignExp : BinAssignExp { @@ -6026,6 +6095,7 @@ extern (C++) final class MulAssignExp : BinAssignExp } /*********************************************************** + * `x /= y` */ extern (C++) final class DivAssignExp : BinAssignExp { @@ -6041,6 +6111,7 @@ extern (C++) final class DivAssignExp : BinAssignExp } /*********************************************************** + * `x %= y` */ extern (C++) final class ModAssignExp : BinAssignExp { @@ -6056,6 +6127,7 @@ extern (C++) final class ModAssignExp : BinAssignExp } /*********************************************************** + * `x &= y` */ extern (C++) final class AndAssignExp : BinAssignExp { @@ -6071,6 +6143,7 @@ extern (C++) final class AndAssignExp : BinAssignExp } /*********************************************************** + * `x |= y` */ extern (C++) final class OrAssignExp : BinAssignExp { @@ -6086,6 +6159,7 @@ extern (C++) final class OrAssignExp : BinAssignExp } /*********************************************************** + * `x ^= y` */ extern (C++) final class XorAssignExp : BinAssignExp { @@ -6101,6 +6175,7 @@ extern (C++) final class XorAssignExp : BinAssignExp } /*********************************************************** + * `x ^^= y` */ extern (C++) final class PowAssignExp : BinAssignExp { @@ -6116,6 +6191,7 @@ extern (C++) final class PowAssignExp : BinAssignExp } /*********************************************************** + * `x <<= y` */ extern (C++) final class ShlAssignExp : BinAssignExp { @@ -6131,6 +6207,7 @@ extern (C++) final class ShlAssignExp : BinAssignExp } /*********************************************************** + * `x >>= y` */ extern (C++) final class ShrAssignExp : BinAssignExp { @@ -6146,6 +6223,7 @@ extern (C++) final class ShrAssignExp : BinAssignExp } /*********************************************************** + * `x >>>= y` */ extern (C++) final class UshrAssignExp : BinAssignExp { @@ -6161,7 +6239,9 @@ extern (C++) final class UshrAssignExp : BinAssignExp } /*********************************************************** - * The ~= operator. It can have one of the following operators: + * The `~=` operator. + * + * It can have one of the following operators: * * EXP.concatenateAssign - appending T[] to T[] * EXP.concatenateElemAssign - appending T to T[] @@ -6188,7 +6268,9 @@ extern (C++) class CatAssignExp : BinAssignExp } } -/// +/*********************************************************** + * The `~=` operator when appending a single element + */ extern (C++) final class CatElemAssignExp : CatAssignExp { extern (D) this(const ref Loc loc, Type type, Expression e1, Expression e2) @@ -6203,7 +6285,9 @@ extern (C++) final class CatElemAssignExp : CatAssignExp } } -/// +/*********************************************************** + * The `~=` operator when appending a single `dchar` + */ extern (C++) final class CatDcharAssignExp : CatAssignExp { extern (D) this(const ref Loc loc, Type type, Expression e1, Expression e2) @@ -6219,6 +6303,8 @@ extern (C++) final class CatDcharAssignExp : CatAssignExp } /*********************************************************** + * The addition operator, `x + y` + * * https://dlang.org/spec/expression.html#add_expressions */ extern (C++) final class AddExp : BinExp @@ -6235,6 +6321,9 @@ extern (C++) final class AddExp : BinExp } /*********************************************************** + * The minus operator, `x - y` + * + * https://dlang.org/spec/expression.html#add_expressions */ extern (C++) final class MinExp : BinExp { @@ -6250,6 +6339,8 @@ extern (C++) final class MinExp : BinExp } /*********************************************************** + * The concatenation operator, `x ~ y` + * * https://dlang.org/spec/expression.html#cat_expressions */ extern (C++) final class CatExp : BinExp @@ -6273,6 +6364,8 @@ extern (C++) final class CatExp : BinExp } /*********************************************************** + * The multiplication operator, `x * y` + * * https://dlang.org/spec/expression.html#mul_expressions */ extern (C++) final class MulExp : BinExp @@ -6289,6 +6382,8 @@ extern (C++) final class MulExp : BinExp } /*********************************************************** + * The division operator, `x / y` + * * https://dlang.org/spec/expression.html#mul_expressions */ extern (C++) final class DivExp : BinExp @@ -6305,6 +6400,8 @@ extern (C++) final class DivExp : BinExp } /*********************************************************** + * The modulo operator, `x % y` + * * https://dlang.org/spec/expression.html#mul_expressions */ extern (C++) final class ModExp : BinExp @@ -6321,6 +6418,8 @@ extern (C++) final class ModExp : BinExp } /*********************************************************** + * The 'power' operator, `x ^^ y` + * * https://dlang.org/spec/expression.html#pow_expressions */ extern (C++) final class PowExp : BinExp @@ -6337,6 +6436,9 @@ extern (C++) final class PowExp : BinExp } /*********************************************************** + * The 'shift left' operator, `x << y` + * + * https://dlang.org/spec/expression.html#shift_expressions */ extern (C++) final class ShlExp : BinExp { @@ -6352,6 +6454,9 @@ extern (C++) final class ShlExp : BinExp } /*********************************************************** + * The 'shift right' operator, `x >> y` + * + * https://dlang.org/spec/expression.html#shift_expressions */ extern (C++) final class ShrExp : BinExp { @@ -6367,6 +6472,9 @@ extern (C++) final class ShrExp : BinExp } /*********************************************************** + * The 'unsigned shift right' operator, `x >>> y` + * + * https://dlang.org/spec/expression.html#shift_expressions */ extern (C++) final class UshrExp : BinExp { @@ -6382,6 +6490,9 @@ extern (C++) final class UshrExp : BinExp } /*********************************************************** + * The bitwise 'and' operator, `x & y` + * + * https://dlang.org/spec/expression.html#and_expressions */ extern (C++) final class AndExp : BinExp { @@ -6397,6 +6508,9 @@ extern (C++) final class AndExp : BinExp } /*********************************************************** + * The bitwise 'or' operator, `x | y` + * + * https://dlang.org/spec/expression.html#or_expressions */ extern (C++) final class OrExp : BinExp { @@ -6412,6 +6526,9 @@ extern (C++) final class OrExp : BinExp } /*********************************************************** + * The bitwise 'xor' operator, `x ^ y` + * + * https://dlang.org/spec/expression.html#xor_expressions */ extern (C++) final class XorExp : BinExp { @@ -6427,6 +6544,8 @@ extern (C++) final class XorExp : BinExp } /*********************************************************** + * The logical 'and' / 'or' operator, `X && Y` / `X || Y` + * * https://dlang.org/spec/expression.html#andand_expressions * https://dlang.org/spec/expression.html#oror_expressions */ @@ -6445,6 +6564,8 @@ extern (C++) final class LogicalExp : BinExp } /*********************************************************** + * A comparison operator, `<` `<=` `>` `>=` + * * `op` is one of: * EXP.lessThan, EXP.lessOrEqual, EXP.greaterThan, EXP.greaterOrEqual * @@ -6465,6 +6586,11 @@ extern (C++) final class CmpExp : BinExp } /*********************************************************** + * The `in` operator, `"a" in ["a": 1]` + * + * Note: `x !in y` is rewritten to `!(x in y)` in the parser + * + * https://dlang.org/spec/expression.html#in_expressions */ extern (C++) final class InExp : BinExp { @@ -6480,6 +6606,8 @@ extern (C++) final class InExp : BinExp } /*********************************************************** + * Associative array removal, `aa.remove(arg)` + * * This deletes the key e1 from the associative array e2 */ extern (C++) final class RemoveExp : BinExp @@ -6539,7 +6667,7 @@ extern (C++) final class IdentityExp : BinExp } /*********************************************************** - * `econd ? e1 : e2` + * The ternary operator, `econd ? e1 : e2` * * https://dlang.org/spec/expression.html#conditional_expressions */ @@ -6672,6 +6800,18 @@ bool isDefaultInitOp(EXP op) pure nothrow @safe @nogc } /*********************************************************** + * A special keyword when used as a function's default argument + * + * When possible, special keywords are resolved in the parser, but when + * appearing as a default argument, they result in an expression deriving + * from this base class that is resolved for each function call. + * + * --- + * const x = __LINE__; // resolved in the parser + * void foo(string file = __FILE__, int line = __LINE__); // DefaultInitExp + * --- + * + * https://dlang.org/spec/expression.html#specialkeywords */ extern (C++) class DefaultInitExp : Expression { @@ -6687,6 +6827,7 @@ extern (C++) class DefaultInitExp : Expression } /*********************************************************** + * The `__FILE__` token as a default argument */ extern (C++) final class FileInitExp : DefaultInitExp { @@ -6717,6 +6858,7 @@ extern (C++) final class FileInitExp : DefaultInitExp } /*********************************************************** + * The `__LINE__` token as a default argument */ extern (C++) final class LineInitExp : DefaultInitExp { @@ -6739,6 +6881,7 @@ extern (C++) final class LineInitExp : DefaultInitExp } /*********************************************************** + * The `__MODULE__` token as a default argument */ extern (C++) final class ModuleInitExp : DefaultInitExp { @@ -6763,6 +6906,7 @@ extern (C++) final class ModuleInitExp : DefaultInitExp } /*********************************************************** + * The `__FUNCTION__` token as a default argument */ extern (C++) final class FuncInitExp : DefaultInitExp { @@ -6793,6 +6937,7 @@ extern (C++) final class FuncInitExp : DefaultInitExp } /*********************************************************** + * The `__PRETTY_FUNCTION__` token as a default argument */ extern (C++) final class PrettyFuncInitExp : DefaultInitExp { diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d index 6377e9c7dea..965b3b45f87 100644 --- a/gcc/d/dmd/lexer.d +++ b/gcc/d/dmd/lexer.d @@ -79,6 +79,12 @@ class Lexer bool doDocComment; // collect doc comment information bool anyToken; // seen at least one token bool commentToken; // comments are TOK.comment's + + version (DMDLIB) + { + bool whitespaceToken; // tokenize whitespaces + } + int inTokenStringConstant; // can be larger than 1 when in nested q{} strings int lastDocLine; // last line of previous doc comment @@ -145,6 +151,31 @@ class Lexer } } + version (DMDLIB) + { + this(const(char)* filename, const(char)* base, size_t begoffset, size_t endoffset, + bool doDocComment, bool commentToken, bool whitespaceToken) + { + this(filename, base, begoffset, endoffset, doDocComment, commentToken); + this.whitespaceToken = whitespaceToken; + } + + bool empty() const pure @property @nogc @safe + { + return front() == TOK.endOfFile; + } + + TOK front() const pure @property @nogc @safe + { + return token.value; + } + + void popFront() + { + nextToken(); + } + } + /// Returns: a newly allocated `Token`. Token* allocateToken() pure nothrow @safe { @@ -237,20 +268,52 @@ class Lexer while (*p == ' ') p++; LendSkipFourSpaces: + version (DMDLIB) + { + if (whitespaceToken) + { + t.value = TOK.whitespace; + return; + } + } continue; // skip white space case '\t': case '\v': case '\f': p++; + version (DMDLIB) + { + if (whitespaceToken) + { + t.value = TOK.whitespace; + return; + } + } continue; // skip white space case '\r': p++; if (*p != '\n') // if CR stands by itself endOfLine(); + version (DMDLIB) + { + if (whitespaceToken) + { + t.value = TOK.whitespace; + return; + } + } continue; // skip white space case '\n': p++; endOfLine(); + version (DMDLIB) + { + if (whitespaceToken) + { + t.value = TOK.whitespace; + return; + } + } continue; // skip white space case '0': if (!isZeroSecond(p[1])) // if numeric literal does not continue @@ -594,8 +657,12 @@ class Lexer } if (commentToken) { - p++; - endOfLine(); + version (DMDLIB) {} + else + { + p++; + endOfLine(); + } t.loc = startLoc; t.value = TOK.comment; return; diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d index 3653aa8b06b..10c265f600b 100644 --- a/gcc/d/dmd/optimize.d +++ b/gcc/d/dmd/optimize.d @@ -469,10 +469,11 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) * Params: * e = the DotVarExp or VarExp * var = set to the VarExp at the end, or null if doesn't end in VarExp + * eint = set to the IntegerExp at the end, or null if doesn't end in IntegerExp * offset = accumulation of all the .var offsets encountered * Returns: true on error */ - static bool getVarAndOffset(Expression e, ref VarDeclaration var, ref uint offset) + static bool getVarAndOffset(Expression e, out VarDeclaration var, out IntegerExp eint, ref uint offset) { if (e.type.size() == SIZE_INVALID) // trigger computation of v.offset return true; @@ -483,7 +484,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) if (!v || !v.isField() || v.isBitFieldDeclaration()) return false; - if (getVarAndOffset(dve.e1, var, offset)) + if (getVarAndOffset(dve.e1, var, eint, offset)) return true; offset += v.offset; } @@ -497,12 +498,20 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) var = ve.var.isVarDeclaration(); } } + else if (auto ep = e.isPtrExp()) + { + if (auto ei = ep.e1.isIntegerExp()) + { + eint = ei; + } + } return false; } uint offset; VarDeclaration var; - if (getVarAndOffset(e.e1, var, offset)) + IntegerExp eint; + if (getVarAndOffset(e.e1, var, eint, offset)) { ret = ErrorExp.get(); return; @@ -513,6 +522,11 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) ret.type = e.type; return; } + if (eint) + { + ret = new IntegerExp(e.loc, eint.toInteger() + offset, e.type); + return; + } } if (auto ae = e.e1.isIndexExp()) { @@ -828,6 +842,7 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue) void visitMin(MinExp e) { + //printf("MinExp::optimize(%s)\n", e.toChars()); if (binOptimize(e, result)) return; if (e.e1.isConst() && e.e2.isConst()) diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d index 5dbe5b66d3e..88520e85c24 100644 --- a/gcc/d/dmd/statementsem.d +++ b/gcc/d/dmd/statementsem.d @@ -47,6 +47,7 @@ import dmd.globals; import dmd.gluelayer; import dmd.id; import dmd.identifier; +import dmd.importc; import dmd.init; import dmd.intrange; import dmd.mtype; @@ -2862,6 +2863,7 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor rs.exp = inferType(rs.exp, fld.treq.nextOf().nextOf()); rs.exp = rs.exp.expressionSemantic(sc); + rs.exp = rs.exp.arrayFuncConv(sc); // If we're returning by ref, allow the expression to be `shared` const returnSharedRef = (tf.isref && (fd.inferRetType || tret.isShared())); rs.exp.checkSharedAccess(sc, returnSharedRef); diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d index 9c24df06530..0b1d1583a55 100644 --- a/gcc/d/dmd/tokens.d +++ b/gcc/d/dmd/tokens.d @@ -246,6 +246,7 @@ enum TOK : ubyte arrow, // -> colonColon, // :: wchar_tLiteral, + whitespace, // C only keywords inline, @@ -851,6 +852,7 @@ extern (C++) struct Token TOK.wcharLiteral: "wcharv", TOK.dcharLiteral: "dcharv", TOK.wchar_tLiteral: "wchar_tv", + TOK.whitespace: "whitespace", TOK.hexadecimalString: "xstring", diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h index c23e0fb4a01..6dfd0ce3333 100644 --- a/gcc/d/dmd/tokens.h +++ b/gcc/d/dmd/tokens.h @@ -255,6 +255,7 @@ enum class TOK : unsigned char arrow, // -> colonColon, // :: wchar_tLiteral, + whitespace, // C only keywords inline_, diff --git a/gcc/testsuite/gdc.test/compilable/test21975.d b/gcc/testsuite/gdc.test/compilable/test21975.d new file mode 100644 index 00000000000..f840d4c5329 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test21975.d @@ -0,0 +1,15 @@ +// https://issues.dlang.org/show_bug.cgi?id=21975 + +struct Outer(T) +{ + Inner!T inner; + alias inner this; +} + +struct Inner(T) +{ + T t; +} + +static assert(is(Outer!int : Inner!int)); // ok +static assert(is(Outer!int : Inner!T, T)); // needs to compile diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp index ea4fb1c8a0e..4fa87efcfff 100644 --- a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp +++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cppb.cpp @@ -4,6 +4,30 @@ #include #include +#if _WIN32 // otherwise defined in C header files! +// https://issues.dlang.org/show_bug.cgi?id=18955 +namespace std +{ + template + struct char_traits + { + }; + template + class allocator + { + }; + template + class basic_string + { + }; + typedef basic_string, allocator > string; +} +#else // if POSIX + +#include + +#endif // _WIN32 + #include "cppb.h" /**************************************/ @@ -317,10 +341,9 @@ size_t getoffset13161a() /****************************************************/ -#if __linux__ || __APPLE__ || __FreeBSD__ || __DragonFly__ +#if __linux__ #include #include -#include #if __linux__ template struct std::allocator; @@ -903,26 +926,6 @@ void A18966::foo() { calledOverloads[i++] = 'A'; } B18966::B18966() { foo(); } void B18966::foo() { calledOverloads[i++] = 'B'; } -#if _WIN32 // otherwise defined in C header files! -// https://issues.dlang.org/show_bug.cgi?id=18955 -namespace std -{ - template - struct char_traits - { - }; - template - class allocator - { - }; - template - class basic_string - { - }; - typedef basic_string, allocator > string; -} -#endif // _WIN32 - void callback18955(const std::string& s); void test18955() diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index 7c0bb573e2b..c4b1538b3a4 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -caf14b0f4ebbae4157aac89368d6278332ee2aa1 +0316b981e5f2fa1525e893c5d94c59c847a8c386 The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/core/memory.d b/libphobos/libdruntime/core/memory.d index f25ba6f1d46..27c84e7f55e 100644 --- a/libphobos/libdruntime/core/memory.d +++ b/libphobos/libdruntime/core/memory.d @@ -1229,7 +1229,10 @@ void __delete(T)(ref T x) @system else static if (is(T == U*, U)) { static if (is(U == struct)) - _destructRecurse(*x); + { + if (x) + _destructRecurse(*x); + } } else static if (is(T : E[], E)) { @@ -1334,6 +1337,10 @@ unittest assert(a is null); assert(dtorCalled); assert(GC.addrOf(cast(void*) a) == null); + + // https://issues.dlang.org/show_bug.cgi?id=22779 + A *aptr; + __delete(aptr); } /// Deleting arrays diff --git a/libphobos/libdruntime/core/stdc/math.d b/libphobos/libdruntime/core/stdc/math.d index 0c5da0bfefa..0393ea52c07 100644 --- a/libphobos/libdruntime/core/stdc/math.d +++ b/libphobos/libdruntime/core/stdc/math.d @@ -90,6 +90,13 @@ else version (DragonFlyBSD) /// enum int FP_ILOGBNAN = int.max; } +else version (Solaris) +{ + /// + enum int FP_ILOGB0 = -int.max; + /// + enum int FP_ILOGBNAN = int.max; +} else version (CRuntime_Bionic) { /// @@ -1380,18 +1387,128 @@ else version (DragonFlyBSD) } else version (Solaris) { - pure int __isnanf(float x); - pure int __isnan(double x); - pure int __isnanl(real x); + enum + { + FP_INFINITE = 3, + FP_NAN = 4, + FP_NORMAL = 2, + FP_SUBNORMAL = 1, + FP_ZERO = 0, + } + + enum + { + /// + FP_FAST_FMA = 0, + /// + FP_FAST_FMAF = 0, + /// + FP_FAST_FMAL = 0, + } + + extern (D) + { + //int fpclassify(real-floating x); + /// + pure int fpclassify(float x) + { + return isnan(x) ? FP_NAN : isinf(x) ? FP_INFINITE : + isnormal(x) ? FP_NORMAL : x == 0.0f ? FP_ZERO : + FP_SUBNORMAL; + } + + /// + pure int fpclassify(double x) + { + return isnan(x) ? FP_NAN : isinf(x) ? FP_INFINITE : + isnormal(x) ? FP_NORMAL : x == 0.0 ? FP_ZERO : + FP_SUBNORMAL; + } + + /// + pure int fpclassify(real x) + { + return isnan(x) ? FP_NAN : isinf(x) ? FP_INFINITE : + isnormal(x) ? FP_NORMAL : x == 0.0L ? FP_ZERO : + FP_SUBNORMAL; + } + + //int isfinite(real-floating x); + /// + pure int isfinite(float x) { return !isnan(x) && !isinf(x); } + /// + pure int isfinite(double x) { return !isnan(x) && !isinf(x); } + /// + pure int isfinite(real x) { return !isnan(x) && !isinf(x); } + + //int isinf(real-floating x); + /// + pure int isinf(float x) { return x == float.infinity || x == -float.infinity; } + /// + pure int isinf(double x) { return x == double.infinity || x == -double.infinity; } + /// + pure int isinf(real x) { return x == real.infinity || x == -real.infinity; } //int isnan(real-floating x); - /// - pragma(mangle, "__isnanf") pure int isnan(float x); /// - pragma(mangle, "__isnan") pure int isnan(double x); + pure int isnan(float x) { return x != x; } /// - pragma(mangle, real.sizeof == double.sizeof ? "__isnan" : "__isnanl") - pure int isnan(real x); + pure int isnan(double x) { return x != x; } + /// + pure int isnan(real x) { return x != x; } + + //int isnormal(real-floating x); + /// + pure int isnormal(float x) + { + import core.math; + return isfinite(x) && fabs(x) >= float.min_normal; + } + /// + pure int isnormal(double x) + { + import core.math; + return isfinite(x) && fabs(x) >= double.min_normal; + } + /// + pure int isnormal(real x) + { + import core.math; + return isfinite(x) && fabs(x) >= real.min_normal; + } + + //int signbit(real-floating x); + /// + pure int signbit(float x) + { + version (SPARC_Any) + return cast(int)(*cast(uint*)&x >> 31); + else version (X86_Any) + return cast(int)(*cast(uint*)&x >> 31); + else + static assert(false, "Architecture not supported."); + } + /// + pure int signbit(double x) + { + version (SPARC_Any) + return cast(int)(*cast(uint*)&x >> 31); + else version (X86_Any) + return cast(int)((cast(uint*)&x)[1] >> 31); + else + static assert(false, "Architecture not supported."); + } + /// + pure int signbit(real x) + { + version (SPARC_Any) + return cast(int)(*cast(uint*)&x >> 31); + else version (X86_Any) + return cast(int)((cast(ushort *)&x)[4] >> 15); + else + static assert(false, "Architecture not supported."); + } + } } else version (CRuntime_Bionic) { diff --git a/libphobos/libdruntime/core/stdc/stdio.d b/libphobos/libdruntime/core/stdc/stdio.d index 0dcdb6efc26..cd53f0ab50b 100644 --- a/libphobos/libdruntime/core/stdc/stdio.d +++ b/libphobos/libdruntime/core/stdc/stdio.d @@ -983,7 +983,7 @@ else version (NetBSD) _IONBF = 2, } - private extern __gshared FILE[3] __sF; + private extern shared FILE[3] __sF; @property auto __stdin()() { return &__sF[0]; } @property auto __stdout()() { return &__sF[1]; } @property auto __stderr()() { return &__sF[2]; } @@ -1006,7 +1006,7 @@ else version (OpenBSD) _IONBF = 2, } - private extern __gshared FILE[3] __sF; + private extern shared FILE[3] __sF; @property auto __stdin()() { return &__sF[0]; } @property auto __stdout()() { return &__sF[1]; } @property auto __stderr()() { return &__sF[2]; } @@ -1061,11 +1061,11 @@ else version (Solaris) private extern shared FILE[_NFILE] __iob; /// - shared stdin = &__iob[0]; + @property auto stdin()() { return &__iob[0]; } /// - shared stdout = &__iob[1]; + @property auto stdout()() { return &__iob[1]; } /// - shared stderr = &__iob[2]; + @property auto stderr()() { return &__iob[2]; } } else version (CRuntime_Bionic) { @@ -1082,11 +1082,11 @@ else version (CRuntime_Bionic) private extern shared FILE[3] __sF; /// - shared stdin = &__sF[0]; + @property auto stdin()() { return &__sF[0]; } /// - shared stdout = &__sF[1]; + @property auto stdout()() { return &__sF[1]; } /// - shared stderr = &__sF[2]; + @property auto stderr()() { return &__sF[2]; } } else version (CRuntime_Musl) { diff --git a/libphobos/libdruntime/core/stdcpp/exception.d b/libphobos/libdruntime/core/stdcpp/exception.d index d65cd8d1832..d5339964e36 100644 --- a/libphobos/libdruntime/core/stdcpp/exception.d +++ b/libphobos/libdruntime/core/stdcpp/exception.d @@ -69,7 +69,7 @@ version (GenericBaseException) { @nogc: /// - this() nothrow {} + extern(D) this() nothrow {} /// @weak ~this() nothrow {} // HACK: this should extern, but then we have link errors! @@ -77,7 +77,7 @@ version (GenericBaseException) @weak const(char)* what() const nothrow { return "unknown"; } // HACK: this should extern, but then we have link errors! protected: - this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes + extern(D) this(const(char)*, int = 1) nothrow { this(); } // compat with MS derived classes } } else version (CppRuntime_DigitalMars) @@ -87,7 +87,7 @@ else version (CppRuntime_DigitalMars) { @nogc: /// - this() nothrow {} + extern(D) this() nothrow {} //virtual ~this(); void dtor() { } // reserve slot in vtbl[] @@ -105,7 +105,7 @@ else version (CppRuntime_Microsoft) { @nogc: /// - this(const(char)* message = "unknown", int = 1) nothrow { msg = message; } + extern(D) this(const(char)* message = "unknown", int = 1) nothrow { msg = message; } /// @weak ~this() nothrow {} @@ -131,7 +131,7 @@ class bad_exception : exception { @nogc: /// - this(const(char)* message = "bad exception") { super(message); } + extern(D) this(const(char)* message = "bad exception") nothrow { super(message); } version (GenericBaseException) { diff --git a/libphobos/libdruntime/core/stdcpp/typeinfo.d b/libphobos/libdruntime/core/stdcpp/typeinfo.d index 53b25c5e9a5..24f2938ccab 100644 --- a/libphobos/libdruntime/core/stdcpp/typeinfo.d +++ b/libphobos/libdruntime/core/stdcpp/typeinfo.d @@ -18,10 +18,10 @@ version (CppRuntime_DigitalMars) import core.stdcpp.exception; extern (C++, "std"): - @nogc: class type_info { + @nogc: void* pdata; public: @@ -41,8 +41,9 @@ version (CppRuntime_DigitalMars) class bad_cast : exception { - this() nothrow { } - this(const bad_cast) nothrow { } + @nogc: + extern(D) this() nothrow { } + extern(D) this(const bad_cast) nothrow { } //bad_cast operator=(const bad_cast) nothrow { return this; } //virtual ~this() nothrow; override const(char)* what() const nothrow; @@ -50,8 +51,9 @@ version (CppRuntime_DigitalMars) class bad_typeid : exception { - this() nothrow { } - this(const bad_typeid) nothrow { } + @nogc: + extern(D) this() nothrow { } + extern(D) this(const bad_typeid) nothrow { } //bad_typeid operator=(const bad_typeid) nothrow { return this; } //virtual ~this() nothrow; override const (char)* what() const nothrow; @@ -62,7 +64,6 @@ else version (CppRuntime_Microsoft) import core.stdcpp.exception; extern (C++, "std"): - @nogc: struct __type_info_node { @@ -74,6 +75,7 @@ else version (CppRuntime_Microsoft) class type_info { + @nogc: @weak ~this() nothrow {} //bool operator==(const type_info rhs) const; //bool operator!=(const type_info rhs) const; @@ -88,13 +90,15 @@ else version (CppRuntime_Microsoft) class bad_cast : exception { - this(const(char)* msg = "bad cast") @nogc nothrow { super(msg); } + @nogc: + extern(D) this(const(char)* msg = "bad cast") nothrow { super(msg); } //virtual ~this(); } class bad_typeid : exception { - this(const(char)* msg = "bad typeid") @nogc nothrow { super(msg); } + @nogc: + extern(D) this(const(char)* msg = "bad typeid") nothrow { super(msg); } //virtual ~this(); } } @@ -108,10 +112,10 @@ else version (CppRuntime_Gcc) } extern (C++, "std"): - @nogc: abstract class type_info { + @nogc: @weak ~this() {} @weak final const(char)* name() const nothrow { @@ -133,19 +137,21 @@ else version (CppRuntime_Gcc) protected: const(char)* _name; - this(const(char)* name) { _name = name; } + extern(D) this(const(char)* name) { _name = name; } } class bad_cast : exception { - this() nothrow {} + @nogc: + extern(D) this() nothrow {} //~this(); @weak override const(char)* what() const nothrow { return "bad cast"; } } class bad_typeid : exception { - this() nothrow {} + @nogc: + extern(D) this() nothrow {} //~this(); @weak override const(char)* what() const nothrow { return "bad typeid"; } } @@ -155,10 +161,10 @@ else version (CppRuntime_Clang) import core.stdcpp.exception; extern (C++, "std"): - @nogc: abstract class type_info { + @nogc: @weak ~this() {} @weak final const(char)* name() const nothrow { @@ -173,19 +179,21 @@ else version (CppRuntime_Clang) protected: const(char)* __type_name; - this(const(char)* __n) { __type_name = __n; } + extern(D) this(const(char)* __n) { __type_name = __n; } } class bad_cast : exception { - this() nothrow {} + @nogc: + extern(D) this() nothrow {} //~this(); @weak override const(char)* what() const nothrow { return "bad cast"; } } class bad_typeid : exception { - this() nothrow {} + @nogc: + extern(D) this() nothrow {} //~this(); @weak override const(char)* what() const nothrow { return "bad typeid"; } } diff --git a/libphobos/libdruntime/core/sys/posix/locale.d b/libphobos/libdruntime/core/sys/posix/locale.d index 18558a2696a..85e2fb66915 100644 --- a/libphobos/libdruntime/core/sys/posix/locale.d +++ b/libphobos/libdruntime/core/sys/posix/locale.d @@ -31,7 +31,7 @@ version (FreeBSD) version = DarwinBSDLocale; version (NetBSD) version = DarwinBSDLocale; -version (DragonflyBSD) +version (DragonFlyBSD) version = DarwinBSDLocale; version (CRuntime_Glibc) diff --git a/libphobos/libdruntime/object.d b/libphobos/libdruntime/object.d index 56a2efe735a..a15616c6e0f 100644 --- a/libphobos/libdruntime/object.d +++ b/libphobos/libdruntime/object.d @@ -4445,7 +4445,11 @@ void destroy(bool initialize = true, T)(T obj) if (is(T == class)) } } else - rt_finalize(cast(void*)obj); + { + // Bypass overloaded opCast + auto ptr = (() @trusted => *cast(void**) &obj)(); + rt_finalize(ptr); + } } /// ditto @@ -4707,6 +4711,18 @@ nothrow unittest assert(C.dtorCount == 1); } +// https://issues.dlang.org/show_bug.cgi?id=22832 +nothrow unittest +{ + static struct A {} + static class B + { + A opCast(T : A)() { return A(); } + } + + destroy(B.init); +} + /// ditto void destroy(bool initialize = true, T)(ref T obj) if (__traits(isStaticArray, T)) diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index e15541e181d..5fd357c534a 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -41aaf8c2636df0e2e3ad39933b321d2b4cd231fa +a1f8c4c0700ce4e256f4130ad7883c6ea3890901 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/datetime/systime.d b/libphobos/src/std/datetime/systime.d index 9b2a8443fdd..db325f727e8 100644 --- a/libphobos/src/std/datetime/systime.d +++ b/libphobos/src/std/datetime/systime.d @@ -8713,13 +8713,14 @@ public: /++ Creates a $(LREF SysTime) from a string with the format - YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds is the time - zone). Whitespace is stripped from the given string. + YYYYMMDDTHHMMSS.FFFFFFFTZ (where F is fractional seconds and TZ + is the time zone). Whitespace is stripped from the given string. - The exact format is exactly as described in `toISOString` except that - trailing zeroes are permitted - including having fractional seconds with - all zeroes. However, a decimal point with nothing following it is - invalid. Also, while $(LREF toISOString) will never generate a string + The exact format is exactly as described in $(LREF toISOString) except + that trailing zeroes are permitted - including having fractional seconds + with all zeroes. The time zone and fractional seconds are optional, + however, a decimal point with nothing following it is invalid. + Also, while $(LREF toISOString) will never generate a string with more than 7 digits in the fractional seconds (because that's the limit with hecto-nanosecond precision), it will allow more than 7 digits in order to read strings from other sources that have higher precision @@ -9024,13 +9025,14 @@ public: /++ Creates a $(LREF SysTime) from a string with the format - YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the - time zone). Whitespace is stripped from the given string. + YYYY-MM-DDTHH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ + is the time zone). Whitespace is stripped from the given string. - The exact format is exactly as described in `toISOExtString` + The exact format is exactly as described in $(LREF toISOExtString) except that trailing zeroes are permitted - including having fractional - seconds with all zeroes. However, a decimal point with nothing following - it is invalid. Also, while $(LREF toISOExtString) will never generate a + seconds with all zeroes. The time zone and fractional seconds are + optional, however, a decimal point with nothing following it is invalid. + Also, while $(LREF toISOExtString) will never generate a string with more than 7 digits in the fractional seconds (because that's the limit with hecto-nanosecond precision), it will allow more than 7 digits in order to read strings from other sources that have higher @@ -9273,13 +9275,14 @@ public: /++ Creates a $(LREF SysTime) from a string with the format - YYYY-MM-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds is the - time zone). Whitespace is stripped from the given string. + YYYY-Mon-DD HH:MM:SS.FFFFFFFTZ (where F is fractional seconds and TZ + is the time zone). Whitespace is stripped from the given string. - The exact format is exactly as described in `toSimpleString` except + The exact format is exactly as described in $(LREF toSimpleString) except that trailing zeroes are permitted - including having fractional seconds - with all zeroes. However, a decimal point with nothing following it is - invalid. Also, while $(LREF toSimpleString) will never generate a + with all zeroes. The time zone and fractional seconds are optional, + however, a decimal point with nothing following it is invalid. + Also, while $(LREF toSimpleString) will never generate a string with more than 7 digits in the fractional seconds (because that's the limit with hecto-nanosecond precision), it will allow more than 7 digits in order to read strings from other sources that have higher diff --git a/libphobos/src/std/sumtype.d b/libphobos/src/std/sumtype.d index 0dd636ea67b..3833c84243c 100644 --- a/libphobos/src/std/sumtype.d +++ b/libphobos/src/std/sumtype.d @@ -1569,27 +1569,7 @@ private enum bool isSumTypeInstance(T) = is(T == SumType!Args, Args...); } /// True if `T` is a [SumType] or implicitly converts to one, otherwise false. -template isSumType(T) -{ - static if (is(T : SumType!Args, Args...)) - { - enum isSumType = true; - } - else static if (is(T == struct) && __traits(getAliasThis, T).length > 0) - { - // Workaround for https://issues.dlang.org/show_bug.cgi?id=21975 - import std.traits : ReturnType; - - alias AliasThisType = ReturnType!((T t) => - __traits(getMember, t, __traits(getAliasThis, T)[0]) - ); - enum isSumType = .isSumType!AliasThisType; - } - else - { - enum isSumType = false; - } -} +enum bool isSumType(T) = is(T : SumType!Args, Args...); /// @safe unittest @@ -1610,25 +1590,6 @@ template isSumType(T) assert(!isSumType!ContainsSumType); } -@safe unittest -{ - static struct AliasThisVar(T) - { - SumType!T payload; - alias payload this; - } - - static struct AliasThisFunc(T) - { - SumType!T payload; - ref get() { return payload; } - alias get this; - } - - static assert(isSumType!(AliasThisVar!int)); - static assert(isSumType!(AliasThisFunc!int)); -} - /** * Calls a type-appropriate function with the value held in a [SumType]. *