[committed,2/4] d: Merge upstream dmd testsuite 568496d5b

Message ID 20211208235721.3254924-1-ibuclaw@gdcproject.org
State Committed
Headers
Series [committed,1/4] d: Merge upstream dmd 568496d5b |

Commit Message

Iain Buclaw Dec. 8, 2021, 11:57 p.m. UTC
  Hi,

This patch merges the D2 testsuite upstream dmd 568496d5b.

Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and
committed to mainline.

Regards,
Iain.

---
gcc/d/ChangeLog:

	* dmd/MERGE: Merge upstream dmd 568496d5b.
---
 gcc/testsuite/gdc.test/compilable/b19294.d    |  69 ++
 gcc/testsuite/gdc.test/compilable/cdcmp.d     |   2 +-
 .../compilable/ddoc_markdown_tables_22285.d   |  15 +
 .../gdc.test/compilable/dtoh_ignored.d        |   5 +-
 .../gdc.test/compilable/imports/cstuff3.c     |   6 -
 .../gdc.test/compilable/mixintype2.d          |  49 ++
 gcc/testsuite/gdc.test/compilable/noreturn1.d |  49 +-
 .../gdc.test/compilable/previewall.d          |  10 -
 .../gdc.test/compilable/reinterpretctfe.d     |  14 +
 gcc/testsuite/gdc.test/compilable/sroa.d      |  55 ++
 .../gdc.test/compilable/stc_traits.d          | 172 ++++
 gcc/testsuite/gdc.test/compilable/test15711.d |  31 +
 gcc/testsuite/gdc.test/compilable/test16492.d |  87 --
 gcc/testsuite/gdc.test/compilable/test19482.d |  68 ++
 gcc/testsuite/gdc.test/compilable/test21438.d |  15 +
 gcc/testsuite/gdc.test/compilable/test21794.d |  52 ++
 gcc/testsuite/gdc.test/compilable/test21850.d |  35 +
 gcc/testsuite/gdc.test/compilable/test22214.d |  16 +
 gcc/testsuite/gdc.test/compilable/test22224.d |   4 +
 gcc/testsuite/gdc.test/compilable/test22228.d |  11 +
 gcc/testsuite/gdc.test/compilable/test22292.d | 155 ++++
 gcc/testsuite/gdc.test/compilable/test22388.d |  22 +
 gcc/testsuite/gdc.test/compilable/test22410.d |  59 ++
 gcc/testsuite/gdc.test/compilable/test22420.d |  88 +++
 gcc/testsuite/gdc.test/compilable/test22421.d |  19 +
 gcc/testsuite/gdc.test/compilable/test318.d   |  19 +
 gcc/testsuite/gdc.test/compilable/test4090.d  |  17 -
 gcc/testsuite/gdc.test/compilable/test9766.d  |   4 +-
 .../gdc.test/compilable/testcstuff3.d         |   4 -
 .../gdc.test/compilable/transition_in.d       |  26 +
 gcc/testsuite/gdc.test/compilable/zerosize.d  |  13 +-
 .../gdc.test/fail_compilation/diag10327.d     |   3 +-
 .../gdc.test/fail_compilation/diag20059.d     |   2 +-
 .../gdc.test/fail_compilation/fail20618.d     |  16 +
 .../gdc.test/fail_compilation/fail21091a.d    |   3 +-
 .../gdc.test/fail_compilation/fail21091b.d    |   3 +-
 .../gdc.test/fail_compilation/fail22084.d     |   2 +-
 .../gdc.test/fail_compilation/fail22151.d     |  24 +
 .../gdc.test/fail_compilation/fail22366.d     |  15 +
 .../gdc.test/fail_compilation/fail225.d       |  17 -
 .../gdc.test/fail_compilation/fail287.d       |   2 +-
 .../gdc.test/fail_compilation/fail318.d       |   8 -
 .../gdc.test/fail_compilation/fail318_b.d     |  11 +
 .../gdc.test/fail_compilation/fail7173.d      |   2 +-
 .../gdc.test/fail_compilation/foreach.d       |  14 +
 .../gdc.test/fail_compilation/foreach2.d      |  22 +
 .../gdc.test/fail_compilation/ice10212.d      |   2 +-
 .../gdc.test/fail_compilation/ice22377.d      |   8 +
 .../gdc.test/fail_compilation/ice7782.d       |   3 +-
 .../fail_compilation/imports/imp22329.d       |   4 +
 .../gdc.test/fail_compilation/noreturn.d      |   2 +-
 .../gdc.test/fail_compilation/noreturn2.d     |  90 +++
 .../fail_compilation/reserved_version.d       |   6 +
 .../reserved_version_switch.d                 |   6 +
 .../gdc.test/fail_compilation/test17425.d     |   2 +-
 .../gdc.test/fail_compilation/test17868b.d    |   2 +-
 .../gdc.test/fail_compilation/test20998.d     | 120 +++
 .../gdc.test/fail_compilation/test21093.d     |  56 ++
 .../gdc.test/fail_compilation/test21380.d     |  46 ++
 .../gdc.test/fail_compilation/test21930.d     |  27 +
 .../gdc.test/fail_compilation/test22329.d     |  21 +
 .../gdc.test/fail_compilation/test22361.d     |  11 +
 .../gdc.test/fail_compilation/testOpApply.d   | 161 ++++
 gcc/testsuite/gdc.test/runnable/aliasthis.d   |  36 +
 gcc/testsuite/gdc.test/runnable/dhry.d        |  16 +
 gcc/testsuite/gdc.test/runnable/fix22372.d    |  38 +
 gcc/testsuite/gdc.test/runnable/interpret.d   |  57 ++
 gcc/testsuite/gdc.test/runnable/noreturn1.d   |  47 ++
 gcc/testsuite/gdc.test/runnable/noreturn2.d   | 220 ++++++
 gcc/testsuite/gdc.test/runnable/sroa13220.d   | 103 +++
 gcc/testsuite/gdc.test/runnable/test15624.d   |  51 --
 gcc/testsuite/gdc.test/runnable/test21039.d   |  27 +
 gcc/testsuite/gdc.test/runnable/test22205.d   |  17 +
 gcc/testsuite/gdc.test/runnable/test22278.d   |  24 +
 gcc/testsuite/gdc.test/runnable/testOpApply.d | 142 ++++
 gcc/testsuite/gdc.test/runnable/testmainb.d   |  15 +
 gcc/testsuite/gdc.test/runnable/uda.d         |  48 ++
 gcc/testsuite/gdc.test/runnable/ufcs.d        |   1 +
 .../runnable_cxx/extra-files/cpp22287.cpp     | 337 ++++++++
 .../gdc.test/runnable_cxx/test22287.d         | 327 ++++++++
 80 files changed, 3187 insertions(+), 221 deletions(-)
 create mode 100644 gcc/testsuite/gdc.test/compilable/b19294.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/ddoc_markdown_tables_22285.d
 delete mode 100644 gcc/testsuite/gdc.test/compilable/imports/cstuff3.c
 delete mode 100644 gcc/testsuite/gdc.test/compilable/previewall.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/sroa.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/stc_traits.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test15711.d
 delete mode 100644 gcc/testsuite/gdc.test/compilable/test16492.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test19482.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test21438.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test21794.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test21850.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22214.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22224.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22228.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22292.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22388.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22410.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22420.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test22421.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/test318.d
 delete mode 100644 gcc/testsuite/gdc.test/compilable/testcstuff3.d
 create mode 100644 gcc/testsuite/gdc.test/compilable/transition_in.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail20618.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail22151.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail22366.d
 delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail225.d
 delete mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail318.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/fail318_b.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/foreach.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/foreach2.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/ice22377.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/imports/imp22329.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/noreturn2.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test20998.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test21093.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test21380.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test21930.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test22329.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/test22361.d
 create mode 100644 gcc/testsuite/gdc.test/fail_compilation/testOpApply.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/fix22372.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/noreturn2.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/sroa13220.d
 delete mode 100644 gcc/testsuite/gdc.test/runnable/test15624.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/test21039.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/test22205.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/test22278.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/testOpApply.d
 create mode 100644 gcc/testsuite/gdc.test/runnable/testmainb.d
 create mode 100644 gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp22287.cpp
 create mode 100644 gcc/testsuite/gdc.test/runnable_cxx/test22287.d
  

Patch

diff --git a/gcc/testsuite/gdc.test/compilable/b19294.d b/gcc/testsuite/gdc.test/compilable/b19294.d
new file mode 100644
index 00000000000..063a9df152a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/b19294.d
@@ -0,0 +1,69 @@ 
+alias MT = MyStruct!int;
+
+struct MyStruct(T)
+{
+    T x;
+
+    this(T y)
+    {
+        x = y;
+    }
+
+    MyStruct!T opBinary(string op)(MyStruct!T y) const
+    {
+        alias C = typeof(return);
+        auto w = C(this.x);
+        return w.opOpAssign!(op)(y);
+    }
+
+    MyStruct!T opBinaryRight(string op)(MyStruct!T y) const
+    {
+        return opBinary!(op)(y);
+    }
+
+    ref MyStruct opOpAssign(string op, T)(const MyStruct!T z)
+    {
+        mixin ("x "~op~"= z.x;");
+        return this;
+    }
+
+    MyStruct!T opBinary(string op)(T y) const
+    {
+        alias C = typeof(return);
+        auto w = C(this.x);
+        return w.opOpAssign!(op)(y);
+    }
+
+    MyStruct!T opBinaryRight(string op)(T y) const
+    {
+        return opBinary!(op)(y);
+    }
+
+    ref MyStruct opOpAssign(string op, T)(const T z)
+    {
+        mixin ("x "~op~"= z;");
+        return this;
+    }
+}
+
+void test()
+{
+    MT s = MyStruct!int(1);
+    MT[] arr = [s, 2 * s, 3 * s, 4 * s, 5 * s, 6 * s];
+    MT[] result = new MT[arr.length];
+    
+    result[] = arr[] + s;
+    result[] = s + arr[];
+    
+    result[] = arr[] - s;
+    result[] = s - arr[];
+    
+    result[] = arr[] * s;
+    result[] = s * arr[];
+    
+    result[] = arr[] / s;
+    result[] = s / arr[];
+    
+    result[] = arr[] ^^ s;
+    result[] = s ^^ arr[];
+}
diff --git a/gcc/testsuite/gdc.test/compilable/cdcmp.d b/gcc/testsuite/gdc.test/compilable/cdcmp.d
index 614bdc8c984..42488186717 100644
--- a/gcc/testsuite/gdc.test/compilable/cdcmp.d
+++ b/gcc/testsuite/gdc.test/compilable/cdcmp.d
@@ -2,7 +2,7 @@ 
 // REQUIRED_ARGS: -O
 // POST_SCRIPT: compilable/extra-files/objdump-postscript.sh
 // only testing on SYSV-ABI, but backend code is identical across platforms
-// DISABLED: win32 win64 osx linux32 freebsd32 freebsd64
+// DISABLED: win32 win64 osx linux32 freebsd32 freebsd64 openbsd32 openbsd64
 
 bool test_ltz(ubyte x) { return x <  0; }
 bool test_lez(ubyte x) { return x <= 0; }
diff --git a/gcc/testsuite/gdc.test/compilable/ddoc_markdown_tables_22285.d b/gcc/testsuite/gdc.test/compilable/ddoc_markdown_tables_22285.d
new file mode 100644
index 00000000000..5e8836d78ad
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/ddoc_markdown_tables_22285.d
@@ -0,0 +1,15 @@ 
+// PERMUTE_ARGS:
+// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-
+// TEST_OUTPUT_FILE: extra-files/ddoc_markdown_tables_22285.html
+// OUTPUT_FILES: ${RESULTS_DIR}/compilable/ddoc_markdown_tables_22285.html
+
+module test.compilable.ddoc_markdown_tables_22285;
+
+/**
+| A | B | C |
+|---|---|---|
+| a | 0 |   |
+| b | 1 1 1   |              |
+| c | 2 |   |
+*/
+enum _ = 0;
diff --git a/gcc/testsuite/gdc.test/compilable/dtoh_ignored.d b/gcc/testsuite/gdc.test/compilable/dtoh_ignored.d
index 54bbc79bf46..47c0172009d 100644
--- a/gcc/testsuite/gdc.test/compilable/dtoh_ignored.d
+++ b/gcc/testsuite/gdc.test/compilable/dtoh_ignored.d
@@ -144,4 +144,7 @@  __gshared void function(ifloat) onVariableFunctionParam;
 
 __gshared ifloat delegate() onVariableDelegate;
 
-noreturn myExit() {}
+noreturn myExit()
+{
+    assert(false);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c b/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c
deleted file mode 100644
index f6aaf3b2a4a..00000000000
--- a/gcc/testsuite/gdc.test/compilable/imports/cstuff3.c
+++ /dev/null
@@ -1,6 +0,0 @@ 
-// check bugs in importing C files
-
-int squared(int a)
-{
-    return a * a;
-}
diff --git a/gcc/testsuite/gdc.test/compilable/mixintype2.d b/gcc/testsuite/gdc.test/compilable/mixintype2.d
index 43803df12cf..d160bd410ad 100644
--- a/gcc/testsuite/gdc.test/compilable/mixintype2.d
+++ b/gcc/testsuite/gdc.test/compilable/mixintype2.d
@@ -66,3 +66,52 @@  static assert(is(T8 == const(ubyte*)));
 alias T8 = mixin(q{immutable(__traits(getMember, S, "T"))})*;
 static assert(is(T8 == immutable(float*)*));
 */
+
+/**************************************************/
+// https://issues.dlang.org/show_bug.cgi?id=22356
+
+mixin("void") func22356(int) { }
+static assert(is(typeof(&func22356) == void function(int)));
+
+static mixin("void") func22356_s(char) { }
+static assert(is(typeof(&func22356_s) == void function(char)));
+
+mixin("int")[2] func22356_2(int) { return [1, 2]; }
+static assert(is(typeof(&func22356_2) == int[2] function(int)));
+
+mixin("int") func22356tp(S, T)(S, T) { return 1; }
+static assert(is(typeof(&func22356tp!(char, float)) == int function(char, float) pure nothrow @nogc @safe));
+
+mixin("int") x22356;
+static assert(is(typeof(x22356) == int));
+
+mixin("int")** xpp22356;
+static assert(is(typeof(xpp22356) == int**));
+
+mixin("int") y22356, z22356;
+static assert(is(typeof(y22356) == int) && is(typeof(z22356) == int));
+
+// Already working but for completeness
+void test_statements_22356()
+{
+    mixin("void") func22356(int) { }
+    static assert(is(typeof(&func22356) == void delegate(int) pure nothrow @nogc @safe));
+
+    static mixin("void") func22356_s(char) { }
+    static assert(is(typeof(&func22356_s) == void function(char) pure nothrow @nogc @safe));
+
+    mixin("int")[2] func22356_2(int) { return [1, 2]; }
+    static assert(is(typeof(&func22356_2) == int[2] delegate(int) pure nothrow @nogc @safe));
+
+    mixin("int") func22356tp(S, T)(S, T) { return 1; }
+    static assert(is(typeof(&func22356tp!(char, float)) == int delegate(char, float) pure nothrow @nogc @safe));
+
+    mixin("int") x22356;
+    static assert(is(typeof(x22356) == int));
+
+    mixin("int")** xpp22356;
+    static assert(is(typeof(xpp22356) == int**));
+
+    mixin("int") y22356, z22356;
+    static assert(is(typeof(y22356) == int) && is(typeof(z22356) == int));
+}
diff --git a/gcc/testsuite/gdc.test/compilable/noreturn1.d b/gcc/testsuite/gdc.test/compilable/noreturn1.d
index 7517bb26e0d..b041e072e9c 100644
--- a/gcc/testsuite/gdc.test/compilable/noreturn1.d
+++ b/gcc/testsuite/gdc.test/compilable/noreturn1.d
@@ -49,8 +49,17 @@  static assert(noreturn.alignof == 0);
 static assert((noreturn*).sizeof == (int*).sizeof);
 static assert((noreturn[]).sizeof == (int[]).sizeof);
 
+static assert(is(typeof(noreturn.init) == noreturn));
+static assert(is(typeof((const noreturn).init) == const noreturn));
+static assert(is(typeof((immutable noreturn).init) == immutable noreturn));
+static assert(is(typeof((shared noreturn).init) == shared noreturn));
+
 version (DigitalMars)
-    noreturn exits(int* p) { *p = 3; }
+    noreturn exits(int* p)
+    {
+        *p = 3;
+        assert(false); // *p could be valid
+    }
 
 noreturn exit();
 
@@ -58,9 +67,47 @@  noreturn pureexits() @nogc nothrow pure @safe { assert(0); }
 
 noreturn callpureexits() { pureexits(); }
 
+noreturn returnExits()
+{
+    return pureexits();
+}
+
+void alsoExits()
+{
+    return assert(0);
+}
+
+int thisAlsoExits()
+{
+    return assert(0);
+}
+
+void cast_()
+{
+    noreturn n;
+    int i = n;
+}
+
 int test1(int i)
 {
     if (exit())
         return i + 1;
     return i - 1;
 }
+
+noreturn tlsNoreturn;
+__gshared noreturn globalNoreturn;
+
+template CreateTLS(A)
+{
+    A a;
+}
+
+void* useTls()
+{
+    alias Tnr = CreateTLS!noreturn;
+    void* a1 = &Tnr.a;
+    void* a2 = &tlsNoreturn;
+    void* a3 = &globalNoreturn;
+    return a1 < a2 ? a2 : a3;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/previewall.d b/gcc/testsuite/gdc.test/compilable/previewall.d
deleted file mode 100644
index e5ed7a8bafb..00000000000
--- a/gcc/testsuite/gdc.test/compilable/previewall.d
+++ /dev/null
@@ -1,10 +0,0 @@ 
-// ARG_SETS: -preview=all
-// ARG_SETS: -transition=all
-// ARG_SETS: -revert=all
-import core.stdc.stdio;
-
-void main (string[] args)
-{
-    if (args.length == 42)
-        printf("Hello World\n");
-}
diff --git a/gcc/testsuite/gdc.test/compilable/reinterpretctfe.d b/gcc/testsuite/gdc.test/compilable/reinterpretctfe.d
index 1d6fd4f39c7..9a4db353e0a 100644
--- a/gcc/testsuite/gdc.test/compilable/reinterpretctfe.d
+++ b/gcc/testsuite/gdc.test/compilable/reinterpretctfe.d
@@ -1,5 +1,11 @@ 
 // https://issues.dlang.org/show_bug.cgi?id=21997
 
+struct Strukt
+{
+    int i;
+    string s;
+}
+
 int nonPureFunc(int i)
 {
     return 2 * i;
@@ -28,6 +34,14 @@  int mainCtfe()
     auto baseDel = cast(int delegate(int)) pureDel;
     assert(baseDel(4) == 20);
     */
+
+    {
+        shared Strukt shStr;
+        Strukt str = *cast(Strukt*) &shStr;
+
+        shared(Strukt)* ptr = cast(shared(Strukt)*) &str;
+    }
+
     return 0;
 }
 
diff --git a/gcc/testsuite/gdc.test/compilable/sroa.d b/gcc/testsuite/gdc.test/compilable/sroa.d
new file mode 100644
index 00000000000..8ea515c164a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/sroa.d
@@ -0,0 +1,55 @@ 
+/* REQUIRED_ARGS: -O -release -inline
+This compares two different ways to do a for loop. The range
+version should SROA the VecRange struct into two register variables.
+*/
+
+extern (C):
+
+nothrow:
+@nogc:
+@safe:
+
+alias vec_base_t = size_t;                     // base type of vector
+alias vec_t = vec_base_t*;
+
+@trusted
+pure
+size_t vec_index(size_t b, const vec_t vec);
+
+@trusted
+pure ref inout(vec_base_t) vec_numbits(inout vec_t v) { return v[-1]; }
+@trusted
+pure ref inout(vec_base_t) vec_dim(inout vec_t v) { return v[-2]; }
+
+struct VecRange
+{
+    size_t i;
+    const vec_t v;
+
+  @nogc @safe nothrow pure:
+    this(const vec_t v) { this.v = v; i = vec_index(0, v); }
+    bool empty() const { return i == vec_numbits(v); }
+    size_t front() const { return i; }
+    void popFront() { i = vec_index(i + 1, v); }
+}
+
+@safe
+pure
+uint vec_numBitsSet(const vec_t vec)
+{
+    uint n = 0;
+    size_t length = vec_numbits(vec);
+    for (size_t i = 0; (i = vec_index(i, vec)) < length; ++i)
+        ++n;
+    return n;
+}
+
+@safe
+pure
+uint vec_numBitsSet2(const vec_t vec)
+{
+    uint n = 0;
+    foreach (j; VecRange(vec))
+        ++n;
+    return n;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/stc_traits.d b/gcc/testsuite/gdc.test/compilable/stc_traits.d
new file mode 100644
index 00000000000..c5c4e5f0ac0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/stc_traits.d
@@ -0,0 +1,172 @@ 
+// REQUIRED_ARGS: -preview=dip1000 -preview=in
+/*
+TEST_OUTPUT:
+---
+100 tuple()
+101 tuple("return", "ref")
+102 tuple("ref")
+103 tuple()
+104 tuple("ref")
+105 tuple()
+106 tuple()
+107 tuple("ref")
+108 tuple("ref")
+109 tuple("ref")
+110 tuple("ref")
+111 tuple()
+112 tuple("ref")
+113 tuple("ref")
+114 tuple("ref")
+115 tuple("ref")
+116 tuple()
+117 tuple("ref")
+118 tuple("ref")
+119 tuple()
+120 tuple("ref")
+121 tuple()
+122 tuple("ref")
+123 tuple("in")
+124 tuple("in")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("return", "ref")
+m-mixin tuple("return", "ref")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple()
+m-mixin tuple()
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("ref")
+m-mixin tuple("ref")
+m       tuple("in")
+m-mixin tuple("in")
+---
+*/
+
+void func(int i) {}
+void func(return ref bool i) {}
+void func(ref float a, int b) {}
+void get(T : int)(ref T t) {}
+void get()(float t) {}
+void get(T)(ref T[] t) {}
+void funcautoi()(auto ref int i) {}
+void funcauto(T)(auto ref T a) {}
+void funcin(in int i) {}
+
+struct Foo {
+	void foo(int i) {}
+	void foo(ref bool i) {}
+	static void sfoo(ref int i) {}
+}
+
+struct FooT(T) {
+	void foo(ref T i) {}
+	static void sfoo(ref T i) {}
+}
+
+class Bar {
+	void bar(int i) {}
+	void bar(ref bool i) {}
+	static void sbar(ref int i) {}
+}
+
+class BarT(T) {
+	void bar(ref T i) {}
+	static void sbar(ref T i) {}
+}
+
+int i;
+
+template match(handlers...)
+{
+	static foreach(h; handlers)
+	{
+		// should give the same result
+		pragma(msg, "m       ", __traits(getParameterStorageClasses, h(i), 0));
+		pragma(msg, "m-mixin ", __traits(getParameterStorageClasses, mixin("h(i)"), 0));
+	}
+
+	enum match = (){};
+}
+
+void funcT(T)(ref T t) {}
+
+void main() {
+	int i;
+	bool b;
+	float f;
+	int[] ia;
+	Foo foo;
+	FooT!int foot;
+	Bar bar = new Bar;
+	BarT!int bart = new BarT!int;
+
+	ref int _foo(return ref const int* p, scope int* a, out int b, lazy int c);
+
+	// From SPEC_RUNNABLE_EXAMPLE_COMPILE:
+	int* p, a;
+	int _b, c;
+
+	static assert(__traits(getParameterStorageClasses, _foo(p, a, _b, c), 1)[0] == "scope");
+	static assert(__traits(getParameterStorageClasses, _foo(p, a, _b, c), 2)[0] == "out");
+	static assert(__traits(getParameterStorageClasses, _foo(p, a, _b, c), 3)[0] == "lazy");
+
+#line 100
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, func(0), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, func(b), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, func(f, i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, func(f, i), 1));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, get(i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, get(0.0), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, get(f), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, get(ia), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, mixin("get(i)"), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, Foo.sfoo(i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, FooT!int.sfoo(i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, foo.foo(0), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, foo.foo(b), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, foot.foo(i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, Bar.sbar(i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, BarT!int.sbar(i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, bar.bar(0), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, bar.bar(b), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, bart.bar(i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, funcautoi(10), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, funcautoi(i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, funcauto(10), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, funcauto(i), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, funcin(1), 0));
+	pragma(msg, __LINE__, " ", __traits(getParameterStorageClasses, funcin(i), 0));
+
+	cast(void) match!(
+		function(ref int i) => true,
+		delegate(ref int i) => true,
+		(ref int i) => true,
+		(return ref int i) => &i,
+		get,
+		funcT,
+		(int i) => true,
+		FooT!int.sfoo,
+		Foo.sfoo,
+		BarT!int.sbar,
+		Bar.sbar,
+		funcautoi,
+		funcauto,
+		funcin,
+	);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test15711.d b/gcc/testsuite/gdc.test/compilable/test15711.d
new file mode 100644
index 00000000000..ba7a93d930c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test15711.d
@@ -0,0 +1,31 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=15711
+
+struct Quu {
+    string val;
+}
+
+string[] result = foo!(0, [Quu(['z']), Quu("")]);
+
+template foo(size_t i, Quu[] data, string[] results = []) {
+    static if (i < data.length) {
+        enum def = data[i];
+        enum foo = foo!(i+1, data, results ~ def.val);
+    }
+    else {
+        enum foo = results;
+    }
+}
+
+// Run-time version already works
+
+string[] result_rt = foo_rt(0, [Quu(['z']), Quu("")]);
+
+string[] foo_rt(size_t i, Quu[] data, string[] results = []) {
+    if (i < data.length) {
+        auto def = data[i];
+        return foo_rt(i+1, data, results ~ def.val);
+    }
+    else {
+        return results;
+    }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test16492.d b/gcc/testsuite/gdc.test/compilable/test16492.d
deleted file mode 100644
index 833be1d8cf3..00000000000
--- a/gcc/testsuite/gdc.test/compilable/test16492.d
+++ /dev/null
@@ -1,87 +0,0 @@ 
-// ARG_SETS: -debug; -o-; -debug -preview=dip1000
-// https://issues.dlang.org/show_bug.cgi?id=16492
-
-void mayCallGC();
-
-void test() @nogc pure
-{
-    debug new int(1);
-    debug
-    {
-        mayCallGC();
-        auto b = [1, 2, 3];
-        b ~= 4;
-    }
-}
-
-void debugSafe() @safe
-{
-    debug unsafeSystem();
-    debug unsafeTemplated();
-}
-
-void unsafeSystem() @system {}
-void unsafeTemplated()() {
-    int[] arr;
-    auto b = arr.ptr;
-}
-
-void debugSafe2() @safe
-{
-    char[] arr1, arr2;
-    debug unsafeDIP1000Lifetime(arr1, arr2);
-
-    char* ptr;
-    char[] arr;
-    debug ptr = arr.ptr;
-}
-
-void unsafeDIP1000Lifetime()(ref char[] p, scope char[] s)
-{
-    p = s;
-}
-
-
-void test2() nothrow
-{
-    debug throw new Exception("");
-}
-
-void test3() nothrow
-{
-    debug {
-        foreach (_; 0 .. 10) {
-            if (1) {
-                throw new Exception("");
-            }
-        }
-    }
-}
-
-void test4() nothrow
-{
-    debug throwException();
-}
-
-void test5() nothrow
-{
-    debug willThrowException();
-}
-
-void willThrowException()()
-{
-    throwException();
-}
-
-void throwException()
-{
-    throw new Exception("");
-}
-
-void test6() nothrow
-{
-    debug
-    {
-        () {throw new Exception("");}();
-    }
-}
diff --git a/gcc/testsuite/gdc.test/compilable/test19482.d b/gcc/testsuite/gdc.test/compilable/test19482.d
new file mode 100644
index 00000000000..09485a3098a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test19482.d
@@ -0,0 +1,68 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=19482
+
+alias AliasSeq(T...) = T;
+
+extern (C++, "cppns")
+@("asd", 123)
+private
+deprecated
+immutable
+static foreach (i; 0 .. 1)
+{
+    static assert(is(typeof(i) == int));
+    static assert(__traits(getLinkage, i) == "D");
+    static assert(__traits(isDeprecated, i) == false);
+    static assert(__traits(getAttributes, i).length == 0);
+    static assert(__traits(getCppNamespaces, i).length == 0);
+    static assert(__traits(getVisibility, i) == "public");
+
+    extern int x;
+    static assert(is(typeof(x) == immutable int));
+    static assert(__traits(getLinkage, x) == "C++");
+    static assert(__traits(isDeprecated, x) == true);
+    static assert(__traits(getAttributes, x) == AliasSeq!("asd", 123));
+    static assert(__traits(getCppNamespaces, x) == AliasSeq!("cppns"));
+    static assert(__traits(getVisibility, x) == "private");
+}
+
+struct S
+{
+    @disable static foreach (j; 0 .. 1)
+    {
+        int y;
+        static assert(__traits(isDisabled, j) == false);
+        static assert(__traits(isDisabled, S.y) == true);
+    }
+}
+
+const
+static foreach (i, v; ['a'])
+{
+    static assert(is(typeof(i) == size_t));
+    static assert(is(typeof(v) == char));
+}
+
+const
+static foreach (i, s, f; Range())
+{
+    static assert(is(typeof(i) == int));
+    static assert(is(typeof(s) == string));
+    static assert(is(typeof(f) == float));
+}
+
+struct Range
+{
+    int i;
+    auto front()
+    {
+        return Tup!(int, string, float)(123, "asd", 3.14f);
+    }
+    bool empty() { return i > 0; }
+    void popFront() { ++i; }
+}
+
+struct Tup(T...)
+{
+    T fields;
+    alias fields this;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test21438.d b/gcc/testsuite/gdc.test/compilable/test21438.d
new file mode 100644
index 00000000000..02e2d8d6403
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test21438.d
@@ -0,0 +1,15 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=21438
+
+int genGBPLookup() {
+    static struct Table {
+        int[1] entries;
+    }
+
+    auto table = new Table;
+    auto x = table.entries[0];
+
+    static assert(is(typeof(x) == int));
+    return 0;
+}
+
+enum x = genGBPLookup;
diff --git a/gcc/testsuite/gdc.test/compilable/test21794.d b/gcc/testsuite/gdc.test/compilable/test21794.d
new file mode 100644
index 00000000000..68e504bce56
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test21794.d
@@ -0,0 +1,52 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=21794
+/*
+TEST_OUTPUT:
+---
+0
+0u
+0L
+0LU
+0.0F
+0.0
+0.0L
+---
+*/
+
+bool fun(void* p) {
+    const x = cast(ulong)p;
+    return 1;
+}
+
+static assert(fun(null));
+
+T fun2(T)(void* p) {
+    const x = cast(T)p;
+    return x;
+}
+
+// These were an error before, they were returning a NullExp instead of IntegerExp/RealExp
+
+static assert(fun2!int(null)    == 0);
+static assert(fun2!uint(null)   == 0);
+static assert(fun2!long(null)   == 0);
+static assert(fun2!ulong(null)  == 0);
+static assert(fun2!float(null)  == 0);
+static assert(fun2!double(null) == 0);
+static assert(fun2!real(null)   == 0);
+
+// These were printing 'null' instead of the corresponding number
+
+const i = cast(int)null;
+const ui = cast(uint)null;
+const l = cast(long)null;
+const ul = cast(ulong)null;
+const f = cast(float)null;
+const d = cast(double)null;
+const r = cast(real)null;
+pragma(msg, i);
+pragma(msg, ui);
+pragma(msg, l);
+pragma(msg, ul);
+pragma(msg, f);
+pragma(msg, d);
+pragma(msg, r);
diff --git a/gcc/testsuite/gdc.test/compilable/test21850.d b/gcc/testsuite/gdc.test/compilable/test21850.d
new file mode 100644
index 00000000000..e7fe2d4d125
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test21850.d
@@ -0,0 +1,35 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=21850
+
+struct Strukt2 {
+    this(int* _block) {  }
+}
+
+struct Strukt {
+    int* block;
+    Strukt2 foo() { return Strukt2(null); }
+    alias foo this;
+}
+
+bool wrapper(T)(ref T a, ref T b)
+{
+    return doesPointTo(a, b);
+}
+
+void johan() pure {
+    Strukt a;
+    Strukt b;
+    assert(wrapper(a, b));         // error wrapper is not pure
+    assert(doesPointTo(a, b));     // fine
+}
+
+bool doesPointTo(S, T)(S , T) {
+    return false;
+}
+
+bool doesPointTo(S)(shared S) {
+    return false;
+}
+
+bool mayPointTo(){
+    return false;
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22214.d b/gcc/testsuite/gdc.test/compilable/test22214.d
new file mode 100644
index 00000000000..d21812588ad
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22214.d
@@ -0,0 +1,16 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22214
+
+struct S
+{
+    struct T
+    {
+    }
+}
+
+void main() {
+    const S s;
+    static if (__traits(compiles, { auto t = s.T; }))
+    {
+        auto t = s.T;
+    }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22224.d b/gcc/testsuite/gdc.test/compilable/test22224.d
new file mode 100644
index 00000000000..d16b2f4023d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22224.d
@@ -0,0 +1,4 @@ 
+// REQUIRED_ARGS: -profile -c
+
+import core.stdc.stdarg; 
+void error(...) { }
diff --git a/gcc/testsuite/gdc.test/compilable/test22228.d b/gcc/testsuite/gdc.test/compilable/test22228.d
new file mode 100644
index 00000000000..ef31b4badca
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22228.d
@@ -0,0 +1,11 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22228
+// Note: fixed by reverting pull #11545
+
+auto f()
+{   immutable int i;
+    auto p = (() => &i)();
+
+    return 0;
+}
+
+enum ctfeInvocation = f;
diff --git a/gcc/testsuite/gdc.test/compilable/test22292.d b/gcc/testsuite/gdc.test/compilable/test22292.d
new file mode 100644
index 00000000000..945dffb6b2f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22292.d
@@ -0,0 +1,155 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22292
+
+// Original case
+
+class C1
+{
+    C1 c1;
+    this () pure
+    {
+        c1 = this;
+    }
+}
+immutable x = cast(immutable)r;
+
+auto r()
+{
+    C1 c1 = new C1;
+    return c1;
+}
+
+// Reference stored in another class
+
+template Test2()
+{
+    class C1
+    {
+        C2 c2;
+        this () pure
+        {
+            C1 a = this;
+            c2 = new C2(a);
+        }
+    }
+    class C2
+    {
+        C1 c1;
+        this (C1 c) pure
+        {
+            c1 = c;
+        }
+    }
+    immutable x = cast(immutable)r;
+
+    auto r()
+    {
+        C1 c1 = new C1();
+        return c1;
+    }
+}
+
+alias test2 = Test2!();
+
+// Ditto but using a struct in the middle
+
+template Test3()
+{
+    class C0
+    {
+        S1 s1;
+
+        this()
+        {
+            s1 = S1(this);
+        }
+    }
+    struct S1
+    {
+        C1 c1;
+        this (C0 c)
+        {
+            c1 = new C1(c);
+        }
+    }
+    class C1
+    {
+        C0 c0;
+        this(C0 c)
+        {
+            c0 = c;
+        }
+    }
+    immutable x = cast(immutable)r;
+
+    auto r()
+    {
+        C0 c0 = new C0();
+        return c0;
+    }
+}
+
+alias test3 = Test3!();
+
+// From https://issues.dlang.org/show_bug.cgi?id=22114
+
+template Test4()
+{
+    public class Test1(T)
+    {
+        private Test2!T val;
+
+        this()
+        {
+            val = new Test2!T(this);
+        }
+
+        private class Test2(T)
+        {
+            private Test1!(T) m_source;
+
+            this(Test1!T source)
+            {
+                m_source = source;
+            }
+        }
+    }
+
+    public class Demo
+    {
+        auto val = new Test1!int();
+    }
+}
+
+alias test4 = Test4!();
+
+// ditto
+
+template Test5()
+{
+    public @nogc class TestA(T)
+    {
+        private TestB!T valA;
+        private TestB!T valB;
+        this()
+        {
+            valB = valA = new TestB!T(this);
+        }
+
+        private @nogc class TestB(T)
+        {
+            private TestA!(T) m_source;
+
+            this(TestA!T source)
+            {
+                m_source = source;
+            }
+        }
+    }
+
+    public class Demo
+    {
+        auto val = new TestA!int();
+    }
+}
+
+alias test5 = Test5!();
diff --git a/gcc/testsuite/gdc.test/compilable/test22388.d b/gcc/testsuite/gdc.test/compilable/test22388.d
new file mode 100644
index 00000000000..cf8c3fc7677
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22388.d
@@ -0,0 +1,22 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22388
+
+void setTimer(void delegate()) @system;
+void setTimer(void delegate() @safe) @safe;
+
+void setTimer2(void delegate() @safe) @safe;
+void setTimer2(void delegate()) @system;
+
+void main() @safe
+{
+    setTimer(() => assert(false));
+
+    alias lambda = () => assert(false);
+    setTimer(lambda);
+
+    // Reversed order
+
+    setTimer2(() => assert(false));
+
+    alias lambda2 = () => assert(false);
+    setTimer2(lambda2);
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22410.d b/gcc/testsuite/gdc.test/compilable/test22410.d
new file mode 100644
index 00000000000..7e631b7e789
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22410.d
@@ -0,0 +1,59 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22410
+
+alias A(T...) = T;
+
+void fun0(const A!(int, string) x = A!(1, "asdf"))
+{
+    static assert(is(typeof(x) == A!(const int, const string)));
+}
+
+void fun1(const A!(immutable int, string) x = A!(1, "asdf"))
+{
+    static assert(is(typeof(x) == A!(immutable int, const string)));
+}
+
+void fun2(shared A!(int, string) x = A!(1, "asdf"))
+{
+    static assert(is(typeof(x) == A!(shared int, shared string)));
+}
+
+void fun3(shared const A!(int, string) x = A!(1, "asdf"))
+{
+    static assert(is(typeof(x) == A!(shared const int, shared const string)));
+}
+
+void fun4(inout A!(int, const string) x = A!(1, "asdf"))
+{
+    static assert(is(typeof(x) == A!(inout int, inout const string)));
+}
+
+void fun5(ref const A!(int, string) x = A!(1, "asdf"))
+{
+    static assert(is(typeof(x) == A!(const int, const string)));
+    static assert(__traits(isRef, x[0]) && __traits(isRef, x[1]));
+}
+
+// Implicitly conversion is also fixed, for example:
+// from (ulong, double) to (int, float)
+
+// Integral narrowing here, ulong(uint.max + 1UL) would fail.
+void fun10(A!(uint, float) x = A!(ulong(uint.max), 3.14))
+{
+    static assert(is(typeof(x) == A!(uint, float)));
+}
+
+void fun11(A!(int, double) x = A!(byte(1), 2.5f))
+{
+    static assert(is(typeof(x) == A!(int, double)));
+}
+
+void fun12(A!(byte, float) x = A!(1, 'a'))
+{
+    static assert(is(typeof(x) == A!(byte, float)));
+}
+
+A!(const int, shared char) tup = A!(1, 'a');
+void fun13(A!(byte, float) x = tup)
+{
+    static assert(is(typeof(x) == A!(byte, float)));
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22420.d b/gcc/testsuite/gdc.test/compilable/test22420.d
new file mode 100644
index 00000000000..c18d0a9b20d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22420.d
@@ -0,0 +1,88 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22420
+
+struct File
+{
+    ~this()
+    {
+    }
+    File impl()
+    {
+        return File.init;
+    }
+    alias impl this;
+}
+struct Variable
+{
+    this(File)(File) { }
+    this(File)(File[]) { }
+}
+Variable wrapFunctionReturn(alias handler)(Variable params)
+{
+    return Variable(handler(params));
+}
+void registerFile()
+{
+    wrapFunctionReturn!((Variable) {
+            return File.init;
+        })(Variable.init);
+}
+
+// Reduction from an 'automem' test
+
+struct Issue156 {}
+
+void test2()
+{
+    RefCounted!Issue156 s;
+    auto r1 = repeat(s);
+    zip(r1);
+}
+
+struct RefCounted(RefCountedType)
+{
+    ~this() {}
+    alias _impl this;
+
+    struct Impl {}
+    alias ImplType = Impl;
+
+    private ImplType* _impl;
+
+}
+template Tuple(Specs)
+{
+    struct Tuple
+    {
+        this(U)(U) {}
+        this()(int) {}
+    }
+}
+
+template ElementType(R)
+{
+    static if (is(typeof(R.init) T))
+        alias ElementType = T;
+}
+
+struct Repeat(T)
+{
+    inout(T) front() inout {assert(0);}
+}
+
+Repeat!T repeat(T)(T ) {assert(0);}
+
+auto zip(Ranges)(Ranges )
+{
+    return ZipShortest!Ranges();
+}
+
+struct ZipShortest(Ranges...)
+{
+    Ranges ranges;
+    alias ElementType = Tuple!(.ElementType!(Ranges[0]));
+
+    ElementType front()
+    {
+        return typeof(return)(ranges[0].front);
+    }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test22421.d b/gcc/testsuite/gdc.test/compilable/test22421.d
new file mode 100644
index 00000000000..902646d323b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test22421.d
@@ -0,0 +1,19 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22421
+
+alias AliasSeq(T...) = T;
+
+template staticMap(alias fun, args...)
+{
+    alias staticMap = AliasSeq!();
+    static foreach(arg; args)
+        staticMap = AliasSeq!(staticMap, fun!arg);
+}
+
+template id(alias what)
+{
+    enum id = __traits(identifier, what);
+}
+
+enum A { a }
+
+static assert(staticMap!(id, A.a) == AliasSeq!("a"));
diff --git a/gcc/testsuite/gdc.test/compilable/test318.d b/gcc/testsuite/gdc.test/compilable/test318.d
new file mode 100644
index 00000000000..fd3cabeaea3
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test318.d
@@ -0,0 +1,19 @@ 
+// LINK:
+// PERMUTE_ARGS: -version=C_Main
+
+version (C_Main)
+{
+    // Fine, infers int
+    extern(C) auto main(int argc, const char** argv)
+    {
+        return argc;
+    }
+}
+else
+{
+    // Fine, infers void
+    auto main()
+    {
+
+    }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/test4090.d b/gcc/testsuite/gdc.test/compilable/test4090.d
index 8f8f7c9f26d..0e785cf21c9 100644
--- a/gcc/testsuite/gdc.test/compilable/test4090.d
+++ b/gcc/testsuite/gdc.test/compilable/test4090.d
@@ -12,9 +12,6 @@  void test4090a()
         // inference + qualifier + ref
         foreach (          ref x; arr) static assert(is(typeof(x) == int));
         foreach (    const ref x; arr) static assert(is(typeof(x) == const int));
-      static assert(!__traits(compiles, {
-        foreach (immutable ref x; arr) {}
-      }));
 
         // with exact type + qualifier
         foreach (          int x; arr) static assert(is(typeof(x) == int));
@@ -24,25 +21,11 @@  void test4090a()
         // with exact type + qualifier + ref
         foreach (          ref int x; arr) static assert(is(typeof(x) == int));
         foreach (    const ref int x; arr) static assert(is(typeof(x) == const int));
-      static assert(!__traits(compiles, {
-        foreach (immutable ref int x; arr) {}
-      }));
 
         // convertible type + qualifier
         foreach (          double x; arr) static assert(is(typeof(x) == double));
         foreach (    const double x; arr) static assert(is(typeof(x) == const double));
         foreach (immutable double x; arr) static assert(is(typeof(x) == immutable double));
-
-        // convertible type + qualifier + ref
-      static assert(!__traits(compiles, {
-        foreach (          ref double x; arr) {}
-      }));
-      static assert(!__traits(compiles, {
-        foreach (    const ref double x; arr) {}
-      }));
-      static assert(!__traits(compiles, {
-        foreach (immutable ref double x; arr) {}
-      }));
     }
     // for the immutable elements
     {
diff --git a/gcc/testsuite/gdc.test/compilable/test9766.d b/gcc/testsuite/gdc.test/compilable/test9766.d
index 3cfc22f0464..aaceb7d95e1 100644
--- a/gcc/testsuite/gdc.test/compilable/test9766.d
+++ b/gcc/testsuite/gdc.test/compilable/test9766.d
@@ -69,9 +69,9 @@  static assert(U9766.var4.offsetof == 40);
 
 struct TestMaxAlign
 {
-align(1u << 31):
+align(1u << 15):
     ubyte a;
     ubyte b;
 }
 
-static assert(TestMaxAlign.b.offsetof == 2147483648u);
+static assert(TestMaxAlign.b.offsetof == (1 << 15));
diff --git a/gcc/testsuite/gdc.test/compilable/testcstuff3.d b/gcc/testsuite/gdc.test/compilable/testcstuff3.d
deleted file mode 100644
index 89228a9bc4a..00000000000
--- a/gcc/testsuite/gdc.test/compilable/testcstuff3.d
+++ /dev/null
@@ -1,4 +0,0 @@ 
-// EXTRA_FILES: imports/cstuff3.c
-import imports.cstuff3;
-
-static assert(squared(4) == 16);
diff --git a/gcc/testsuite/gdc.test/compilable/transition_in.d b/gcc/testsuite/gdc.test/compilable/transition_in.d
new file mode 100644
index 00000000000..cc492a747fd
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/transition_in.d
@@ -0,0 +1,26 @@ 
+// REQUIRED_ARGS: -transition=in
+/*
+TRANSFORM_OUTPUT: remove_lines(druntime)
+TEST_OUTPUT:
+---
+compilable/transition_in.d(3): Usage of 'in' on parameter
+compilable/transition_in.d(3): Usage of 'in' on parameter
+compilable/transition_in.d(8): Usage of 'in' on parameter
+compilable/transition_in.d(13): Usage of 'in' on parameter
+---
+*/
+#line 1
+struct Foobar
+{
+    void bar (in int a, in Object c);
+}
+
+version (none)
+{
+    void barfoo (in string arg);
+}
+
+void main ()
+{
+    void nested (in char c) {}
+}
diff --git a/gcc/testsuite/gdc.test/compilable/zerosize.d b/gcc/testsuite/gdc.test/compilable/zerosize.d
index 3c0062ead30..6e26deb5490 100644
--- a/gcc/testsuite/gdc.test/compilable/zerosize.d
+++ b/gcc/testsuite/gdc.test/compilable/zerosize.d
@@ -1,12 +1,17 @@ 
 
 extern (C) struct S { }
 
-static assert(S.sizeof == 0);
-static assert(S.alignof == 1);
+version (CRuntime_Microsoft)
+    static assert(S.sizeof == 4);
+else
+    static assert(S.sizeof == 0);
+
+version (CRuntime_DigitalMars)
+    static assert(S.alignof == 0);
+else
+    static assert(S.alignof == 1);
 
 extern (C++) struct T { }
 
 static assert(T.sizeof == 1);
 static assert(T.alignof == 1);
-
-
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag10327.d b/gcc/testsuite/gdc.test/fail_compilation/diag10327.d
index 38f9ccbe12b..1366882edeb 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag10327.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag10327.d
@@ -1,7 +1,8 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/diag10327.d(11): Error: module `test10327` is in file 'imports/test10327.d' which cannot be read
+fail_compilation/diag10327.d(12): Error: unable to read module `test10327`
+fail_compilation/diag10327.d(12):        Expected 'imports/test10327.d' or 'imports/test10327/package.d' in one of the following import paths:
 import path[0] = fail_compilation
 import path[1] = $p:druntime/import$
 import path[2] = $p:phobos$
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag20059.d b/gcc/testsuite/gdc.test/fail_compilation/diag20059.d
index a7a5914cfce..2c8063a2430 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/diag20059.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag20059.d
@@ -1,7 +1,7 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/diag20059.d(15): Error: Expected return type of `string`, not `string[]`:
+fail_compilation/diag20059.d(15): Error: expected return type of `string`, not `string[]`:
 fail_compilation/diag20059.d(13):        Return type of `string` inferred here.
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail20618.d b/gcc/testsuite/gdc.test/fail_compilation/fail20618.d
new file mode 100644
index 00000000000..ac6b33a3a9c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail20618.d
@@ -0,0 +1,16 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail20618.d(13): Error: in slice `a[1 .. 12]`, upper bound is greater than array length `10`
+fail_compilation/fail20618.d(14): Error: in slice `a[4 .. 3]`, lower bound is greater than upper bound
+fail_compilation/fail20618.d(15): Error: in slice `a[0 .. 11]`, upper bound is greater than array length `10`
+---
+*/
+
+void main()
+{
+    int[10] a;
+    auto b = a[1..12];
+    auto c = a[4..3];
+    auto d = a[0..$ + 1];
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21091a.d b/gcc/testsuite/gdc.test/fail_compilation/fail21091a.d
index 74f40c2eeb5..c2bbe4d59e4 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail21091a.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21091a.d
@@ -3,7 +3,8 @@ 
 /*
 TEST_OUTPUT:
 ----
-fail_compilation/fail21091a.d(15): Error: module `Ternary` is in file 'Ternary.d' which cannot be read
+fail_compilation/fail21091a.d(16): Error: unable to read module `Ternary`
+fail_compilation/fail21091a.d(16):        Expected 'Ternary.d' or 'Ternary/package.d' in one of the following import paths:
 import path[0] = fail_compilation
 import path[1] = $p:druntime/import$
 import path[2] = $p:phobos$
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail21091b.d b/gcc/testsuite/gdc.test/fail_compilation/fail21091b.d
index d9467aafdb3..3d7d6001bd2 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail21091b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail21091b.d
@@ -3,7 +3,8 @@ 
 /*
 TEST_OUTPUT:
 ----
-fail_compilation/fail21091b.d(15): Error: module `Tid` is in file 'Tid.d' which cannot be read
+fail_compilation/fail21091b.d(16): Error: unable to read module `Tid`
+fail_compilation/fail21091b.d(16):        Expected 'Tid.d' or 'Tid/package.d' in one of the following import paths:
 import path[0] = fail_compilation
 import path[1] = $p:druntime/import$
 import path[2] = $p:phobos$
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22084.d b/gcc/testsuite/gdc.test/fail_compilation/fail22084.d
index 02fff2f6cc6..bd11832adeb 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail22084.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22084.d
@@ -18,6 +18,6 @@  struct Destructor
 
 void test()
 {
-    auto a0 = Destructor;
+    auto a0 = Destructor();
     testVariadic(1, a0);
 }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22151.d b/gcc/testsuite/gdc.test/fail_compilation/fail22151.d
new file mode 100644
index 00000000000..c6c3b1b742b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22151.d
@@ -0,0 +1,24 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22151
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail22151.d(14): Error: function `test` is not an lvalue and cannot be modified
+fail_compilation/fail22151.d(15): Error: function `test2` is not an lvalue and cannot be modified
+fail_compilation/fail22151.d(18): Error: function pointed to by `fp` is not an lvalue and cannot be modified
+fail_compilation/fail22151.d(21): Error: function pointed to by `ff` is not an lvalue and cannot be modified
+---
+*/
+
+void test()
+{
+    *&test = *&test;
+    *&test2 = *&test;
+
+    void function() fp;
+    *fp = *fp;
+
+    auto ff = &test2;
+    *ff = *&test2;
+}
+
+void test2();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22366.d b/gcc/testsuite/gdc.test/fail_compilation/fail22366.d
new file mode 100644
index 00000000000..3a2469f5fe1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail22366.d
@@ -0,0 +1,15 @@ 
+// REQUIRED_ARGS: -dip1000
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail22366.d(13): Error: scope variable `__aaval2` assigned to non-scope `aa[0]`
+---
+*/
+
+int* fun(scope int* x) @safe
+{
+    int*[int] aa;
+    aa[0] = x; // should give an error
+    return aa[0];
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail225.d b/gcc/testsuite/gdc.test/fail_compilation/fail225.d
deleted file mode 100644
index dee9a543b6e..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail225.d
+++ /dev/null
@@ -1,17 +0,0 @@ 
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail225.d(15): Error: cannot implicitly convert expression `1` of type `int` to `immutable(char*)`
-fail_compilation/fail225.d(15): Error: cannot implicitly convert expression `& ch` of type `char*` to `immutable(char*)`
----
-*/
-struct Struct { 
-        char* chptr; 
-}
-
-void main()
-{
-        char ch = 'd';
-        immutable Struct iStruct = {1, &ch};
-}
-
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail287.d b/gcc/testsuite/gdc.test/fail_compilation/fail287.d
index 7ed8f134c97..e5b1a79bb04 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail287.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail287.d
@@ -1,7 +1,7 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail287.d(14): Error: had 299 cases which is more than 256 cases in case range
+fail_compilation/fail287.d(14): Error: had 300 cases which is more than 257 cases in case range
 ---
 */
 
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail318.d b/gcc/testsuite/gdc.test/fail_compilation/fail318.d
deleted file mode 100644
index d99175e6eff..00000000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail318.d
+++ /dev/null
@@ -1,8 +0,0 @@ 
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail318.d(8): Error: function `D main` must return `int` or `void`
----
-*/
-
-auto main() { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail318_b.d b/gcc/testsuite/gdc.test/fail_compilation/fail318_b.d
new file mode 100644
index 00000000000..efbf45bdc2e
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail318_b.d
@@ -0,0 +1,11 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail318_b.d(8): Error: function `D main` must return `int`, `void` or `noreturn`, not `string`
+---
+*/
+
+auto main()
+{
+    return "";
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7173.d b/gcc/testsuite/gdc.test/fail_compilation/fail7173.d
index 2a2e46bb9f0..05ba7f9fc0a 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail7173.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail7173.d
@@ -1,7 +1,7 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/fail7173.d(23): Error: cannot implicitly convert expression `b1._a.opBinary(b2._a).fun()` of type `void` to `B`
+fail_compilation/fail7173.d(23): Error: expression `b1._a.opBinary(b2._a).fun()` is `void` and has no value
 ---
 */
 struct A{
diff --git a/gcc/testsuite/gdc.test/fail_compilation/foreach.d b/gcc/testsuite/gdc.test/fail_compilation/foreach.d
new file mode 100644
index 00000000000..9a1c7c8ddb0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/foreach.d
@@ -0,0 +1,14 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/foreach.d(12): Error: cannot declare `out` loop variable, use `ref` instead
+fail_compilation/foreach.d(13): Error: cannot declare `out` loop variable, use `ref` instead
+fail_compilation/foreach.d(13): Error: cannot declare `out` loop variable, use `ref` instead
+---
+*/
+void main ()
+{
+    int[] array;
+    foreach (out val; array) {}
+    foreach (out idx, out val; array) {}
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/foreach2.d b/gcc/testsuite/gdc.test/fail_compilation/foreach2.d
new file mode 100644
index 00000000000..8bd4893b3fb
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/foreach2.d
@@ -0,0 +1,22 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/foreach2.d(15): Error: argument type mismatch, `int` to `ref immutable(int)`
+fail_compilation/foreach2.d(16): Error: argument type mismatch, `int` to `ref immutable(int)`
+fail_compilation/foreach2.d(19): Error: argument type mismatch, `int` to `ref double`
+fail_compilation/foreach2.d(20): Error: argument type mismatch, `int` to `ref const(double)`
+fail_compilation/foreach2.d(21): Error: argument type mismatch, `int` to `ref immutable(double)`
+---
+*/
+void test4090 ()
+{
+    // From https://issues.dlang.org/show_bug.cgi?id=4090
+    int[] arr = [1,2,3];
+    foreach (immutable ref x; arr) {}
+    foreach (immutable ref int x; arr) {}
+
+    // convertible type + qualifier + ref
+    foreach (          ref double x; arr) {}
+    foreach (    const ref double x; arr) {}
+    foreach (immutable ref double x; arr) {}
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice10212.d b/gcc/testsuite/gdc.test/fail_compilation/ice10212.d
index b9fe2aa6557..99fe1edf3e0 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice10212.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice10212.d
@@ -1,7 +1,7 @@ 
 /*
 TEST_OUTPUT:
 ---
-fail_compilation/ice10212.d(13): Error: Expected return type of `int`, not `int function() pure nothrow @nogc @safe`:
+fail_compilation/ice10212.d(13): Error: expected return type of `int`, not `int function() pure nothrow @nogc @safe`:
 fail_compilation/ice10212.d(13):        Return type of `int` inferred here.
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice22377.d b/gcc/testsuite/gdc.test/fail_compilation/ice22377.d
new file mode 100644
index 00000000000..4616f99212a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice22377.d
@@ -0,0 +1,8 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/ice22377.d(8): Error: Internal Compiler Error: type `string` cannot be mapped to C++
+---
+*/
+
+extern(C++) void foo(string a) {}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice7782.d b/gcc/testsuite/gdc.test/fail_compilation/ice7782.d
index d42011a0dd0..551933b382d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/ice7782.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice7782.d
@@ -2,7 +2,8 @@ 
 EXTRA_FILES: imports/ice7782algorithm.d imports/ice7782range.d
 TEST_OUTPUT:
 ----
-fail_compilation/ice7782.d(13): Error: module `ice7782math` is in file 'imports/ice7782range/imports/ice7782math.d' which cannot be read
+fail_compilation/ice7782.d(14): Error: unable to read module `ice7782math`
+fail_compilation/ice7782.d(14):        Expected 'imports/ice7782range/imports/ice7782math.d' or 'imports/ice7782range/imports/ice7782math/package.d' in one of the following import paths:
 import path[0] = fail_compilation
 import path[1] = $p:druntime/import$
 import path[2] = $p:phobos$
diff --git a/gcc/testsuite/gdc.test/fail_compilation/imports/imp22329.d b/gcc/testsuite/gdc.test/fail_compilation/imports/imp22329.d
new file mode 100644
index 00000000000..9dc3c8efa06
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/imports/imp22329.d
@@ -0,0 +1,4 @@ 
+void func(T)(T arg)
+{
+    auto a = arg + 1;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/noreturn.d b/gcc/testsuite/gdc.test/fail_compilation/noreturn.d
index 3b340e84c4d..4a588b4c00d 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/noreturn.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/noreturn.d
@@ -72,7 +72,7 @@  noreturn casting(int i)
             return cast() n;
         }
     }
-
+    assert(false);
 }
 
 enum forceCasting0 = casting(0);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d b/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d
new file mode 100644
index 00000000000..e7d28dc3aaf
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/noreturn2.d
@@ -0,0 +1,90 @@ 
+/*
+REQUIRED_ARGS: -w -o-
+
+TEST_OUTPUT:
+---
+fail_compilation/noreturn2.d(18): Error: expected return type of `noreturn`, not `void`
+---
+
+https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1034.md
+*/
+
+alias noreturn = typeof(*null);
+
+void doStuff();
+
+noreturn returnVoid()
+{
+    return doStuff();
+}
+
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/noreturn2.d(37): Error: expected return type of `int`, not `string`:
+fail_compilation/noreturn2.d(35):        Return type of `int` inferred here.
+---
++/
+
+auto missmatch(int i)
+{
+    if (i < 0)
+        return assert(false);
+    if (i == 0)
+        return i;
+    if (i > 0)
+        return "";
+}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/noreturn2.d(50): Error: function `noreturn2.returns` is typed as `NR` but does return
+fail_compilation/noreturn2.d(50):        `noreturn` functions must either throw, abort or loop indefinitely
+---
++/
+
+enum NR : noreturn;
+
+NR returns()
+{
+    // Fallthrough despite noreturn
+}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/noreturn2.d(64): Error: cannot implicitly convert expression `1` of type `int` to `noreturn`
+---
++/
+
+noreturn returnsValue()
+{
+    return 1;
+}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/noreturn2.d(75): Error: expected return type of `int`, not `void`
+---
++/
+int returnVoid2()
+{
+    return doStuff();
+}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/noreturn2.d(89): Error: mismatched function return type inference of `void` and `int`
+---
++/
+auto returnVoid3(int i)
+{
+    if (i > 0)
+        return i;
+    else
+        return doStuff();
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
index 034fa541234..43998b9f47c 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version.d
@@ -113,6 +113,8 @@  fail_compilation/reserved_version.d(214): Error: version identifier `CppRuntime_
 fail_compilation/reserved_version.d(215): Error: version identifier `CppRuntime_Sun` is reserved and cannot be set
 fail_compilation/reserved_version.d(216): Error: version identifier `D_PIE` is reserved and cannot be set
 fail_compilation/reserved_version.d(217): Error: version identifier `AVR` is reserved and cannot be set
+fail_compilation/reserved_version.d(218): Error: version identifier `D_PreConditions` is reserved and cannot be set
+fail_compilation/reserved_version.d(219): Error: version identifier `D_PostConditions` is reserved and cannot be set
 ---
 */
 
@@ -232,6 +234,8 @@  version = CppRuntime_Microsoft;
 version = CppRuntime_Sun;
 version = D_PIE;
 version = AVR;
+version = D_PreConditions;
+version = D_PostConditions;
 
 // This should work though
 debug = DigitalMars;
@@ -340,3 +344,5 @@  debug = none;
 debug = D_P16;
 debug = MSP430;
 debug = AVR;
+debug = D_PreConditions;
+debug = D_PostConditions;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d
index b8b6fa4d8e8..633330908c8 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/reserved_version_switch.d
@@ -103,6 +103,8 @@ 
 // REQUIRED_ARGS: -version=assert
 // REQUIRED_ARGS: -version=all
 // REQUIRED_ARGS: -version=none
+// REQUIRED_ARGS: -version=D_PreConditions
+// REQUIRED_ARGS: -version=D_PostConditions
 // REQUIRED_ARGS: -debug=DigitalMars
 // REQUIRED_ARGS: -debug=GNU
 // REQUIRED_ARGS: -debug=LDC
@@ -203,6 +205,8 @@ 
 // REQUIRED_ARGS: -debug=assert
 // REQUIRED_ARGS: -debug=all
 // REQUIRED_ARGS: -debug=none
+// REQUIRED_ARGS: -debug=D_PreConditions
+// REQUIRED_ARGS: -debug=D_PostConditions
 /*
 TEST_OUTPUT:
 ---
@@ -309,5 +313,7 @@  Error: version identifier `unittest` is reserved and cannot be set
 Error: version identifier `assert` is reserved and cannot be set
 Error: version identifier `all` is reserved and cannot be set
 Error: version identifier `none` is reserved and cannot be set
+Error: version identifier `D_PreConditions` is reserved and cannot be set
+Error: version identifier `D_PostConditions` is reserved and cannot be set
 ---
 */
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17425.d b/gcc/testsuite/gdc.test/fail_compilation/test17425.d
index f7628b83e22..77c49567e47 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test17425.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17425.d
@@ -1,7 +1,7 @@ 
 /* TEST_OUTPUT:
 ---
 fail_compilation/test17425.d(24): Error: parameter index must be in range 0..4 not 4
-fail_compilation/test17425.d(27): Error: first argument to `__traits(getParameterStorageClasses, i, 4)` is not a function
+fail_compilation/test17425.d(27): Error: first argument to `__traits(getParameterStorageClasses, i, 4)` is not a function or a function call
 fail_compilation/test17425.d(29): Error: expression expected as second argument of `__traits(getParameterStorageClasses, foo, int)`
 fail_compilation/test17425.d(31): Error: expected 2 arguments for `getParameterStorageClasses` but had 3
 ---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test17868b.d b/gcc/testsuite/gdc.test/fail_compilation/test17868b.d
index 5bfff5cf50a..7833b61a949 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/test17868b.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/test17868b.d
@@ -1,9 +1,9 @@ 
 /*
 TEST_OUTPUT:
 ----
+fail_compilation/test17868b.d(9): Error: pragma `crt_constructor` can only apply to a single declaration
 fail_compilation/test17868b.d(10): Error: function `test17868b.foo` must be `extern(C)` for `pragma(crt_constructor)`
 fail_compilation/test17868b.d(14): Error: function `test17868b.bar` must be `extern(C)` for `pragma(crt_constructor)`
-fail_compilation/test17868b.d(9): Error: pragma `crt_constructor` can only apply to a single declaration
 ----
  */
 pragma(crt_constructor):
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test20998.d b/gcc/testsuite/gdc.test/fail_compilation/test20998.d
new file mode 100644
index 00000000000..16eb02622d8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test20998.d
@@ -0,0 +1,120 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=20998
+/*
+REQUIRED_ARGS: -verrors=context
+TEST_OUTPUT:
+---
+fail_compilation/test20998.d(76): Error: undefined identifier `invalid`
+X x = { invalid, 2, "asd" };
+        ^
+fail_compilation/test20998.d(76): Error: too many initializers for `X`
+X x = { invalid, 2, "asd" };
+                    ^
+fail_compilation/test20998.d(83): Error: cannot implicitly convert expression `"a"` of type `string` to `int`
+X2 x2 = { ptr: null, "a", ptr: 2, 444 };
+                     ^
+fail_compilation/test20998.d(83): Error: duplicate initializer for field `ptr`
+X2 x2 = { ptr: null, "a", ptr: 2, 444 };
+                               ^
+fail_compilation/test20998.d(83): Error: too many initializers for `X2`
+X2 x2 = { ptr: null, "a", ptr: 2, 444 };
+                                  ^
+fail_compilation/test20998.d(90): Error: overlapping initialization for field `ptr` and `x`
+X3 x3 = { ptr: null, "a", ptr: 2, 444 };
+               ^
+fail_compilation/test20998.d(90): Error: cannot implicitly convert expression `"a"` of type `string` to `int`
+X3 x3 = { ptr: null, "a", ptr: 2, 444 };
+                     ^
+fail_compilation/test20998.d(90): Error: duplicate initializer for field `ptr`
+X3 x3 = { ptr: null, "a", ptr: 2, 444 };
+                               ^
+fail_compilation/test20998.d(90): Error: too many initializers for `X3`
+X3 x3 = { ptr: null, "a", ptr: 2, 444 };
+                                  ^
+fail_compilation/test20998.d(98): Error: field `X4.ptr` cannot assign to misaligned pointers in `@safe` code
+    X4 x4 = { ptr: null, "a", 444, ptr: 2, true };
+                   ^
+fail_compilation/test20998.d(98): Error: cannot implicitly convert expression `"a"` of type `string` to `int`
+    X4 x4 = { ptr: null, "a", 444, ptr: 2, true };
+                         ^
+fail_compilation/test20998.d(98): Error: too many initializers for `X4`
+    X4 x4 = { ptr: null, "a", 444, ptr: 2, true };
+                              ^
+fail_compilation/test20998.d(102):        called from here: `test()`
+auto e = test();
+             ^
+fail_compilation/test20998.d(104): Error: cannot implicitly convert expression `1` of type `int` to `void*`
+X2 a5 = { ptr: 1, ptr: 2, ptr: 444, ptr: 555 };
+               ^
+fail_compilation/test20998.d(104): Error: duplicate initializer for field `ptr`
+X2 a5 = { ptr: 1, ptr: 2, ptr: 444, ptr: 555 };
+                       ^
+fail_compilation/test20998.d(104): Error: duplicate initializer for field `ptr`
+X2 a5 = { ptr: 1, ptr: 2, ptr: 444, ptr: 555 };
+                               ^
+fail_compilation/test20998.d(104): Error: too many initializers for `X2`
+X2 a5 = { ptr: 1, ptr: 2, ptr: 444, ptr: 555 };
+                                         ^
+fail_compilation/test20998.d(107): Error: too many initializers for `X2`
+X2 c6 = { null, 2, true, null };
+                         ^
+fail_compilation/test20998.d(116): Error: cannot implicitly convert expression `1` of type `int` to `immutable(char*)`
+    immutable Struct iStruct = {1, &ch};
+                                ^
+fail_compilation/test20998.d(116): Error: too many initializers for `Struct`
+    immutable Struct iStruct = {1, &ch};
+                                   ^
+fail_compilation/test20998.d(120):        called from here: `test2()`
+auto t = test2();
+              ^
+---
+*/
+
+struct X {
+	void* ptr;
+	int x;
+}
+X x = { invalid, 2, "asd" };
+
+struct X2 {
+	void* ptr;
+	int x;
+	bool y;
+}
+X2 x2 = { ptr: null, "a", ptr: 2, 444 };
+
+union X3 {
+    void* ptr;
+    int x;
+    bool y;
+}
+X3 x3 = { ptr: null, "a", ptr: 2, 444 };
+
+int test() @safe
+{
+    align (1) struct X4 {
+        void* ptr;
+        int x;
+    }
+    X4 x4 = { ptr: null, "a", 444, ptr: 2, true };
+    return 0;
+}
+
+auto e = test();
+
+X2 a5 = { ptr: 1, ptr: 2, ptr: 444, ptr: 555 };
+X2 b5 = { ptr: null, y: true };
+X2 c5 = { x: 2, true, ptr: null };
+X2 c6 = { null, 2, true, null };
+
+struct Struct {
+        char* chptr;
+}
+
+int test2()
+{
+    char ch = 'd';
+    immutable Struct iStruct = {1, &ch};
+    return 0;
+}
+
+auto t = test2();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21093.d b/gcc/testsuite/gdc.test/fail_compilation/test21093.d
new file mode 100644
index 00000000000..b85d0c36c3f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21093.d
@@ -0,0 +1,56 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=21093
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test21093.d(24): Error: function `test21093.LocalTime.hasDST` does not override any function
+fail_compilation/test21093.d(32): Error: class `test21093.LocalTime2` cannot implicitly generate a default constructor when base class `test21093.TimeZone2` is missing a default constructor
+fail_compilation/test21093.d(44): Error: function `test21093.LocalTime3.string` does not override any function
+fail_compilation/test21093.d(55): Error: cannot implicitly override base class method `test21093.TimeZone4.hasDST` with `test21093.LocalTime4.hasDST`; add `override` attribute
+---
+*/
+
+void fromUnixTime(immutable TimeZone tz = LocalTime()) { }
+void fromUnixTime(immutable TimeZone2 tz = LocalTime2()) { }
+void fromUnixTime(immutable TimeZone3 tz = LocalTime3()) { }
+void fromUnixTime(immutable TimeZone4 tz = LocalTime4()) { }
+
+class TimeZone
+{
+}
+
+class LocalTime : TimeZone
+{
+    static immutable(LocalTime) opCall() { }
+    override hasDST() { }
+}
+
+class TimeZone2
+{
+    this(string) { }
+}
+
+class LocalTime2 : TimeZone2
+{
+    static immutable(LocalTime2) opCall() { }
+}
+
+class TimeZone3
+{
+}
+
+class LocalTime3 : TimeZone3
+{
+    static immutable(LocalTime3) opCall() { }
+    override string () { }
+}
+
+class TimeZone4
+{
+    bool hasDST();
+}
+
+class LocalTime4 : TimeZone4
+{
+    static immutable(LocalTime4) opCall() { }
+    bool hasDST() { }
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21380.d b/gcc/testsuite/gdc.test/fail_compilation/test21380.d
new file mode 100644
index 00000000000..6a2da1b2132
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21380.d
@@ -0,0 +1,46 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=21380
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test21380.d(39): Error: partial template instance `MySerializer().serializeSinkType!int` has no value
+fail_compilation/test21380.d(44): Error: template instance `test21380.SupportSinkTypeSer!(MySerializer!int)` error instantiating
+---
+*/
+
+template isSomeFunction(T...)
+if (T.length == 1)
+{
+    static if (is(typeof(& T[0]) U : U*) && is(U == function) || is(typeof(& T[0]) U == delegate))
+    {
+        // T is a (nested) function symbol.
+        enum bool isSomeFunction = true;
+    }
+    else static if (is(T[0] W) || is(typeof(T[0]) W))
+    {
+        // T is an expression or a type.  Take the type of it and examine.
+        static if (is(W F : F*) && is(F == function))
+            enum bool isSomeFunction = true; // function pointer
+        else
+            enum bool isSomeFunction = is(W == function) || is(W == delegate);
+    }
+    else
+        enum bool isSomeFunction = false;
+}
+
+struct MySerializer (T)
+{
+	void serializeSinkType(T2) (scope auto ref T2 record) {}
+}
+
+template SupportSinkTypeSer(SerT)
+{
+    /* Note: Partial template instance because it needs inference, in this case
+       it cannot infer 'auto ref' parameter */
+	enum SupportSinkTypeSer = isSomeFunction!(SerT.init.serializeSinkType!int);
+}
+
+int main()
+{
+	enum x = SupportSinkTypeSer!(MySerializer!int);
+	return 0;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21930.d b/gcc/testsuite/gdc.test/fail_compilation/test21930.d
new file mode 100644
index 00000000000..6c932435b01
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test21930.d
@@ -0,0 +1,27 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=21930
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test21930.d(21): Error: variable `string` is used as a type
+fail_compilation/test21930.d(15):        variable `string` is declared here
+fail_compilation/test21930.d(26): Error: constructor `test21930.R.this(string)` is not callable using argument types `()`
+---
+*/
+
+alias AliasSeq(T...) = T;
+
+alias TP(alias name) = AliasSeq!name;
+
+int string; // 'string' declared as a variable
+
+alias a = TP!(main);
+
+class R
+{
+    this(string) { } // so constructor have errors
+}
+
+@system main()
+{
+    new R;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22329.d b/gcc/testsuite/gdc.test/fail_compilation/test22329.d
new file mode 100644
index 00000000000..237f9c76667
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test22329.d
@@ -0,0 +1,21 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=22329
+// EXTRA_FILES: imports/imp22329.d
+/*
+TEST_OUTPUT:
+---
+fail_compilation/imports/imp22329.d(3): Error: no property `values` for type `test22329.Foo`
+fail_compilation/imports/imp22329.d(3): Error: incompatible types for `(arg) + (1)`: `Foo` and `int`
+fail_compilation/test22329.d(20): Error: template instance `imp22329.func!(Foo)` error instantiating
+---
+*/
+
+public struct Foo {
+    private int values;
+    alias values this;
+}
+
+void main()
+{
+    import imports.imp22329 : func;
+    func(Foo());
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test22361.d b/gcc/testsuite/gdc.test/fail_compilation/test22361.d
new file mode 100644
index 00000000000..11255ff1f1b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/test22361.d
@@ -0,0 +1,11 @@ 
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test22361.d(11): Error: unable to read module `this_module_does_not_exist`
+fail_compilation/test22361.d(11):        Expected 'this_module_does_not_exist.d' or 'this_module_does_not_exist/package.d' in one of the following import paths:
+import path[0] = fail_compilation
+import path[1] = $p:druntime/import$
+import path[2] = $p:phobos$
+---
+*/
+import this_module_does_not_exist;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/testOpApply.d b/gcc/testsuite/gdc.test/fail_compilation/testOpApply.d
new file mode 100644
index 00000000000..9203685fdc8
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/testOpApply.d
@@ -0,0 +1,161 @@ 
+/+
+TEST_OUTPUT:
+---
+fail_compilation/testOpApply.d(27): Error: `testOpApply.SameAttr.opApply` called with argument types `(int delegate(int i) pure nothrow @nogc @safe)` matches both:
+fail_compilation/testOpApply.d(13):     `testOpApply.SameAttr.opApply(int delegate(int) @system dg)`
+and:
+fail_compilation/testOpApply.d(18):     `testOpApply.SameAttr.opApply(int delegate(int) @system dg)`
+---
++/
+
+struct SameAttr
+{
+    int opApply(int delegate(int) @system dg) @system
+    {
+        return 0;
+    }
+
+    int opApply(int delegate(int) @system dg) @safe
+    {
+        return 0;
+    }
+}
+
+void testSameAttr() @safe
+{
+    SameAttr sa;
+    foreach (int i; sa) {}
+}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/testOpApply.d(104): Error: `testOpApply.SameAttr.opApply` called with argument types `(int delegate(int i) pure nothrow @nogc @system)` matches both:
+fail_compilation/testOpApply.d(13):     `testOpApply.SameAttr.opApply(int delegate(int) @system dg)`
+and:
+fail_compilation/testOpApply.d(18):     `testOpApply.SameAttr.opApply(int delegate(int) @system dg)`
+---
++/
+#line 100
+
+void testSameAttr() @system
+{
+    SameAttr sa;
+    foreach (int i; sa) {}
+}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/testOpApply.d(217): Error: `sa.opApply` matches more than one declaration:
+`fail_compilation/testOpApply.d(203)`:     `int(int delegate(int) dg)`
+and:
+`fail_compilation/testOpApply.d(208)`:     `int(int delegate(string) dg)`
+fail_compilation/testOpApply.d(217): Error: cannot uniquely infer `foreach` argument types
+---
++/
+#line 200
+
+struct DifferentTypes
+{
+    int opApply(int delegate(int) dg)
+    {
+        return 0;
+    }
+
+    int opApply(int delegate(string) dg)
+    {
+        return 0;
+    }
+}
+
+void testDifferentTypes()
+{
+    DifferentTypes sa;
+    foreach (i; sa) {}
+}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/testOpApply.d(317): Error: `sa.opApply` matches more than one declaration:
+`fail_compilation/testOpApply.d(303)`:     `int(int delegate(int) dg)`
+and:
+`fail_compilation/testOpApply.d(308)`:     `int(int delegate(long) dg)`
+fail_compilation/testOpApply.d(317): Error: cannot uniquely infer `foreach` argument types
+---
++/
+#line 300
+
+struct CovariantTypes
+{
+    int opApply(int delegate(int) dg)
+    {
+        return 0;
+    }
+
+    int opApply(int delegate(long) dg)
+    {
+        return 0;
+    }
+}
+
+void testCovariantTypes()
+{
+    CovariantTypes sa;
+    foreach (i; sa) {}
+}
+
+/+
+See https://issues.dlang.org/show_bug.cgi?id=21683
+
+TEST_OUTPUT:
+---
+fail_compilation/testOpApply.d(420): Error: `sa.opApply` matches more than one declaration:
+`fail_compilation/testOpApply.d(404)`:     `int(int delegate(int) dg)`
+and:
+`fail_compilation/testOpApply.d(410)`:     `int(int delegate(ref int) dg)`
+fail_compilation/testOpApply.d(420): Error: cannot uniquely infer `foreach` argument types
+---
++/
+#line 400
+
+struct DifferentQualifiers
+{
+    int x;
+    int opApply(int delegate(int) dg)
+    {
+        x = 1;
+        return 0;
+    }
+
+    int opApply(int delegate(ref int) dg)
+    {
+        x = 2;
+        return 0;
+    }
+}
+
+void testDifferentQualifiers()
+{
+    DifferentQualifiers sa;
+    foreach (i; sa) {}
+}
+
+/+
+TEST_OUTPUT:
+---
+fail_compilation/testOpApply.d(504): Error: `sa.opApply` matches more than one declaration:
+`fail_compilation/testOpApply.d(404)`:     `int(int delegate(int) dg)`
+and:
+`fail_compilation/testOpApply.d(410)`:     `int(int delegate(ref int) dg)`
+fail_compilation/testOpApply.d(504): Error: cannot uniquely infer `foreach` argument types
+---
++/
+#line 500
+
+void testDifferentQualifiersRef()
+{
+    DifferentQualifiers sa;
+    foreach (ref i; sa) {}
+}
diff --git a/gcc/testsuite/gdc.test/runnable/aliasthis.d b/gcc/testsuite/gdc.test/runnable/aliasthis.d
index cc12f55935d..db5913c8389 100644
--- a/gcc/testsuite/gdc.test/runnable/aliasthis.d
+++ b/gcc/testsuite/gdc.test/runnable/aliasthis.d
@@ -2102,6 +2102,42 @@  void test16633()
     root.populate;
 }
 
+/***************************************************/
+// https://issues.dlang.org/show_bug.cgi?id=13009
+
+struct RefCounted13009_2(T)
+{
+    ref T refCountedPayload()
+    {
+        assert(false);
+    }
+
+    ref inout(T) refCountedPayload() inout
+    {
+        assert(false);
+    }
+
+    alias refCountedPayload this;
+}
+
+struct S13009_2
+{
+    struct Payload
+    {
+        int[] data;
+    }
+
+    RefCounted13009_2!Payload payload;
+    alias X = typeof(payload.data[0]);
+
+    void foo()
+    {
+        payload.data[0] = 0;
+    }
+}
+
+/***************************************************/
+
 int main()
 {
     test1();
diff --git a/gcc/testsuite/gdc.test/runnable/dhry.d b/gcc/testsuite/gdc.test/runnable/dhry.d
index f772d6160ad..1eb463ce8cc 100644
--- a/gcc/testsuite/gdc.test/runnable/dhry.d
+++ b/gcc/testsuite/gdc.test/runnable/dhry.d
@@ -929,3 +929,19 @@  version (NetBSD)
      return q;
     }
 }
+
+version (OpenBSD)
+{
+    import core.sys.posix.sys.time;
+
+    double dtime()
+    {
+     double q;
+     timeval tv;
+
+     gettimeofday(&tv,null);
+     q = cast(double)tv.tv_sec + cast(double)tv.tv_usec * 1.0e-6;
+
+     return q;
+    }
+}
diff --git a/gcc/testsuite/gdc.test/runnable/fix22372.d b/gcc/testsuite/gdc.test/runnable/fix22372.d
new file mode 100644
index 00000000000..55864a0cf0f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/fix22372.d
@@ -0,0 +1,38 @@ 
+/* PERMUTE_ARGS: -O
+ */
+
+// https://issues.dlang.org/show_bug.cgi?id=22104
+
+struct S { int a1, a2, a3; }
+
+version (none)
+void throws2ndCall(ref S x);
+else
+{
+void throws2ndCall(ref S x)
+{
+    __gshared bool b;
+    if (b)
+        throw new Exception("n == 1");
+    b = true;
+}
+}
+
+void main() { foo(); }
+
+void foo()
+{
+    S[] arr = [S(), S()];
+    size_t i;
+    try
+    {
+        for (i = 0; i < 2; i++)
+            throws2ndCall(arr[i]);
+    }
+    catch (Exception o)
+    {
+        //printf("Exception: i = %lu\n", i);
+        assert(i == 1);  // this fails
+    }
+}
+
diff --git a/gcc/testsuite/gdc.test/runnable/interpret.d b/gcc/testsuite/gdc.test/runnable/interpret.d
index a626749ee46..989fb2e1e90 100644
--- a/gcc/testsuite/gdc.test/runnable/interpret.d
+++ b/gcc/testsuite/gdc.test/runnable/interpret.d
@@ -3604,6 +3604,62 @@  void test21878()
     ctfeFunc21878(); // succeeds at runtime
 }
 
+/************************************************/
+// https://issues.dlang.org/show_bug.cgi?id=20133
+
+void bar20133(ref string text)
+{
+    text = text[1 .. $];
+    assert(text.length < 3);
+    if (text.length == 2) assert(text == "oo");
+    if (text.length == 1) assert(text == "o");
+    if (text.length == 0) assert(text == "");
+    string tcopy = text;
+    if (tcopy.length > 0)
+        bar20133(tcopy);
+    assert(tcopy.length < 2);
+    if (tcopy.length == 1) assert(tcopy == "o");
+    if (tcopy.length == 0) assert(tcopy == "");
+}
+
+void bar20133_2(ref string text)
+{
+    auto ptext = &text;
+    *ptext = text[1 .. $];
+    assert(text.length < 3);
+    if (text.length == 2) assert(text == "oo");
+    if (text.length == 1) assert(text == "o");
+    if (text.length == 0) assert(text == "");
+    string tcopy = text;
+    if (tcopy.length > 0)
+        bar20133_2(tcopy);
+    assert(tcopy.length < 2);
+    if (tcopy.length == 1) assert(tcopy == "o");
+    if (tcopy.length == 0) assert(tcopy == "");
+}
+
+alias fun20133 = {
+    string input = "foo";
+    bar20133(input);
+    assert(input == "oo");
+    return input;
+};
+
+alias fun20133_2 = {
+    string input = "foo";
+    bar20133_2(input);
+    assert(input == "oo");
+    return input;
+};
+
+void test20133()
+{
+    enum ctest = fun20133();
+    enum ctest2 = fun20133_2();
+    auto rtest = fun20133();
+    auto rtest2 = fun20133_2();
+}
+
 /************************************************/
 
 int main()
@@ -3732,6 +3788,7 @@  int main()
     test20366();
     test20400();
     test21878();
+    test20133();
 
     printf("Success\n");
     return 0;
diff --git a/gcc/testsuite/gdc.test/runnable/noreturn1.d b/gcc/testsuite/gdc.test/runnable/noreturn1.d
index 447ea28294c..1da0479d9f6 100644
--- a/gcc/testsuite/gdc.test/runnable/noreturn1.d
+++ b/gcc/testsuite/gdc.test/runnable/noreturn1.d
@@ -66,9 +66,56 @@  void test2()
 
 /*****************************************/
 
+struct BasicStruct
+{
+	int firstInt;
+	noreturn noRet;
+	long lastLong;
+}
+
+struct AlignedStruct
+{
+	int firstInt;
+	align(16) noreturn noRet;
+	long lastLong;
+}
+
+void takeBasic(BasicStruct bs)
+{
+    assert(bs.firstInt == 13);
+    assert(bs.lastLong == 42);
+
+    assert(&bs.noRet == (&bs.firstInt + 1));
+}
+
+void takeAligned(AlignedStruct as)
+{
+    assert(as.firstInt == 99);
+    assert(as.lastLong == 0xDEADBEEF);
+
+    assert(&as.noRet == &as.lastLong);
+}
+
+void test3()
+{
+    {
+        BasicStruct bs;
+        bs.firstInt = 13;
+        bs.lastLong = 42;
+        takeBasic(bs);
+    }
+    {
+        AlignedStruct as;
+        as.firstInt = 99;
+        as.lastLong = 0xDEADBEEF;
+        takeAligned(as);
+    }
+}
+
 int main()
 {
     test1();
     test2();
+    test3();
     return 0;
 }
diff --git a/gcc/testsuite/gdc.test/runnable/noreturn2.d b/gcc/testsuite/gdc.test/runnable/noreturn2.d
new file mode 100644
index 00000000000..1d3d362e107
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/noreturn2.d
@@ -0,0 +1,220 @@ 
+/*
+PERMUTE_ARGS: -O -inline
+RUN_OUTPUT:
+---
+getAndPrintS
+---
+*/
+
+import core.stdc.stdio;
+import core.exception : AssertError;
+
+/*****************************************/
+
+// noreturn is inferred for functions that always throw
+// The code must not strip the destructor when calling a noreturn function
+
+struct WithDtor
+{
+    __gshared int destroyed;
+
+    int num;
+
+    int acceptNoreturn(int a, int b, int c)
+    {
+        puts("unreachable");
+        return num + a + b + c;
+    }
+
+    ~this()
+    {
+        destroyed += num;
+    }
+}
+
+noreturn doesThrow()
+{
+    WithDtor wd = WithDtor(1);
+    throw new Exception("");
+}
+
+noreturn callDoesThrow()
+{
+    WithDtor wd = WithDtor(2);
+    doesThrow();
+}
+
+
+void testDtors()
+{
+    try
+    {
+        callDoesThrow();
+        assert(0);
+    } catch (Exception e) {}
+
+    assert(WithDtor.destroyed == 3);
+}
+
+/*****************************************************************************/
+
+/// Verifies that `func` throws a `Throwable` with `message` at `line`
+void testAssertFailure(size_t expLine, string expMsg, void function() func, size_t callLine = __LINE__)
+{
+    void enforce(bool check, string error)
+    {
+        if (!check)
+            throw new AssertError(error, __FILE__, callLine);
+    }
+
+    bool caught;
+    try
+    {
+        func();
+    }
+    catch (Throwable t)
+    {
+        // Save members because t might be overwritten by an Assertion failure below
+        string actFile = t.file;
+        size_t actLine = t.line;
+        string actMsg = t.msg;
+        caught = true;
+
+        scope (failure)
+        {
+            printf("\nfile = \"%.*s\"\nline = %zu\nmsg = \"%.*s\"\n\n",
+                cast(int) actFile.length, actFile.ptr,
+                actLine,
+                cast(int) actMsg.length, actMsg.ptr
+            );
+            fflush(stdout);
+        }
+
+        enforce(actFile == __FILE__, "Wrong file");
+        enforce(actLine == expLine, "Wrong line");
+        enforce(actMsg == expMsg, "Wrong message");
+    }
+
+    enforce(caught, "No Throwable was thrown!");
+}
+
+void testAccess()
+{
+    enum msg = "Accessed expression of type `noreturn`";
+
+    // FIXME: Another assertion failure in the backend trying to generate noreturn.sizeof = 0 byte assignment
+    version (FIXME)
+    testAssertFailure(__LINE__ + 3, msg, function noreturn()
+    {
+        noreturn a;
+        noreturn b = a;
+    });
+
+    if (false) // read does not assert!
+    testAssertFailure(__LINE__ + 3, msg, function noreturn()
+    {
+        noreturn a;
+        int b = a;
+        assert(false, "Unreachable!"); // Statement above not detected as noreturn
+    });
+
+    testAssertFailure(__LINE__ + 2, msg, function noreturn()
+    {
+        cast(noreturn) 1;
+    });
+
+    version (FIXME)
+    testAssertFailure(__LINE__ + 3, msg, function noreturn()
+    {
+        noreturn a;
+        noreturn b = cast(noreturn) 1;
+    });
+
+    if (false) // Read does not assert
+    testAssertFailure(__LINE__ + 3, msg, function noreturn()
+    {
+        noreturn a;
+        return a;
+    });
+
+    if (false) // Read does not assert
+    testAssertFailure(__LINE__ + 4, msg, function noreturn()
+    {
+        static void foo(noreturn) {}
+        noreturn a;
+        foo(a);
+        assert(false, "Unreachable!"); // Ditto
+    });
+}
+
+/*****************************************/
+
+void testFuncCall()
+{
+    enum msg = "Called abort()";
+    enum line = __LINE__ + 1;
+    static noreturn abort() { assert(0, msg); }
+
+    // Canaries to check for side effects
+    __gshared int countLeft, countRight;
+
+    scope (failure) printf("countLeft = %d\ncountRight = %d\n", countLeft, countRight);
+
+
+    // D function arguments are evaluated left to right
+    testAssertFailure(line, msg, function()
+    {
+        static void acceptNoreturnD(int, int, int) { puts("unreachable"); }
+
+        acceptNoreturnD(countLeft++, abort(), countRight++);
+    });
+
+    assert(countLeft == 1);
+    assert(countRight == 0);
+
+//     // C function arguments are still evaluated left to right
+//     // Despite them being push in reverse order
+    testAssertFailure(line, msg, function()
+    {
+        static extern(C) void acceptNoreturnC(int, int, int) { puts("unreachable"); }
+
+        acceptNoreturnC(countLeft++, abort(), countRight++);
+
+        assert(false);
+    });
+
+    assert(countLeft == 2);
+    assert(countRight == 0);
+
+    WithDtor.destroyed = 0;
+
+    testAssertFailure(__LINE__ + 2, "Error", function()
+    {
+        static WithDtor getS() { assert(false, "Error"); }
+
+        getS().acceptNoreturn(countLeft++, abort(), countRight++);
+    });
+
+    assert(countLeft == 2); // No changes
+    assert(countRight == 0);
+    assert(WithDtor.destroyed == 0); // No temporary to destruct
+
+    testAssertFailure(line, msg, function()
+    {
+        static WithDtor getAndPrintS() { puts("getAndPrintS"); return WithDtor(1); }
+
+        getAndPrintS().acceptNoreturn(countLeft++, abort(), countRight++);
+    });
+
+    assert(countLeft == 3);
+    assert(countRight == 0);
+    assert(WithDtor.destroyed == 1);
+}
+
+int main()
+{
+    testDtors();
+    testAccess();
+    testFuncCall();
+    return 0;
+}
diff --git a/gcc/testsuite/gdc.test/runnable/sroa13220.d b/gcc/testsuite/gdc.test/runnable/sroa13220.d
new file mode 100644
index 00000000000..2cec6665a33
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/sroa13220.d
@@ -0,0 +1,103 @@ 
+/* REQUIRED_ARGS: -O -inline -noboundscheck
+ */
+// https://github.com/dlang/pull/13220
+
+version (D_SIMD)
+{
+
+mixin template VectorOps(VectorType, ArrayType: BaseType[N], BaseType, size_t N)
+{
+    enum Count = N;
+    alias Base = BaseType;
+
+    BaseType* ptr() return pure nothrow @nogc
+    {
+        return array.ptr;
+    }
+
+    // Unary operators
+    VectorType opUnary(string op)() pure nothrow @safe @nogc
+    {
+        VectorType res = void;
+        mixin("res.array[] = " ~ op ~ "array[];");
+        return res;
+    }
+
+    // Binary operators
+    VectorType opBinary(string op)(VectorType other) pure const nothrow @safe @nogc
+    {
+        VectorType res = void;
+        mixin("res.array[] = array[] " ~ op ~ " other.array[];");
+        return res;
+    }
+
+    // Assigning a BaseType value
+    void opAssign(BaseType e) pure nothrow @safe @nogc
+    {
+        array[] = e;
+    }
+
+    // Assigning a static array
+    void opAssign(ArrayType v) pure nothrow @safe @nogc
+    {
+        array[] = v[];
+    }
+
+    void opOpAssign(string op)(VectorType other) pure nothrow @safe @nogc
+    {
+        mixin("array[] "  ~ op ~ "= other.array[];");
+    }
+
+    // Assigning a dyn array
+    this(ArrayType v) pure nothrow @safe @nogc
+    {
+        array[] = v[];
+    }
+
+    // Broadcast constructor
+    this(BaseType x) pure nothrow @safe @nogc
+    {
+        array[] = x;
+    }
+
+    ref inout(BaseType) opIndex(size_t i) inout pure nothrow @safe @nogc
+    {
+        return array[i];
+    }
+}
+
+// Note: can't be @safe with this signature
+Vec loadUnaligned(Vec)(const(BaseType!Vec)* pvec) @trusted
+{
+    // Since this vector is emulated, it doesn't have alignement constraints
+    // and as such we can just cast it.
+    return *cast(Vec*)(pvec);
+}
+
+private template BaseType(V)
+{
+    alias typeof( ( { V v; return v; }()).array[0]) BaseType;
+}
+
+struct int4
+{
+    int[4] array;
+    mixin VectorOps!(int4, int[4]);
+}
+
+alias __m128i = int4;
+}
+
+int main()
+{
+  version (D_SIMD)
+  {
+    int4 A = [1, 2, 3, 4];
+    int4 ia = A;
+    ia.ptr[2] = 5;
+    int4 C = ia;
+    int[4] result = [1, 2, 5, 4];
+    assert(C.array == result);
+  }
+    return 0;
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test15624.d b/gcc/testsuite/gdc.test/runnable/test15624.d
deleted file mode 100644
index 792757932e4..00000000000
--- a/gcc/testsuite/gdc.test/runnable/test15624.d
+++ /dev/null
@@ -1,51 +0,0 @@ 
-/* PERMUTE_ARGS:
- */
-
-// https://issues.dlang.org/show_bug.cgi?id=15624
-
-struct Foo {
-        int x;
-        int opApply(int delegate(int, string, string) @safe dg) @safe {
-                x = 1;
-                return 0;
-        }
-        int opApply(int delegate(int, string, string) @system dg) @system {
-                x = 2;
-                return 0;
-        }
-}
-
-void testSafe() @safe {
-        Foo foo;
-        foreach (i, k, v; foo) {
-        }
-        assert(foo.x == 1);
-}
-
-void testSystem() @system {
-        Foo foo;
-        foreach (i, k, v; foo) {
-        }
-        assert(foo.x == 2);
-}
-
-void test() @system
-{
-    Foo f;
-
-    int dgsafe  (int x, string s, string t) @safe   { return 1; }
-    int dgsystem(int x, string s, string t) @system { return 1; }
-
-    f.opApply(&dgsafe);
-    assert(f.x == 1);
-    f.opApply(&dgsystem);
-    assert(f.x == 2);
-}
-
-int main()
-{
-    testSafe();
-    testSystem();
-    test();
-    return 0;
-}
diff --git a/gcc/testsuite/gdc.test/runnable/test21039.d b/gcc/testsuite/gdc.test/runnable/test21039.d
new file mode 100644
index 00000000000..c58600f8da0
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test21039.d
@@ -0,0 +1,27 @@ 
+// https://issues.dlang.org/show_bug.cgi?id=21039
+
+class Inner {}
+
+class Outer {
+    Inner inner;
+    alias inner this;
+    this(Inner i) { inner = i; }
+}
+
+void main() {
+  auto inner = new Inner;
+  auto outer = new Outer(new Inner);
+
+  // implicit cast goes through 'alias this'
+
+  Inner inner1 = outer;  // Already does it
+  assert(inner1);
+
+  Inner[] inners = [inner, outer]; // Fixed
+
+  assert(inners[0], "first element is null");
+  assert(inners[1], "second element is null");
+
+  Inner inner2 = 1 ? outer : inner; // Fixed
+  assert(inner2);
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test22205.d b/gcc/testsuite/gdc.test/runnable/test22205.d
new file mode 100644
index 00000000000..78abf2ff658
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test22205.d
@@ -0,0 +1,17 @@ 
+// REQUIRED_ARGS: -debug
+
+void main() nothrow
+{
+    debug
+    {
+        try
+        {
+            throw new Exception("2");
+        }
+        catch (Exception) {}
+        catch (Throwable)
+        {
+            assert(0);
+        }
+    }
+}
diff --git a/gcc/testsuite/gdc.test/runnable/test22278.d b/gcc/testsuite/gdc.test/runnable/test22278.d
new file mode 100644
index 00000000000..72332a45561
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/test22278.d
@@ -0,0 +1,24 @@ 
+/*
+REQUIRED_ARGS: -release
+PERMUTE_ARGS:  -check=in=on -check=out=on
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=22278
+
+bool resultIn;
+bool resultOut;
+
+void foo22278()
+    in { resultIn = true; }
+    out { resultOut = true; }
+do {}
+
+int main()
+{
+    foo22278();
+
+    version(D_PreConditions)  assert(resultIn);  else assert(!resultIn);
+    version(D_PostConditions) assert(resultOut); else assert(!resultOut);
+
+    return 0;
+}
diff --git a/gcc/testsuite/gdc.test/runnable/testOpApply.d b/gcc/testsuite/gdc.test/runnable/testOpApply.d
new file mode 100644
index 00000000000..7b884e5857c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/testOpApply.d
@@ -0,0 +1,142 @@ 
+/* PERMUTE_ARGS:
+ */
+
+// https://issues.dlang.org/show_bug.cgi?id=15624
+
+struct Foo {
+        int x;
+        int opApply(int delegate(int, string, string) @safe dg) @safe {
+                x = 1;
+                return 0;
+        }
+        int opApply(int delegate(int, string, string) @system dg) @system {
+                x = 2;
+                return 0;
+        }
+}
+
+void testSafe() @safe {
+        Foo foo;
+        foreach (i, k, v; foo) {
+        }
+        assert(foo.x == 1);
+}
+
+void testSystem() @system {
+        Foo foo;
+        foreach (i, k, v; foo) {
+        }
+        assert(foo.x == 2);
+}
+
+void test() @system
+{
+    Foo f;
+
+    int dgsafe  (int x, string s, string t) @safe   { return 1; }
+    int dgsystem(int x, string s, string t) @system { return 1; }
+
+    f.opApply(&dgsafe);
+    assert(f.x == 1);
+    f.opApply(&dgsystem);
+    assert(f.x == 2);
+}
+
+int main()
+{
+    testSafe();
+    testSystem();
+    test();
+    testDifferentTypes();
+    testSameAttributes();
+    testInverseAttributes();
+    return 0;
+}
+
+void testDifferentTypes()
+{
+    static struct DifferentTypes
+    {
+        int x;
+        int opApply(int delegate(int) dg) @safe {
+            x = 1;
+            return 0;
+        }
+        int opApply(int delegate(long) dg) @safe {
+            x = 2;
+            return 0;
+        }
+    }
+
+    DifferentTypes dt;
+    foreach (int i; dt) {}
+    assert(dt.x == 1);
+
+    foreach (long i; dt) {}
+    assert(dt.x == 2);
+}
+
+void testSameAttributes()
+{
+    static struct SameAttributes
+    {
+        int x;
+        int opApply(int delegate(int) @system dg) @safe {
+            x = 1;
+            return 0;
+        }
+        int opApply(int delegate(int) @safe dg) @safe {
+            x = 2;
+            return 0;
+        }
+    }
+
+    static void safe() @safe
+    {
+        SameAttributes sa;
+        foreach (i; sa) {}
+        assert(sa.x == 2);
+    }
+    safe();
+
+    static void system() @system
+    {
+        SameAttributes sa;
+        foreach (i; sa) {}
+        assert(sa.x == 1);
+    }
+    system();
+}
+
+// Not useful but enabled by the associated patch
+void testInverseAttributes()
+{
+    static struct InverseAttributes
+    {
+        int x;
+        int opApply(int delegate(int) @system dg) @safe {
+            x = 1;
+            return 0;
+        }
+        int opApply(int delegate(int) @safe dg) @system {
+            x = 2;
+            return 0;
+        }
+    }
+
+    static void system() @system
+    {
+        InverseAttributes sa;
+        foreach (i; sa) {}
+        assert(sa.x == 1);
+    }
+    system();
+
+    static void safe() @safe
+    {
+        InverseAttributes sa;
+        (() @trusted { foreach (i; sa) {} })();
+        assert(sa.x == 2);
+    }
+    safe();
+}
diff --git a/gcc/testsuite/gdc.test/runnable/testmainb.d b/gcc/testsuite/gdc.test/runnable/testmainb.d
new file mode 100644
index 00000000000..d6452ecb17f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable/testmainb.d
@@ -0,0 +1,15 @@ 
+/*
+Test that -main does nothing when main is already defined
+
+REQUIRED_ARGS: -main
+RUN_OUTPUT:
+---
+Success
+---
+*/
+extern(C) int printf(const char*, ...);
+
+void main()
+{
+    printf("Success\n");
+}
diff --git a/gcc/testsuite/gdc.test/runnable/uda.d b/gcc/testsuite/gdc.test/runnable/uda.d
index cdb9aa660cb..1d010989646 100644
--- a/gcc/testsuite/gdc.test/runnable/uda.d
+++ b/gcc/testsuite/gdc.test/runnable/uda.d
@@ -697,6 +697,54 @@  static if(is(typeof(foo20831) Params20831 == __parameters))
 
 /************************************************/
 
+/************************************************/
+// https://issues.dlang.org/show_bug.cgi?id=15804
+
+template test15804()
+{
+    alias AliasSeq(T...) = T;
+
+    @(42) struct Foo(D) {}
+    auto fooFac(T)()
+    {
+        static assert(__traits(getAttributes, Foo) == AliasSeq!42);
+        static assert(__traits(getAttributes, Foo!int) == AliasSeq!42);
+        return Foo!T();
+    }
+
+    auto booFac(T)()
+    {
+        @(43) struct Boo {}
+        static assert(__traits(getAttributes, Boo) == AliasSeq!43);
+        return Boo();
+    }
+
+    auto barFac(T)()
+    {
+        @(44) struct Bar(D) {}
+        static assert(__traits(getAttributes, Bar) == AliasSeq!44); // Fixed
+        static assert(__traits(getAttributes, Bar!int) == AliasSeq!44);
+        return Bar!T();
+    }
+
+    auto bazFac(T)()
+    {
+        @(45) static struct Baz(D) {}
+        static assert(__traits(getAttributes, Baz) == AliasSeq!45); // Fixed
+        static assert(__traits(getAttributes, Baz!int) == AliasSeq!45);
+        return Baz!T();
+    }
+
+    auto foo = fooFac!int;
+    auto boo = booFac!int;
+    auto bar = barFac!int;
+    auto baz = bazFac!int;
+}
+
+alias a15804 = test15804!();
+
+/************************************************/
+
 int main()
 {
     test1();
diff --git a/gcc/testsuite/gdc.test/runnable/ufcs.d b/gcc/testsuite/gdc.test/runnable/ufcs.d
index 2d9bf155983..8fd7bb2fba2 100644
--- a/gcc/testsuite/gdc.test/runnable/ufcs.d
+++ b/gcc/testsuite/gdc.test/runnable/ufcs.d
@@ -196,6 +196,7 @@  void test5()
     {
         // f5_1 .. f5_5 are symbols which declared in module scope
         assert(100.f5_1() == 1);
+        assert(001.f5_1() == 1); // https://issues.dlang.org/show_bug.cgi?id=8346
         assert("s".f5_2() == 2);
         assert(1.4.f5_3() == 3);
         assert(100.f5_4() == 1);
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp22287.cpp b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp22287.cpp
new file mode 100644
index 00000000000..ba7b25aef13
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable_cxx/extra-files/cpp22287.cpp
@@ -0,0 +1,337 @@ 
+#include <assert.h>
+
+class X
+{
+public:
+    virtual ~X();
+    int i;
+};
+
+X::~X()
+{
+}
+
+class Y : public X
+{
+};
+
+class A
+{
+public:
+    virtual ~A();
+    virtual int f1() const;
+
+    int i;
+};
+
+class I
+{
+public:
+    virtual int f2() const = 0;
+    virtual X *f4() = 0;
+};
+
+class B : public A, public I
+{
+public:
+    virtual int f1() const;
+    virtual int f2() const;
+    virtual int f3() const;
+    virtual X *f4();
+};
+
+class C : public B
+{
+public:
+    virtual int f1() const;
+    virtual int f2() const;
+    virtual int f3() const;
+    virtual Y *f4();
+};
+
+#ifdef _WIN32
+class D : public B
+{
+public:
+    virtual int f1() const;
+    virtual int f2() const;
+    virtual int f3() const;
+    virtual Y *f4();
+};
+
+class E : public B
+{
+public:
+    virtual int f1() const;
+    virtual int f2() const;
+    virtual int f3() const;
+    virtual Y *f4();
+};
+#endif
+
+A::~A()
+{
+}
+
+int A::f1() const
+{
+    return i + 11;
+}
+
+int B::f1() const
+{
+    return i + 21;
+}
+
+int B::f2() const
+{
+    return i + 22;
+}
+
+int B::f3() const
+{
+    return i + 23;
+}
+
+X *B::f4()
+{
+    X *r = new X;
+    r->i = i + 24;
+    return r;
+}
+
+int C::f1() const
+{
+    return i + 31;
+}
+
+int C::f2() const
+{
+    return i + 32;
+}
+
+int C::f3() const
+{
+    return i + 33;
+}
+
+Y *C::f4()
+{
+    Y *r = new Y;
+    r->i = i + 34;
+    return r;
+}
+
+I *createIFromCPP(char type, int i)
+{
+    switch (type)
+    {
+    case 'B':
+    {
+        B *b = new B();
+        b->i = i;
+        return b;
+    }
+    case 'C':
+    {
+        C *c = new C();
+        c->i = i;
+        return c;
+    }
+#ifdef _WIN32
+    case 'D':
+    {
+        D *d = new D();
+        d->i = i;
+        return d;
+    }
+    case 'E':
+    {
+        E *e = new E();
+        e->i = i;
+        return e;
+    }
+#endif
+    default:
+        return 0;
+    }
+}
+
+B *createBFromCPP(char type, int i)
+{
+    switch (type)
+    {
+    case 'B':
+    {
+        B *b = new B();
+        b->i = i;
+        return b;
+    }
+    case 'C':
+    {
+        C *c = new C();
+        c->i = i;
+        return c;
+    }
+#ifdef _WIN32
+    case 'D':
+    {
+        D *d = new D();
+        d->i = i;
+        return d;
+    }
+    case 'E':
+    {
+        E *e = new E();
+        e->i = i;
+        return e;
+    }
+#endif
+    default:
+        return 0;
+    }
+}
+
+C *createCFromCPP(int i)
+{
+    C *c = new C();
+    c->i = i;
+    return c;
+}
+
+#ifdef _WIN32
+D *createDFromCPP(int i)
+{
+    D *d = new D();
+    d->i = i;
+    return d;
+}
+
+E *createEFromCPP(int i)
+{
+    E *e = new E();
+    e->i = i;
+    return e;
+}
+#endif
+
+I *createIFromD(char type, int i);
+B *createBFromD(char type, int i);
+C *createCFromD(int i);
+#ifdef _WIN32
+D *createDFromD(int i);
+E *createEFromD(int i);
+#endif
+
+void runCPPTests()
+{
+    {
+        B *b = new B();
+        b->i = 100;
+        assert(b->f1() == 121);
+        assert(b->f2() == 122);
+        assert(b->f3() == 123);
+        assert(b->f4()->i == 124);
+    }
+    {
+        C *c = new C();
+        c->i = 100;
+        assert(c->f1() == 131);
+        assert(c->f2() == 132);
+        assert(c->f3() == 133);
+        assert(c->f4()->i == 134);
+    }
+#ifdef _WIN32
+    {
+        D *d = new D();
+        d->i = 100;
+        assert(d->f1() == 141);
+        assert(d->f2() == 142);
+        assert(d->f3() == 143);
+        assert(d->f4()->i == 144);
+    }
+    {
+        E *e = new E();
+        e->i = 100;
+        assert(e->f1() == 151);
+        assert(e->f2() == 152);
+        assert(e->f3() == 153);
+        assert(e->f4()->i == 154);
+    }
+#endif
+    {
+        I *i = createIFromD('B', 100);
+        assert(i->f2() == 122);
+        assert(i->f4()->i == 124);
+    }
+    {
+        I *i = createIFromD('C', 100);
+        assert(i->f2() == 132);
+        assert(i->f4()->i == 134);
+    }
+#ifdef _WIN32
+    {
+        I *i = createIFromD('D', 100);
+        assert(i->f2() == 142);
+        assert(i->f4()->i == 144);
+    }
+    {
+        I *i = createIFromD('E', 100);
+        assert(i->f2() == 152);
+        assert(i->f4()->i == 154);
+    }
+#endif
+    {
+        B *b = createBFromD('B', 100);
+        assert(b->f1() == 121);
+        assert(b->f2() == 122);
+        assert(b->f3() == 123);
+        assert(b->f4()->i == 124);
+    }
+    {
+        B *b = createBFromD('C', 100);
+        assert(b->f1() == 131);
+        assert(b->f2() == 132);
+        assert(b->f3() == 133);
+        assert(b->f4()->i == 134);
+    }
+#ifdef _WIN32
+    {
+        B *b = createBFromD('D', 100);
+        assert(b->f1() == 141);
+        assert(b->f2() == 142);
+        assert(b->f3() == 143);
+        assert(b->f4()->i == 144);
+    }
+    {
+        B *b = createBFromD('E', 100);
+        assert(b->f1() == 151);
+        assert(b->f2() == 152);
+        assert(b->f3() == 153);
+        assert(b->f4()->i == 154);
+    }
+#endif
+    {
+        C *c = createCFromD(100);
+        assert(c->f1() == 131);
+        assert(c->f2() == 132);
+        assert(c->f3() == 133);
+        assert(c->f4()->i == 134);
+    }
+#ifdef _WIN32
+    {
+        D *d = createDFromD(100);
+        assert(d->f1() == 141);
+        assert(d->f2() == 142);
+        assert(d->f3() == 143);
+        assert(d->f4()->i == 144);
+    }
+    {
+        E *e = createEFromD(100);
+        assert(e->f1() == 151);
+        assert(e->f2() == 152);
+        assert(e->f3() == 153);
+        assert(e->f4()->i == 154);
+    }
+#endif
+}
diff --git a/gcc/testsuite/gdc.test/runnable_cxx/test22287.d b/gcc/testsuite/gdc.test/runnable_cxx/test22287.d
new file mode 100644
index 00000000000..a0c74752ff1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/runnable_cxx/test22287.d
@@ -0,0 +1,327 @@ 
+// EXTRA_CPP_SOURCES: cpp22287.cpp
+
+extern(C++):
+
+class X
+{
+public:
+    ~this();
+    int i;
+}
+
+class Y : X
+{
+}
+
+class A
+{
+    ~this();
+    int f1() const;
+
+    int i;
+}
+
+interface I
+{
+    int f2() const;
+    X f4();
+}
+
+class B : A, I
+{
+    override int f1() const;
+    override int f2() const;
+    int f3() const;
+    override X f4();
+}
+
+class C : B
+{
+    override int f1() const;
+    override int f2() const;
+    override int f3() const;
+    override Y f4();
+}
+
+version(Windows)
+{
+class D : B
+{
+    override int f1() const
+    {
+        return i + 41;
+    }
+
+    override int f2() const
+    {
+        return i + 42;
+    }
+
+    override int f3() const
+    {
+        return i + 43;
+    }
+
+    override Y f4()
+    {
+        Y r = new Y;
+        r.i = i + 44;
+        return r;
+    }
+}
+
+mixin template MixinE()
+{
+    override int f1() const
+    {
+        return i + 51;
+    }
+
+    override int f2() const
+    {
+        return i + 52;
+    }
+
+    override int f3() const
+    {
+        return i + 53;
+    }
+
+    override Y f4()
+    {
+        Y r = new Y;
+        r.i = i + 54;
+        return r;
+    }
+}
+
+class E : B
+{
+    mixin MixinE;
+}
+}
+
+I createIFromCPP(char type, int i);
+B createBFromCPP(char type, int i);
+C createCFromCPP(int i);
+version(Windows)
+{
+D createDFromCPP(int i);
+E createEFromCPP(int i);
+}
+
+I createIFromD(char type, int i)
+{
+    switch (type)
+    {
+    case 'B':
+    {
+        B b = new B();
+        b.i = i;
+        return b;
+    }
+    case 'C':
+    {
+        C c = new C();
+        c.i = i;
+        return c;
+    }
+    version(Windows)
+    {
+    case 'D':
+    {
+        D d = new D();
+        d.i = i;
+        return d;
+    }
+    case 'E':
+    {
+        E e = new E();
+        e.i = i;
+        return e;
+    }
+    }
+    default:
+        return null;
+    }
+}
+
+B createBFromD(char type, int i)
+{
+    switch (type)
+    {
+    case 'B':
+    {
+        B b = new B();
+        b.i = i;
+        return b;
+    }
+    case 'C':
+    {
+        C c = new C();
+        c.i = i;
+        return c;
+    }
+    version(Windows)
+    {
+    case 'D':
+    {
+        D d = new D();
+        d.i = i;
+        return d;
+    }
+    case 'E':
+    {
+        E e = new E();
+        e.i = i;
+        return e;
+    }
+    }
+    default:
+        return null;
+    }
+}
+
+C createCFromD(int i)
+{
+    C c = new C();
+    c.i = i;
+    return c;
+}
+
+version(Windows)
+{
+D createDFromD(int i)
+{
+    D d = new D();
+    d.i = i;
+    return d;
+}
+
+E createEFromD(int i)
+{
+    E e = new E();
+    e.i = i;
+    return e;
+}
+}
+
+void runCPPTests();
+
+extern(D) void main()
+{
+    {
+        B b = new B();
+        b.i = 100;
+        assert(b.f1() == 121);
+        assert(b.f2() == 122);
+        assert(b.f3() == 123);
+        assert(b.f4().i == 124);
+    }
+    {
+        C c = new C();
+        c.i = 100;
+        assert(c.f1() == 131);
+        assert(c.f2() == 132);
+        assert(c.f3() == 133);
+        assert(c.f4().i == 134);
+    }
+    version(Windows)
+    {
+    {
+        D d = new D();
+        d.i = 100;
+        assert(d.f1() == 141);
+        assert(d.f2() == 142);
+        assert(d.f3() == 143);
+        assert(d.f4().i == 144);
+    }
+    {
+        E e = new E();
+        e.i = 100;
+        assert(e.f1() == 151);
+        assert(e.f2() == 152);
+        assert(e.f3() == 153);
+        assert(e.f4().i == 154);
+    }
+    }
+    {
+        I i = createIFromCPP('B', 100);
+        assert(i.f2() == 122);
+        assert(i.f4().i == 124);
+    }
+    {
+        I i = createIFromCPP('C', 100);
+        assert(i.f2() == 132);
+        assert(i.f4().i == 134);
+    }
+    version(Windows)
+    {
+    {
+        I i = createIFromCPP('D', 100);
+        assert(i.f2() == 142);
+        assert(i.f4().i == 144);
+    }
+    {
+        I i = createIFromCPP('E', 100);
+        assert(i.f2() == 152);
+        assert(i.f4().i == 154);
+    }
+    }
+    {
+        B b = createBFromCPP('B', 100);
+        assert(b.f1() == 121);
+        assert(b.f2() == 122);
+        assert(b.f3() == 123);
+        assert(b.f4().i == 124);
+    }
+    {
+        B b = createBFromCPP('C', 100);
+        assert(b.f1() == 131);
+        assert(b.f2() == 132);
+        assert(b.f3() == 133);
+        assert(b.f4().i == 134);
+    }
+    version(Windows)
+    {
+    {
+        B b = createBFromCPP('D', 100);
+        assert(b.f1() == 141);
+        assert(b.f2() == 142);
+        assert(b.f3() == 143);
+        assert(b.f4().i == 144);
+    }
+    {
+        B b = createBFromCPP('E', 100);
+        assert(b.f1() == 151);
+        assert(b.f2() == 152);
+        assert(b.f3() == 153);
+        assert(b.f4().i == 154);
+    }
+    }
+    {
+        C c = createCFromCPP(100);
+        assert(c.f1() == 131);
+        assert(c.f2() == 132);
+        assert(c.f3() == 133);
+        assert(c.f4().i == 134);
+    }
+    version(Windows)
+    {
+    {
+        D d = createDFromCPP(100);
+        assert(d.f1() == 141);
+        assert(d.f2() == 142);
+        assert(d.f3() == 143);
+        assert(d.f4().i == 144);
+    }
+    {
+        E e = createEFromCPP(100);
+        assert(e.f1() == 151);
+        assert(e.f2() == 152);
+        assert(e.f3() == 153);
+        assert(e.f4().i == 154);
+    }
+    }
+    runCPPTests();
+}