diff mbox series

[committed] d: Merge upstream dmd 423f19b41, druntime 100a608c, phobos a1f8c4c07.

Message ID 20220302172604.1111746-1-ibuclaw@gdcproject.org
State New
Headers show
Series [committed] d: Merge upstream dmd 423f19b41, druntime 100a608c, phobos a1f8c4c07. | expand

Commit Message

Iain Buclaw March 2, 2022, 5:26 p.m. UTC
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 mbox series

Patch

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 <exception>
 #include <cstdarg>
 
+#if _WIN32 // otherwise defined in C header files!
+// https://issues.dlang.org/show_bug.cgi?id=18955
+namespace std
+{
+    template<typename Char>
+    struct char_traits
+    {
+    };
+    template<typename Char>
+    class allocator
+    {
+    };
+    template<typename Char, typename Traits, typename Alloc>
+    class basic_string
+    {
+    };
+    typedef basic_string<char, char_traits<char>, allocator<char> > string;
+}
+#else // if POSIX
+
+#include <string>
+
+#endif // _WIN32
+
 #include "cppb.h"
 
 /**************************************/
@@ -317,10 +341,9 @@  size_t getoffset13161a()
 
 /****************************************************/
 
-#if __linux__ || __APPLE__ || __FreeBSD__ || __DragonFly__
+#if __linux__
 #include <memory>
 #include <vector>
-#include <string>
 
 #if __linux__
 template struct std::allocator<int>;
@@ -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<typename Char>
-    struct char_traits
-    {
-    };
-    template<typename Char>
-    class allocator
-    {
-    };
-    template<typename Char, typename Traits, typename Alloc>
-    class basic_string
-    {
-    };
-    typedef basic_string<char, char_traits<char>, allocator<char> > 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].
  *