Hi,

This patch merges the dmd frontend implementation with upstream dmd
6e44734cc, and the libdruntime sub-directory with upstream druntime
cb1583b4.

The patch has been split up into separate commits, so that all PRs
fixed are individually referenced with the part of the patch that
addresses that issue.

Listing the PRs in numerical order.

PR d/90559  (r272351)
PR d/90560  (r272348)
PR d/90650  (r272344)
PR d/90651  (r272345)
PR d/90602  (r272342)
PR d/90604  (r272343)
PR d/90651  (r272340)
PR d/90660  (r272339)
PR d/90661  (r272341)
PR d/90761  (r272346)
PR d/90762  (r272347)
PR d/90863  (r272352)

Bootstrapped and regression tested on x86_64-linux-gnu.

Committed to trunk.

-- 
Iain
---
2019-06-16  Iain Buclaw  <ibuc...@gdcproject.org>

gcc/d/ChangeLog:
        PR d/90559
        * d-target.cc (Target::_init): Reduce max static data size to INT_MAX.

        PR d/90651
        * typeinfo.cc (object_module): New variable.
        (make_frontend_typeinfo): Update signature.  Set temporary on
        generated TypeInfo classes.
        (create_tinfo_types): Set object_module.  Move generation of front-end
        typeinfo into ...
        (create_frontend_tinfo_types): ... New function.
        (layout_typeinfo): Call create_frontend_tinfo_types.
        (layout_classinfo): Likewise.
        (layout_cpp_typeinfo): Likewise.
        (create_typeinfo): Likewise.

gcc/testsuite/ChangeLog:
        PR d/90650
        * gdc.dg/pr90650a.d: New test.
        * gdc.dg/pr90650b.d: New test.

---
commit b5e4c44129acca5d6958c06b0ad6754f8a3763fc

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272352 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 4111fc97044..0620a5ba556 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-7afcc60c30554e452eacdfbefc4951ebf601fccd
+6e44734ccbeb78252a52e129a67fefb313679948
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/blockexit.c b/gcc/d/dmd/blockexit.c
index e9d3f105429..c3b60b88216 100644
--- a/gcc/d/dmd/blockexit.c
+++ b/gcc/d/dmd/blockexit.c
@@ -496,6 +496,8 @@ int blockExit(Statement *s, FuncDeclaration *func, bool mustNotThrow)
         }
     };
 
+    if (!s)
+        return BEfallthru;
     BlockExit be(func, mustNotThrow);
     s->accept(&be);
     return be.result;
diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c
index 167836c0478..143864dc666 100644
--- a/gcc/d/dmd/statementsem.c
+++ b/gcc/d/dmd/statementsem.c
@@ -2035,7 +2035,7 @@ public:
         ss->_body = semantic(ss->_body, sc);
         sc->noctor--;
 
-        if (conditionError || ss->_body->isErrorStatement())
+        if (conditionError || (ss->_body && ss->_body->isErrorStatement()))
             goto Lerror;
 
         // Resolve any goto case's with exp
@@ -2111,7 +2111,7 @@ public:
         {
             ss->hasNoDefault = 1;
 
-            if (!ss->isFinal && !ss->_body->isErrorStatement())
+            if (!ss->isFinal && (!ss->_body || !ss->_body->isErrorStatement()))
                 ss->error("switch statement without a default; use 'final switch' or add 'default: assert(0);' or add 'default: break;'");
 
             // Generate runtime error if the default is hit
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19955.d b/gcc/testsuite/gdc.test/fail_compilation/fail19955.d
new file mode 100644
index 00000000000..7cdce2c676a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19955.d
@@ -0,0 +1,8 @@
+// PERMUTE_ARGS:
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19955.d(8): Error: `switch` statement without a `default`; use `final switch` or add `default: assert(0);` or add `default: break;`
+---
+*/
+void f() { switch(1) static assert(1); }

commit 960d7913321bce56e4cb16c38500f6c8b1291853

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272351 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index e0cfbafe0b9..8d85534f054 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -140,8 +140,9 @@ Target::_init (void)
   /* Size of run-time TypeInfo object.  */
   Target::classinfosize = 19 * Target::ptrsize;
 
-  /* Allow data sizes up to half of the address space.  */
-  Target::maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
+  /* Much of the dmd front-end uses ints for sizes and offsets, and cannot
+     handle any larger data type without some pervasive rework.  */
+  Target::maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (integer_type_node));
 
   /* Define what type to use for size_t, ptrdiff_t.  */
   if (POINTER_SIZE == 64)
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 01c8cb0325d..4111fc97044 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-f8e38c001b9d7bd6586ee5b3dab7f7f199a69be7
+7afcc60c30554e452eacdfbefc4951ebf601fccd
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/clone.c b/gcc/d/dmd/clone.c
index d9a9055cb99..45b4e00a68c 100644
--- a/gcc/d/dmd/clone.c
+++ b/gcc/d/dmd/clone.c
@@ -841,12 +841,7 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
         {
             // __ArrayPostblit((cast(S*)this.v.ptr)[0 .. n])
 
-            uinteger_t n = 1;
-            while (tv->ty == Tsarray)
-            {
-                n *= ((TypeSArray *)tv)->dim->toUInteger();
-                tv = tv->nextOf()->toBasetype();
-            }
+            uinteger_t n = tv->numberOfElems(loc);
             if (n == 0)
                 continue;
 
@@ -898,12 +893,7 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
         {
             // __ArrayDtor((cast(S*)this.v.ptr)[0 .. n])
 
-            uinteger_t n = 1;
-            while (tv->ty == Tsarray)
-            {
-                n *= ((TypeSArray *)tv)->dim->toUInteger();
-                tv = tv->nextOf()->toBasetype();
-            }
+            uinteger_t n = tv->numberOfElems(loc);
             //if (n == 0)
             //    continue;
 
@@ -1049,12 +1039,7 @@ FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc)
         {
             // __ArrayDtor((cast(S*)this.v.ptr)[0 .. n])
 
-            uinteger_t n = 1;
-            while (tv->ty == Tsarray)
-            {
-                n *= ((TypeSArray *)tv)->dim->toUInteger();
-                tv = tv->nextOf()->toBasetype();
-            }
+            uinteger_t n = tv->numberOfElems(loc);
             if (n == 0)
                 continue;
 
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 2957c09ca62..88c59a9045b 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -5851,16 +5851,8 @@ public:
                 if (exp->op != TOKassign)
                 {
                     // If multidimensional static array, treat as one large array
-                    dinteger_t dim = ((TypeSArray *)t1)->dim->toInteger();
-                    Type *t = t1;
-                    while (1)
-                    {
-                        t = t->nextOf()->toBasetype();
-                        if (t->ty != Tsarray)
-                            break;
-                        dim *= ((TypeSArray *)t)->dim->toInteger();
-                        e1x->type = t->nextOf()->sarrayOf(dim);
-                    }
+                    dinteger_t dim = t1->numberOfElems(exp->loc);
+                    e1x->type = t1->baseElemOf()->sarrayOf(dim);
                 }
                 SliceExp *sle = new SliceExp(e1x->loc, e1x, NULL, NULL);
                 sle->arrayop = true;
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 2b1c5a197e2..906fb11b634 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -2517,6 +2517,33 @@ void Type::checkComplexTransition(Loc loc)
     }
 }
 
+/*******************************************
+ * Compute number of elements for a (possibly multidimensional) static array,
+ * or 1 for other types.
+ * Params:
+ *  loc = for error message
+ * Returns:
+ *  number of elements, uint.max on overflow
+ */
+unsigned Type::numberOfElems(const Loc &loc)
+{
+  //printf("Type::numberOfElems()\n");
+  uinteger_t n = 1;
+  Type *tb = this;
+  while ((tb = tb->toBasetype())->ty == Tsarray)
+    {
+      bool overflow = false;
+      n = mulu(n, ((TypeSArray *)tb)->dim->toUInteger(), overflow);
+      if (overflow || n >= UINT32_MAX)
+      {
+          error(loc, "static array `%s` size overflowed to %llu", toChars(), (unsigned long long)n);
+          return UINT32_MAX;
+      }
+      tb = ((TypeSArray *)tb)->next;
+    }
+  return (unsigned)n;
+}
+
 /****************************************
  * Return the mask that an integral type will
  * fit into.
@@ -3900,25 +3927,17 @@ Type *TypeSArray::syntaxCopy()
 d_uns64 TypeSArray::size(Loc loc)
 {
     //printf("TypeSArray::size()\n");
-    dinteger_t sz;
-    if (!dim)
-        return Type::size(loc);
-    sz = dim->toInteger();
-
+    uinteger_t n = numberOfElems(loc);
+    uinteger_t elemsize = baseElemOf()->size();
+    bool overflow = false;
+    uinteger_t sz = mulu(n, elemsize, overflow);
+    if (overflow || sz >= UINT32_MAX)
     {
-        bool overflow = false;
-
-        sz = mulu(next->size(), sz, overflow);
-        if (overflow)
-            goto Loverflow;
+        if (elemsize != SIZE_INVALID && n != UINT32_MAX)
+            error(loc, "static array `%s` size overflowed to %lld", toChars(), (long long)sz);
+        return SIZE_INVALID;
     }
-    if (sz > UINT32_MAX)
-        goto Loverflow;
     return sz;
-
-Loverflow:
-    error(loc, "static array %s size overflowed to %lld", toChars(), (long long)sz);
-    return SIZE_INVALID;
 }
 
 unsigned TypeSArray::alignsize()
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index f1e357a3b18..aab0d034cf0 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -332,6 +332,7 @@ public:
     virtual Type *nextOf();
     Type *baseElemOf();
     uinteger_t sizemask();
+    unsigned numberOfElems(const Loc &loc);
     virtual bool needsDestruction();
     virtual bool needsNested();
     void checkComplexTransition(Loc loc);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/staticarrayoverflow.d b/gcc/testsuite/gdc.test/fail_compilation/staticarrayoverflow.d
index 8743bf1993e..f419869236b 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/staticarrayoverflow.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/staticarrayoverflow.d
@@ -2,11 +2,14 @@
 REQUIRED_ARGS: -m64
 PERMUTE_ARGS:
 ---
-fail_compilation/staticarrayoverflow.d(21): Error: static array S[1879048192] size overflowed to 7516192768000
-fail_compilation/staticarrayoverflow.d(21): Error: variable staticarrayoverflow.y size overflow
-fail_compilation/staticarrayoverflow.d(22): Error: variable staticarrayoverflow.z size of x1000ae0 exceeds max allowed size 0x100_0000
-fail_compilation/staticarrayoverflow.d(23): Error: static array S[8070450532247928832] size overflowed to 0
-fail_compilation/staticarrayoverflow.d(23): Error: variable staticarrayoverflow.a size overflow
+fail_compilation/staticarrayoverflow.d(24): Error: static array `S[1879048192]` size overflowed to 7516192768000
+fail_compilation/staticarrayoverflow.d(24): Error: variable `staticarrayoverflow.y` size overflow
+fail_compilation/staticarrayoverflow.d(26): Error: static array `S[8070450532247928832]` size overflowed to 8070450532247928832
+fail_compilation/staticarrayoverflow.d(26): Error: variable `staticarrayoverflow.a` size overflow
+fail_compilation/staticarrayoverflow.d(27): Error: static array `S[0][18446744073709551615LU]` size overflowed to 18446744073709551615
+fail_compilation/staticarrayoverflow.d(27): Error: variable `staticarrayoverflow.b` size overflow
+fail_compilation/staticarrayoverflow.d(28): Error: static array `S[0][4294967295]` size overflowed to 4294967295
+fail_compilation/staticarrayoverflow.d(28): Error: variable `staticarrayoverflow.c` size overflow
 ---
 */
 
@@ -20,4 +23,5 @@ struct S
 S[0x7000_0000] y;
 S[0x100_0000/(4*1000 - 1)] z;
 S[0x7000_0000_0000_0000] a;
-
+S[0][-1] b;
+S[0][uint.max] c;

commit 160733ff9857ea6b430e9205452df5228b9e4715

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272350 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 03005e3b1ce..01c8cb0325d 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-9746504883fc64f3dcec0cd4cacbb7a372d52158
+f8e38c001b9d7bd6586ee5b3dab7f7f199a69be7
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c
index 0dc5e77b410..167836c0478 100644
--- a/gcc/d/dmd/statementsem.c
+++ b/gcc/d/dmd/statementsem.c
@@ -773,16 +773,48 @@ public:
                         goto Lerror2;
                     }
 
+                    // Finish semantic on all foreach parameter types.
+                    for (size_t i = 0; i < dim; i++)
+                    {
+                        Parameter *p = (*fs->parameters)[i];
+                        p->type = p->type->semantic(loc, sc2);
+                        p->type = p->type->addStorageClass(p->storageClass);
+                    }
+
+                    tn = tab->nextOf()->toBasetype();
+
+                    if (dim == 2)
+                    {
+                        Type *tindex = (*fs->parameters)[0]->type;
+                        if (!tindex->isintegral())
+                        {
+                            fs->error("foreach: key cannot be of non-integral type `%s`",
+                                      tindex->toChars());
+                            goto Lerror2;
+                        }
+                        /* What cases to deprecate implicit conversions for:
+                         *  1. foreach aggregate is a dynamic array
+                         *  2. foreach body is lowered to _aApply (see special case below).
+                         */
+                        Type *tv = (*fs->parameters)[1]->type->toBasetype();
+                        if ((tab->ty == Tarray ||
+                             (tn->ty != tv->ty &&
+                              (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) &&
+                              (tv->ty == Tchar || tv->ty == Twchar || tv->ty == Tdchar))) &&
+                            !Type::tsize_t->implicitConvTo(tindex))
+                        {
+                            fs->deprecation("foreach: loop index implicitly converted from `size_t` to `%s`",
+                                            tindex->toChars());
+                        }
+                    }
+
                     /* Look for special case of parsing char types out of char type
                      * array.
                      */
-                    tn = tab->nextOf()->toBasetype();
                     if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
                     {
                         int i = (dim == 1) ? 0 : 1;     // index of value
                         Parameter *p = (*fs->parameters)[i];
-                        p->type = p->type->semantic(loc, sc2);
-                        p->type = p->type->addStorageClass(p->storageClass);
                         tnv = p->type->toBasetype();
                         if (tnv->ty != tn->ty &&
                             (tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar))
@@ -809,8 +841,6 @@ public:
                     {
                         // Declare parameterss
                         Parameter *p = (*fs->parameters)[i];
-                        p->type = p->type->semantic(loc, sc2);
-                        p->type = p->type->addStorageClass(p->storageClass);
                         VarDeclaration *var;
 
                         if (dim == 2 && i == 0)
@@ -908,6 +938,10 @@ public:
                         fs->key = new VarDeclaration(loc, Type::tsize_t, idkey, NULL);
                         fs->key->storage_class |= STCtemp;
                     }
+                    else if (fs->key->type->ty != Tsize_t)
+                    {
+                        tmp_length = new CastExp(loc, tmp_length, fs->key->type);
+                    }
                     if (fs->op == TOKforeach_reverse)
                         fs->key->_init = new ExpInitializer(loc, tmp_length);
                     else
diff --git a/gcc/testsuite/gdc.test/compilable/b16976.d b/gcc/testsuite/gdc.test/compilable/b16976.d
new file mode 100644
index 00000000000..f5f45ef9076
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/b16976.d
@@ -0,0 +1,66 @@
+/* REQUIRED_ARGS: -m64
+TEST_OUTPUT:
+---
+compilable/b16976.d(33): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(34): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(35): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+compilable/b16976.d(36): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+compilable/b16976.d(41): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(42): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(43): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+compilable/b16976.d(44): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+compilable/b16976.d(50): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(51): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(52): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+compilable/b16976.d(53): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+compilable/b16976.d(58): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(59): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(60): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+compilable/b16976.d(61): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+compilable/b16976.d(62): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(63): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
+compilable/b16976.d(64): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+compilable/b16976.d(65): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
+---
+*/
+void main()
+{
+    int[]  dyn = [1,2,3,4,5];
+    int[5] sta = [1,2,3,4,5];
+    char[]  str = ['1','2','3','4','5'];
+    char[5] chr = ['1','2','3','4','5'];
+
+    foreach(int i, v; dyn) { }
+    foreach_reverse(int i, v; dyn) { }
+    foreach(char i, v; dyn) { }
+    foreach_reverse(char i, v; dyn) { }
+    foreach(int i, v; sta) { }
+    foreach_reverse(int i, v; sta) { }
+    foreach(char i, v; sta) { }
+    foreach_reverse(char i, v; sta) { }
+    foreach(int i, v; str) { }
+    foreach_reverse(int i, v; str) { }
+    foreach(char i, v; str) { }
+    foreach_reverse(char i, v; str) { }
+    foreach(int i, v; chr) { }
+    foreach_reverse(int i, v; chr) { }
+    foreach(char i, v; chr) { }
+    foreach_reverse(char i, v; chr) { }
+
+    foreach(int i, dchar v; dyn) { }
+    foreach_reverse(int i, dchar v; dyn) { }
+    foreach(char i, dchar v; dyn) { }
+    foreach_reverse(char i, dchar v; dyn) { }
+    foreach(int i, dchar v; sta) { }
+    foreach_reverse(int i, dchar v; sta) { }
+    foreach(char i, dchar v; sta) { }
+    foreach_reverse(char i, dchar v; sta) { }
+    foreach(int i, dchar v; str) { }
+    foreach_reverse(int i, dchar v; str) { }
+    foreach(char i, dchar v; str) { }
+    foreach_reverse(char i, dchar v; str) { }
+    foreach(int i, dchar v; chr) { }
+    foreach_reverse(int i, dchar v; chr) { }
+    foreach(char i, dchar v; chr) { }
+    foreach_reverse(char i, dchar v; chr) { }
+}
diff --git a/gcc/testsuite/gdc.test/compilable/interpret3.d b/gcc/testsuite/gdc.test/compilable/interpret3.d
index 386743e6ddc..36cdd13148b 100644
--- a/gcc/testsuite/gdc.test/compilable/interpret3.d
+++ b/gcc/testsuite/gdc.test/compilable/interpret3.d
@@ -3396,13 +3396,13 @@ bool test3512()
     assert(q == 6);
 
     // _aApplycw2
-    foreach (int i, wchar c; s)
+    foreach (ptrdiff_t i, wchar c; s)
     {
         assert(i >= 0 && i < s.length);
     }
 
     // _aApplycd2
-    foreach (int i, dchar c; s)
+    foreach (ptrdiff_t i, dchar c; s)
     {
         assert(i >= 0 && i < s.length);
     }
@@ -3424,13 +3424,13 @@ bool test3512()
     assert(q == 13);
 
     // _aApplywc2
-    foreach (int i, char c; w)
+    foreach (ptrdiff_t i, char c; w)
     {
         assert(i >= 0 && i < w.length);
     }
 
     // _aApplywd2
-    foreach (int i, dchar c; w)
+    foreach (ptrdiff_t i, dchar c; w)
     {
         assert(i >= 0 && i < w.length);
     }
@@ -3454,19 +3454,19 @@ bool test3512()
     assert(q == 3);
 
     // _aApplydc2
-    foreach (int i, char c; d)
+    foreach (ptrdiff_t i, char c; d)
     {
         assert(i >= 0 && i < d.length);
     }
     // _aApplydw2
-    foreach (int i, wchar c; d)
+    foreach (ptrdiff_t i, wchar c; d)
     {
         assert(i >= 0 && i < d.length);
     }
 
     dchar[] dr = "squop"d.dup;
 
-    foreach (int n, char c; dr)
+    foreach (ptrdiff_t n, char c; dr)
     {
         if (n == 2)
             break;
@@ -3482,7 +3482,7 @@ bool test3512()
     {}
 
     // _aApplyRdc2
-    foreach_reverse (int n, char c; dr)
+    foreach_reverse (ptrdiff_t n, char c; dr)
     {
         if (n == 4)
             break;
@@ -3490,14 +3490,14 @@ bool test3512()
     }
 
     // _aApplyRdw2
-    foreach_reverse (int i, wchar c; dr)
+    foreach_reverse (ptrdiff_t i, wchar c; dr)
     {
         assert(i >= 0 && i < dr.length);
     }
 
     q = 0;
     wstring w2 = ['x', 'ΓΌ', 'm']; // foreach over array literals
-    foreach_reverse (int n, char c; w2)
+    foreach_reverse (ptrdiff_t n, char c; w2)
     {
         ++q;
         if (c == 'm') assert(n == 2 && q == 1);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16976.d b/gcc/testsuite/gdc.test/fail_compilation/diag16976.d
new file mode 100644
index 00000000000..ebfb72b493c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/diag16976.d
@@ -0,0 +1,44 @@
+/* TEST_OUTPUT:
+---
+fail_compilation/diag16976.d(28): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(29): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(30): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(31): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(32): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(33): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(34): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(35): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(36): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(37): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(38): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(39): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(40): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(41): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(42): Error: foreach: key cannot be of non-integral type `float`
+fail_compilation/diag16976.d(43): Error: foreach: key cannot be of non-integral type `float`
+---
+*/
+
+void main()
+{
+    int[]  dyn = [1,2,3,4,5];
+    int[5] sta = [1,2,3,4,5];
+    char[]  str = ['1','2','3','4','5'];
+    char[5] chr = ['1','2','3','4','5'];
+    foreach(float f, i; dyn) {}
+    foreach(float f, i; sta) {}
+    foreach(float f, i; str) {}
+    foreach(float f, i; chr) {}
+    foreach(float f, dchar i; dyn) {}
+    foreach(float f, dchar i; sta) {}
+    foreach(float f, dchar i; str) {}
+    foreach(float f, dchar i; chr) {}
+    foreach_reverse(float f, i; dyn) {}
+    foreach_reverse(float f, i; sta) {}
+    foreach_reverse(float f, i; str) {}
+    foreach_reverse(float f, i; chr) {}
+    foreach_reverse(float f, dchar i; dyn) {}
+    foreach_reverse(float f, dchar i; sta) {}
+    foreach_reverse(float f, dchar i; str) {}
+    foreach_reverse(float f, dchar i; chr) {}
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail110.d b/gcc/testsuite/gdc.test/fail_compilation/fail110.d
index 3e9beb02121..47034019ea8 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail110.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail110.d
@@ -14,6 +14,6 @@ void main()
     int i;
     int[] a;
     foreach (i; a) {}
-    foreach (int i, n; a) {}
+    foreach (size_t i, n; a) {}
     for (int i;;) {}
 }
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index dec75f7cb33..a142195c62f 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-aab44549221cb29434fe2feccaf1174af54dd79d
+cb1583b4b7313bb6d79a5102b6c91e71f5181b19
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/druntime repository.
diff --git a/libphobos/libdruntime/rt/minfo.d b/libphobos/libdruntime/rt/minfo.d
index 548bcc71c60..47228663562 100644
--- a/libphobos/libdruntime/rt/minfo.d
+++ b/libphobos/libdruntime/rt/minfo.d
@@ -125,7 +125,7 @@ struct ModuleGroup
                     break;
             distloop:
                 // search for next (previous) module in cycle.
-                foreach (int m, d; distance)
+                foreach (m, d; distance)
                 {
                     if (d == curdist)
                     {
@@ -470,7 +470,7 @@ struct ModuleGroup
             // pre-allocate enough space to hold all modules.
             ctors = (cast(immutable(ModuleInfo)**).malloc(len * (void*).sizeof));
             ctoridx = 0;
-            foreach (int idx, m; _modules)
+            foreach (idx, m; _modules)
             {
                 if (m.flags & relevantFlags)
                 {
@@ -582,8 +582,8 @@ struct ModuleGroup
         }
 
         // initialize the initial edges
-        foreach (int i, ref v; initialEdges)
-            v = i;
+        foreach (i, ref v; initialEdges)
+            v = cast(int)i;
 
         bool sort(ref immutable(ModuleInfo)*[] ctors, uint mask)
         {

commit fe275d8df5b5eb224de253f225ca898be2bfff48

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272349 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 3e3e718c11b..03005e3b1ce 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-c6887d9bbbe7b68e03ba3bccbf61432c1b369386
+9746504883fc64f3dcec0cd4cacbb7a372d52158
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/declaration.c b/gcc/d/dmd/declaration.c
index d0911e21858..2a054306347 100644
--- a/gcc/d/dmd/declaration.c
+++ b/gcc/d/dmd/declaration.c
@@ -830,6 +830,11 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
     this->sequenceNumber = ++nextSequenceNumber;
 }
 
+VarDeclaration *VarDeclaration::create(Loc loc, Type *type, Identifier *id, Initializer *init)
+{
+    return new VarDeclaration(loc, type, id, init);
+}
+
 Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
 {
     //printf("VarDeclaration::syntaxCopy(%s)\n", toChars());
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 16da7ea8428..e3444a70fd8 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -265,6 +265,7 @@ public:
     IntRange *range;            // if !NULL, the variable is known to be within the range
 
     VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init);
+    static VarDeclaration *create(Loc loc, Type *t, Identifier *id, Initializer *init);
     Dsymbol *syntaxCopy(Dsymbol *);
     void semantic(Scope *sc);
     void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);

commit 29114029735e849d60f0de254ba811a0a4d82486

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272348 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 36f9aa9c241..3e3e718c11b 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-b0cd591770fefb4db6eaba89b7a548ef1e980f5c
+c6887d9bbbe7b68e03ba3bccbf61432c1b369386
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 1757b498deb..2b1c5a197e2 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -4134,8 +4134,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
              * when the bottom of element type is opaque.
              */
         }
-        else if (tbn->isintegral() ||
-                 tbn->isfloating() ||
+        else if (tbn->isTypeBasic() ||
                  tbn->ty == Tpointer ||
                  tbn->ty == Tarray ||
                  tbn->ty == Tsarray ||
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19890a.d b/gcc/testsuite/gdc.test/fail_compilation/fail19890a.d
new file mode 100644
index 00000000000..57c4caf34ab
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19890a.d
@@ -0,0 +1,7 @@
+// PERMUTE_ARGS:
+/*
+---
+fail_compilation/fail19890a.d(8): Error: `void[/^[0-9]+(LU)?$/]` size 1 * /^[0-9]+$/ exceeds 0x7fffffff size limit for static array
+---
+*/
+void[] f = cast(void[-1]) "a";
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19890b.d b/gcc/testsuite/gdc.test/fail_compilation/fail19890b.d
new file mode 100644
index 00000000000..a9b18741833
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19890b.d
@@ -0,0 +1,7 @@
+// PERMUTE_ARGS:
+/*
+---
+fail_compilation/fail19890b.d(8): Error: `void[/^[0-9]+(LU)?$/]` size 1 * /^[0-9]+$/ exceeds 0x7fffffff size limit for static array
+---
+*/
+void[] f = cast(void[-2]) "a";

commit 6e9d3f411d9960a98398e3cdea02f34424aa9aea

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272347 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 865462d64fb..36f9aa9c241 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-d912f4e495412b67f0a2e3b07f645909cfee0212
+b0cd591770fefb4db6eaba89b7a548ef1e980f5c
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c
index ccf141ebb09..0dc5e77b410 100644
--- a/gcc/d/dmd/statementsem.c
+++ b/gcc/d/dmd/statementsem.c
@@ -3492,12 +3492,18 @@ public:
             }
 
             s->semantic(sc);
-            Module::addDeferredSemantic2(s);     // Bugzilla 14666
-            sc->insert(s);
-
-            for (size_t j = 0; j < s->aliasdecls.dim; j++)
+            // https://issues.dlang.org/show_bug.cgi?id=19942
+            // If the module that's being imported doesn't exist, don't add it to the symbol table
+            // for the current scope.
+            if (s->mod != NULL)
             {
-                sc->insert(s->aliasdecls[j]);
+                Module::addDeferredSemantic2(s);     // Bugzilla 14666
+                sc->insert(s);
+
+                for (size_t j = 0; j < s->aliasdecls.dim; j++)
+                {
+                    sc->insert(s->aliasdecls[j]);
+                }
             }
         }
         result = imps;
diff --git a/gcc/testsuite/gdc.test/compilable/traits.d b/gcc/testsuite/gdc.test/compilable/traits.d
new file mode 100644
index 00000000000..736eae4a89d
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/traits.d
@@ -0,0 +1,10 @@
+// REQUIRED_ARGS:
+
+// This file is intended to contain all compilable traits-related tests in an
+// effort to keep the number of files in the `compilable` folder to a minimum.
+
+/******************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19942
+
+static assert(!__traits(compiles, { a.init; }));
+static assert(!__traits(compiles, { import m : a; a.init; }));

commit d623e50d975a1e3bfa47a05926380a9f61803a23

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272346 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 7b46e8f3da0..865462d64fb 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-3be8a80bb0c4e01c436be970ac3555ceabb3caf8
+d912f4e495412b67f0a2e3b07f645909cfee0212
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 5177f9f6449..2957c09ca62 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -75,6 +75,7 @@ Expression *semantic(Expression *e, Scope *sc);
 Expression *semanticY(DotIdExp *exp, Scope *sc, int flag);
 Expression *semanticY(DotTemplateInstanceExp *exp, Scope *sc, int flag);
 StringExp *semanticString(Scope *sc, Expression *exp, const char *s);
+Initializer *semantic(Initializer *init, Scope *sc, Type *t, NeedInterpret needInterpret);
 
 /****************************************
  * Preprocess arguments to function.
@@ -1226,6 +1227,23 @@ public:
                     exp->error("no constructor for %s", cd->toChars());
                     return setError();
                 }
+
+                // https://issues.dlang.org/show_bug.cgi?id=19941
+                // Run semantic on all field initializers to resolve any forward
+                // references. This is the same as done for structs in sd->fill().
+                for (ClassDeclaration *c = cd; c; c = c->baseClass)
+                {
+                    for (size_t i = 0; i < c->fields.dim; i++)
+                    {
+                        VarDeclaration *v = c->fields[i];
+                        if (v->inuse || v->_scope == NULL || v->_init == NULL ||
+                            v->_init->isVoidInitializer())
+                            continue;
+                        v->inuse++;
+                        v->_init = semantic(v->_init, v->_scope, v->type, INITinterpret);
+                        v->inuse--;
+                    }
+                }
             }
         }
         else if (tb->ty == Tstruct)
diff --git a/gcc/testsuite/gdc.test/compilable/test19941.d b/gcc/testsuite/gdc.test/compilable/test19941.d
new file mode 100644
index 00000000000..add1d417b6f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test19941.d
@@ -0,0 +1,57 @@
+// https://issues.dlang.org/show_bug.cgi?id=19941
+
+/******************************************/
+
+immutable i4 = 42;
+const v4 = new C4;
+class C4 { int f4 = i4; }
+
+const v5 = new C5;
+immutable i5 = 42;
+class C5 { int f5 = i5; }
+
+const v6 = new C6;
+class C6 { int f6 = i6; }
+immutable i6 = 42;
+
+/******************************************/
+
+immutable i10 = 42;
+__gshared v10 = new C10;
+class C10 { int f10 = i10; }
+
+__gshared v11 = new C11;
+immutable i11 = 42;
+class C11 { int f11 = i11; }
+
+__gshared v12 = new C12;
+class C12 { int f12 = i12; }
+immutable i12 = 42;
+
+/******************************************/
+
+immutable i13 = 42;
+immutable v13 = new C13;
+class C13 { int f13 = i13; }
+
+immutable v14 = new C14;
+immutable i14 = 42;
+class C14 { int f14 = i14; }
+
+immutable v15 = new C15;
+class C15 { int f15 = i15; }
+immutable i15 = 42;
+
+/******************************************/
+
+immutable i16 = 42;
+shared v16 = new C16;
+class C16 { int f16 = i16; }
+
+shared v17 = new C17;
+immutable i17 = 42;
+class C17 { int f17 = i17; }
+
+shared v18 = new C18;
+class C18 { int f18 = i18; }
+immutable i18 = 42;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19941.d b/gcc/testsuite/gdc.test/fail_compilation/fail19941.d
new file mode 100644
index 00000000000..61e174b27fe
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19941.d
@@ -0,0 +1,62 @@
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19941.d(8): Error: undefined identifier `dne`
+---
+*/
+auto a = new Auto;
+class Auto { int field = &dne; }
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19941.d(17): Error: undefined identifier `dne`
+---
+*/
+const c = new Const;
+class Const { int field = &dne; }
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19941.d(26): Error: undefined identifier `dne`
+---
+*/
+enum e = new Enum;
+class Enum { int field = &dne; }
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19941.d(35): Error: undefined identifier `dne`
+---
+*/
+__gshared g = new Gshared;
+class Gshared { int field = &dne; }
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19941.d(44): Error: undefined identifier `dne`
+---
+*/
+immutable i = new Immutable;
+class Immutable { int field = &dne; }
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19941.d(53): Error: undefined identifier `dne`
+---
+*/
+shared s = new Shared;
+class Shared { int field = &dne; }
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19941.d(62): Error: undefined identifier `dne`
+---
+*/
+static t = new Static;
+class Static { int field = &dne; }

commit 985afcabdd7b48a461641f9b7d6ed25ec861d1fb

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272345 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 7258fadb1bb..7b46e8f3da0 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-ab03e2918508d62efcc5ee66c9a912a331b33aa0
+3be8a80bb0c4e01c436be970ac3555ceabb3caf8
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index ebdfae584c8..5177f9f6449 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -1806,11 +1806,19 @@ public:
         Expression *e;
         if (ea && ta->toBasetype()->ty == Tclass)
         {
-            /* Get the dynamic type, which is .classinfo
-            */
-            ea = semantic(ea, sc);
-            e = new TypeidExp(ea->loc, ea);
-            e->type = Type::typeinfoclass->type;
+            if (!Type::typeinfoclass)
+            {
+                error(exp->loc, "`object.TypeInfo_Class` could not be found, but is implicitly used");
+                e = new ErrorExp();
+            }
+            else
+            {
+                /* Get the dynamic type, which is .classinfo
+                */
+                ea = semantic(ea, sc);
+                e = new TypeidExp(ea->loc, ea);
+                e->type = Type::typeinfoclass->type;
+            }
         }
         else if (ta->ty == Terror)
         {
diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c
index 568decc8cee..04c70cf3b7b 100644
--- a/gcc/d/dmd/func.c
+++ b/gcc/d/dmd/func.c
@@ -1520,6 +1520,18 @@ void FuncDeclaration::semantic3(Scope *sc)
         {
             if (f->linkage == LINKd)
             {
+                // Variadic arguments depend on Typeinfo being defined
+                if (!global.params.useTypeInfo || !Type::dtypeinfo || !Type::typeinfotypelist)
+                {
+                    if (!global.params.useTypeInfo)
+                        error("D-style variadic functions cannot be used with -betterC");
+                    else if (!Type::typeinfotypelist)
+                        error("`object.TypeInfo_Tuple` could not be found, but is implicitly used in D-style variadic functions");
+                    else
+                        error("`object.TypeInfo` could not be found, but is implicitly used in D-style variadic functions");
+                    fatal();
+                }
+
                 // Declare _arguments[]
                 v_arguments = new VarDeclaration(Loc(), Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
                 v_arguments->storage_class |= STCtemp | STCparameter;
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 2562f364b49..1757b498deb 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -8350,7 +8350,12 @@ L1:
 
         if (ident == Id::classinfo)
         {
-            assert(Type::typeinfoclass);
+            if (!Type::typeinfoclass)
+            {
+                error(e->loc, "`object.TypeInfo_Class` could not be found, but is implicitly used");
+                return new ErrorExp();
+            }
+
             Type *t = Type::typeinfoclass->type;
             if (e->op == TOKtype || e->op == TOKdottype)
             {
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index 58c6ce1ba3c..25bdb42d762 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -185,28 +185,36 @@ make_internal_typeinfo (tinfo_kind tk, Identifier *ident, ...)
   va_end (ap);
 }
 
-/* Helper for create_tinfo_types.  Creates a typeinfo class declaration
-   incase one wasn't supplied by reading `object.d'.  */
+/* Reference to the `object` module, where all TypeInfo is defined.  */
+
+static Module *object_module;
+
+/* Helper for create_frontend_tinfo_types.  Creates a typeinfo class
+   declaration incase one wasn't supplied by reading `object.d'.  */
 
 static void
-make_frontend_typeinfo (Module *mod, Identifier *ident,
-			ClassDeclaration *base = NULL)
+make_frontend_typeinfo (Identifier *ident, ClassDeclaration *base = NULL)
 {
   if (!base)
     base = Type::dtypeinfo;
 
+  gcc_assert (object_module);
+
   /* Create object module in order to complete the semantic.  */
-  if (!mod->_scope)
-    mod->importAll (NULL);
+  if (!object_module->_scope)
+    object_module->importAll (NULL);
 
   /* Assignment of global typeinfo variables is managed by the ClassDeclaration
      constructor, so only need to new the declaration here.  */
-  Loc loc = (mod->md) ? mod->md->loc : mod->loc;
+  Loc loc = (object_module->md) ? object_module->md->loc : object_module->loc;
   ClassDeclaration *tinfo = ClassDeclaration::create (loc, ident, NULL, NULL,
 						      true);
-  tinfo->parent = mod;
-  tinfo->semantic (mod->_scope);
+  tinfo->parent = object_module;
+  tinfo->semantic (object_module->_scope);
   tinfo->baseClass = base;
+  /* This is a compiler generated class, and shouldn't be mistaken for being
+     the type declared in the runtime library.  */
+  tinfo->storage_class |= STCtemp;
 }
 
 /* Make sure the required builtin types exist for generating the TypeInfo
@@ -227,69 +235,78 @@ create_tinfo_types (Module *mod)
 			  ptr_type_node, d_uint_type, ptr_type_node,
 			  array_type_node, ptr_type_node, ptr_type_node, NULL);
 
+  object_module = mod;
+}
+
+/* Same as create_tinfo_types, but builds all front-end TypeInfo variable
+   definitions.  */
+
+static void
+create_frontend_tinfo_types (void)
+{
   /* If there's no Object class defined, then neither can TypeInfo be.  */
-  if (ClassDeclaration::object == NULL)
+  if (object_module == NULL || ClassDeclaration::object == NULL)
     return;
 
   /* Create all frontend TypeInfo classes declarations.  We rely on all
      existing, even if only just as stubs.  */
   if (!Type::dtypeinfo)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo"),
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo"),
 			    ClassDeclaration::object);
 
   if (!Type::typeinfoclass)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Class"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Class"));
 
   if (!Type::typeinfointerface)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Interface"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Interface"));
 
   if (!Type::typeinfostruct)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Struct"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Struct"));
 
   if (!Type::typeinfopointer)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Pointer"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Pointer"));
 
   if (!Type::typeinfoarray)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Array"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Array"));
 
   if (!Type::typeinfostaticarray)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_StaticArray"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_StaticArray"));
 
   if (!Type::typeinfoassociativearray)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_AssociativeArray"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_AssociativeArray"));
 
   if (!Type::typeinfoenum)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Enum"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Enum"));
 
   if (!Type::typeinfofunction)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Function"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Function"));
 
   if (!Type::typeinfodelegate)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Delegate"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Delegate"));
 
   if (!Type::typeinfotypelist)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Tuple"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Tuple"));
 
   if (!Type::typeinfoconst)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Const"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Const"));
 
   if (!Type::typeinfoinvariant)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Invariant"),
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Invariant"),
 			    Type::typeinfoconst);
 
   if (!Type::typeinfoshared)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Shared"),
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Shared"),
 			    Type::typeinfoconst);
 
   if (!Type::typeinfowild)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Wild"),
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Wild"),
 			    Type::typeinfoconst);
 
   if (!Type::typeinfovector)
-    make_frontend_typeinfo (mod, Identifier::idPool ("TypeInfo_Vector"));
+    make_frontend_typeinfo (Identifier::idPool ("TypeInfo_Vector"));
 
   if (!ClassDeclaration::cpp_type_info_ptr)
-    make_frontend_typeinfo (mod, Identifier::idPool ("__cpp_type_info_ptr"),
+    make_frontend_typeinfo (Identifier::idPool ("__cpp_type_info_ptr"),
 			    ClassDeclaration::object);
 }
 
@@ -1132,6 +1149,9 @@ public:
 tree
 layout_typeinfo (TypeInfoDeclaration *d)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   tree type = TREE_TYPE (get_typeinfo_decl (d));
   TypeInfoVisitor v = TypeInfoVisitor (type);
   d->accept (&v);
@@ -1144,6 +1164,9 @@ layout_typeinfo (TypeInfoDeclaration *d)
 tree
 layout_classinfo (ClassDeclaration *cd)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   TypeInfoClassDeclaration *d = TypeInfoClassDeclaration::create (cd->type);
   tree type = TREE_TYPE (get_classinfo_decl (cd));
   TypeInfoVisitor v = TypeInfoVisitor (type);
@@ -1366,6 +1389,9 @@ build_typeinfo (const Loc &loc, Type *type)
 void
 layout_cpp_typeinfo (ClassDeclaration *cd)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   gcc_assert (cd->isCPPclass ());
 
   tree decl = get_cpp_typeinfo_decl (cd);
@@ -1434,6 +1460,9 @@ get_cpp_typeinfo_decl (ClassDeclaration *decl)
 void
 create_typeinfo (Type *type, Module *mod)
 {
+  if (!Type::dtypeinfo)
+    create_frontend_tinfo_types ();
+
   /* Do this since not all Type's are merged.  */
   Type *t = type->merge2 ();
   Identifier *ident;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d b/gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d
new file mode 100644
index 00000000000..c7060b0d96c
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/extra-files/minimal/object.d
@@ -0,0 +1 @@
+module object;
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19911a.d b/gcc/testsuite/gdc.test/fail_compilation/fail19911a.d
new file mode 100644
index 00000000000..672db305223
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19911a.d
@@ -0,0 +1,11 @@
+/*
+REQUIRED_ARGS: -betterC
+TEST_OUTPUT:
+---
+fail_compilation/fail19911a.d(9): Error: function `fail19911a.fun` D-style variadic functions cannot be used with -betterC
+---
+*/
+
+void fun(...)
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19911b.d b/gcc/testsuite/gdc.test/fail_compilation/fail19911b.d
new file mode 100644
index 00000000000..b4ad22b0896
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19911b.d
@@ -0,0 +1,13 @@
+/* 
+DFLAGS:
+REQUIRED_ARGS:
+EXTRA_SOURCES: extra-files/minimal/object.d
+TEST_OUTPUT:
+---
+fail_compilation/fail19911b.d(10): Error: function `fail19911b.fun` `object.TypeInfo_Tuple` could not be found, but is implicitly used in D-style variadic functions
+---
+*/
+
+void fun(...)
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19911c.d b/gcc/testsuite/gdc.test/fail_compilation/fail19911c.d
new file mode 100644
index 00000000000..d1e954ed394
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19911c.d
@@ -0,0 +1,17 @@
+/* 
+DFLAGS:
+REQUIRED_ARGS:
+TEST_OUTPUT:
+---
+fail_compilation/fail19911c.d(15): Error: function `object.fun` `object.TypeInfo` could not be found, but is implicitly used in D-style variadic functions
+---
+*/
+
+module object;
+
+class Object { }
+class TypeInfo_Tuple { }
+
+void fun(...)
+{
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19922.d b/gcc/testsuite/gdc.test/fail_compilation/fail19922.d
new file mode 100644
index 00000000000..5c9e2bbe0ab
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19922.d
@@ -0,0 +1,19 @@
+/* 
+DFLAGS:
+REQUIRED_ARGS:
+TEST_OUTPUT:
+---
+fail_compilation/fail19922.d(17): Error: `object.TypeInfo_Class` could not be found, but is implicitly used
+---
+*/
+
+module object;
+
+class Object {}
+
+void test()
+{
+    Object o;
+    auto ti = typeid(o);
+}
+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19923.d b/gcc/testsuite/gdc.test/fail_compilation/fail19923.d
new file mode 100644
index 00000000000..042cf8af11a
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19923.d
@@ -0,0 +1,19 @@
+/* 
+DFLAGS:
+REQUIRED_ARGS:
+TEST_OUTPUT:
+---
+fail_compilation/fail19923.d(17): Error: `object.TypeInfo_Class` could not be found, but is implicitly used
+---
+*/
+
+module object;
+
+class Object {}
+
+void test()
+{
+    Object o;
+    auto ti = o.classinfo;
+}
+

commit 893318635f2e5c9adcd9e0e3637a1fc281bb34cb

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272344 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 4cb2bbac46d..7258fadb1bb 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-f30c5dc790c17914463879157447acc671518735
+ab03e2918508d62efcc5ee66c9a912a331b33aa0
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 19b7ccb7236..ebdfae584c8 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -2185,6 +2185,9 @@ public:
         }
         if (exp->e1->op == TOKslice || exp->e1->type->ty == Tarray || exp->e1->type->ty == Tsarray)
         {
+            if (checkNonAssignmentArrayOp(exp->e1))
+                return setError();
+
             if (exp->e1->op == TOKslice)
                 ((SliceExp *)exp->e1)->arrayop = true;
 
@@ -6232,6 +6235,9 @@ public:
         assert(exp->e1->type && exp->e2->type);
         if (exp->e1->op == TOKslice || exp->e1->type->ty == Tarray || exp->e1->type->ty == Tsarray)
         {
+            if (checkNonAssignmentArrayOp(exp->e1))
+                return setError();
+
             // T[] ^^= ...
             if (exp->e2->implicitConvTo(exp->e1->type->nextOf()))
             {
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index 058738ec825..2562f364b49 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -4468,6 +4468,8 @@ Expression *TypeDArray::dotExp(Scope *sc, Expression *e, Identifier *ident, int
         }
         if (e->op == TOKnull)
             return new IntegerExp(e->loc, 0, Type::tsize_t);
+        if (checkNonAssignmentArrayOp(e))
+            return new ErrorExp();
         e = new ArrayLengthExp(e->loc, e);
         e->type = Type::tsize_t;
         return e;
diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c
index 64cc42d9ce9..ccf141ebb09 100644
--- a/gcc/d/dmd/statementsem.c
+++ b/gcc/d/dmd/statementsem.c
@@ -95,6 +95,8 @@ public:
             s->exp = semantic(s->exp, sc);
             s->exp = resolveProperties(sc, s->exp);
             s->exp = s->exp->addDtorHook(sc);
+            if (checkNonAssignmentArrayOp(s->exp))
+                s->exp = new ErrorExp();
             if (FuncDeclaration *f = isFuncAddress(s->exp))
             {
                 if (f->checkForwardRef(s->exp->loc))
@@ -370,6 +372,8 @@ public:
 
         ds->condition = semantic(ds->condition, sc);
         ds->condition = resolveProperties(sc, ds->condition);
+        if (checkNonAssignmentArrayOp(ds->condition))
+            ds->condition = new ErrorExp();
         ds->condition = ds->condition->optimize(WANTvalue);
         ds->condition = checkGC(sc, ds->condition);
 
@@ -440,6 +444,8 @@ public:
 
             fs->condition = semantic(fs->condition, sc);
             fs->condition = resolveProperties(sc, fs->condition);
+            if (checkNonAssignmentArrayOp(fs->condition))
+                fs->condition = new ErrorExp();
             fs->condition = fs->condition->optimize(WANTvalue);
             fs->condition = checkGC(sc, fs->condition);
             fs->condition = fs->condition->toBoolean(sc);
@@ -450,6 +456,8 @@ public:
                 ((CommaExp *)fs->increment)->allowCommaExp = true;
             fs->increment = semantic(fs->increment, sc);
             fs->increment = resolveProperties(sc, fs->increment);
+            if (checkNonAssignmentArrayOp(fs->increment))
+                fs->increment = new ErrorExp();
             fs->increment = fs->increment->optimize(WANTvalue);
             fs->increment = checkGC(sc, fs->increment);
         }
@@ -1723,6 +1731,8 @@ public:
             ifs->condition = resolveProperties(sc, ifs->condition);
             ifs->condition = ifs->condition->addDtorHook(sc);
         }
+        if (checkNonAssignmentArrayOp(ifs->condition))
+            ifs->condition = new ErrorExp();
         ifs->condition = checkGC(sc, ifs->condition);
 
         // Convert to boolean after declaring prm so this works:
@@ -1971,6 +1981,8 @@ public:
                 break;
             }
         }
+        if (checkNonAssignmentArrayOp(ss->condition))
+            ss->condition = new ErrorExp();
         ss->condition = ss->condition->optimize(WANTvalue);
         ss->condition = checkGC(sc, ss->condition);
         if (ss->condition->op == TOKerror)
diff --git a/gcc/testsuite/gdc.dg/pr90650a.d b/gcc/testsuite/gdc.dg/pr90650a.d
new file mode 100644
index 00000000000..57228cab19f
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr90650a.d
@@ -0,0 +1,14 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90650
+// { dg-do compile }
+class c
+{
+  static f ()
+  {
+    return 0;
+  }
+}
+
+void g ()
+{
+  if (0 & [0] & c.f()) {}   // { dg-error "array operation \\\[0\\\] & 0 & f\\(\\) without destination memory not allowed" }
+}
diff --git a/gcc/testsuite/gdc.dg/pr90650b.d b/gcc/testsuite/gdc.dg/pr90650b.d
new file mode 100644
index 00000000000..2b3192ed2b6
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr90650b.d
@@ -0,0 +1,13 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90650
+// { dg-do compile }
+class c
+{
+  static f ()
+  {
+    return 0;
+  }
+}
+void g ()
+{
+  if ([0] & c.f()) {}   // { dg-error "array operation \\\[0\\\] & f\\(\\) without destination memory not allowed" }
+}

commit f56e522b76310bb360d438355a793413ddc712f7

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272343 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 7456d604a91..4cb2bbac46d 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-420cce2a654f14b8de4a75cbb5d4203fce8d4e0f
+f30c5dc790c17914463879157447acc671518735
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/intrange.c b/gcc/d/dmd/intrange.c
index 940385ccf7e..e0e2472b502 100644
--- a/gcc/d/dmd/intrange.c
+++ b/gcc/d/dmd/intrange.c
@@ -278,7 +278,7 @@ IntRange IntRange::fromType(Type *type)
 
 IntRange IntRange::fromType(Type *type, bool isUnsigned)
 {
-    if (!type->isintegral())
+    if (!type->isintegral() || type->toBasetype()->ty == Tvector)
         return widest();
 
     uinteger_t mask = type->sizemask();
@@ -404,7 +404,7 @@ IntRange& IntRange::castDchar()
 
 IntRange& IntRange::cast(Type *type)
 {
-    if (!type->isintegral())
+    if (!type->isintegral() || type->toBasetype()->ty == Tvector)
         return *this;
     else if (!type->isunsigned())
         return castSigned(type->sizemask());
@@ -416,7 +416,7 @@ IntRange& IntRange::cast(Type *type)
 
 IntRange& IntRange::castUnsigned(Type *type)
 {
-    if (!type->isintegral())
+    if (!type->isintegral() || type->toBasetype()->ty == Tvector)
         return castUnsigned(UINT64_MAX);
     else if (type->toBasetype()->ty == Tdchar)
         return castDchar();
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d b/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d
new file mode 100644
index 00000000000..406e468ca00
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19898a.d
@@ -0,0 +1,14 @@
+/*
+PERMUTE_ARGS:
+REQUIRED_ARGS: -m64
+TEST_OUTPUT:
+---
+fail_compilation/fail19898a.d(11): Error: incompatible types for `(__key2) < (__limit3)`: both operands are of type `__vector(int[4])`
+---
+*/
+void f (__vector(int[4]) n)
+{
+    foreach (i; 0 .. n)
+        cast(void)n;
+}
+
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d b/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d
new file mode 100644
index 00000000000..0b47fb78944
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19898b.d
@@ -0,0 +1,21 @@
+/*
+PERMUTE_ARGS:
+REQUIRED_ARGS: -m64
+TEST_OUTPUT:
+---
+fail_compilation/fail19898b.d(18): Error: cannot implicitly convert expression `m` of type `S` to `__vector(int[4])`
+fail_compilation/fail19898b.d(18): Error: incompatible types for `(__key2) != (__limit3)`: both operands are of type `__vector(int[4])`
+fail_compilation/fail19898b.d(18): Error: cannot cast expression `__key2` of type `__vector(int[4])` to `S`
+---
+*/
+struct S
+{
+    int a;
+}
+
+void f (__vector(int[4]) n, S m)
+{
+    foreach (i; m .. n)
+        cast(void)n;
+}
+

commit 2f38d27c4961acca2c1777232537371e2f1c5dcc

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272342 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 6edc63a2014..7456d604a91 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-c74e624c9a0a9e7e39f96b2f005f86e123df56c9
+420cce2a654f14b8de4a75cbb5d4203fce8d4e0f
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c
index acca4e8097d..0749c7f487d 100644
--- a/gcc/d/dmd/dinterpret.c
+++ b/gcc/d/dmd/dinterpret.c
@@ -6053,9 +6053,16 @@ public:
         result = (*se->elements)[i];
         if (!result)
         {
-            e->error("Internal Compiler Error: null field %s", v->toChars());
-            result = CTFEExp::cantexp;
-            return;
+            // https://issues.dlang.org/show_bug.cgi?id=19897
+            // Zero-length fields don't have an initializer.
+            if (v->type->size() == 0)
+                result = voidInitLiteral(e->type, v).copy();
+            else
+            {
+                e->error("Internal Compiler Error: null field %s", v->toChars());
+                result = CTFEExp::cantexp;
+                return;
+            }
         }
         if (result->op == TOKvoid)
         {
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19897.d b/gcc/testsuite/gdc.test/fail_compilation/fail19897.d
new file mode 100644
index 00000000000..8dd4e149a87
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19897.d
@@ -0,0 +1,13 @@
+// PERMUTE_ARGS:
+/*
+TEST_OUTPUT
+---
+fail_compilation/fail19897.d(10): Error: cannot implicitly convert expression `[]` of type `const(char[0])` to `const(char)`
+---
+*/
+struct S
+{
+    char[0] x;
+}
+const a = S('a');
+const char c = a.x;

commit 28d90f3a13cb0fe17fc3c327e62d4449182120b1

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272341 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index e100264fed8..6edc63a2014 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-78dc311524341a76008b341ff6427e5a16e285db
+c74e624c9a0a9e7e39f96b2f005f86e123df56c9
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/attrib.c b/gcc/d/dmd/attrib.c
index a6686381485..6cd715ce08b 100644
--- a/gcc/d/dmd/attrib.c
+++ b/gcc/d/dmd/attrib.c
@@ -667,7 +667,8 @@ Dsymbol *AlignDeclaration::syntaxCopy(Dsymbol *s)
 {
     assert(!s);
     return new AlignDeclaration(loc,
-        ealign->syntaxCopy(), Dsymbol::arraySyntaxCopy(decl));
+        ealign ? ealign->syntaxCopy() : NULL,
+        Dsymbol::arraySyntaxCopy(decl));
 }
 
 Scope *AlignDeclaration::newScope(Scope *sc)
diff --git a/gcc/testsuite/gdc.test/compilable/aggr_alignment.d b/gcc/testsuite/gdc.test/compilable/aggr_alignment.d
index 3a80a039e26..bf602ff31a4 100644
--- a/gcc/testsuite/gdc.test/compilable/aggr_alignment.d
+++ b/gcc/testsuite/gdc.test/compilable/aggr_alignment.d
@@ -26,3 +26,16 @@ enum payloadOffset = C2.bytes.offsetof;
 static assert(C2.int1.offsetof == payloadOffset + 8);
 static assert(C2.alignof == size_t.sizeof);
 static assert(__traits(classInstanceSize, C2) == payloadOffset + 12);
+
+
+/***************************************************/
+// https://issues.dlang.org/show_bug.cgi?id=19914
+// https://issues.dlang.org/show_bug.cgi?id=19915
+
+class TemplatedClass(T)
+{
+    align T field;
+}
+
+mixin TemplatedClass!(string);
+alias TCint = TemplatedClass!(int);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19914.d b/gcc/testsuite/gdc.test/fail_compilation/fail19914.d
new file mode 100644
index 00000000000..a890d35e85b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19914.d
@@ -0,0 +1,10 @@
+// PERMUTE_ARGS:
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19914.d(9): Error: undefined identifier `c` in module `fail19914`
+fail_compilation/fail19914.d(10): Error: mixin `fail19914.a!string` error instantiating
+---
+*/
+class a(b) { align.c d; }
+mixin a!(string);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19915.d b/gcc/testsuite/gdc.test/fail_compilation/fail19915.d
new file mode 100644
index 00000000000..17e05ee32c2
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19915.d
@@ -0,0 +1,10 @@
+// PERMUTE_ARGS:
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19915.d(9): Error: undefined identifier `c` in module `fail19915`
+fail_compilation/fail19915.d(10): Error: template instance `fail19915.a!int` error instantiating
+---
+*/
+class a (b) { align.c d; }
+alias a!(int) e;

commit 11c724ef9105802d72fc71d7e8a7eecfd35bc208

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272340 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 99499252279..e100264fed8 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-bbc5ea66ab41ebd14abd9a0fbb9ca6ef6b2dcb14
+78dc311524341a76008b341ff6427e5a16e285db
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/dmodule.c b/gcc/d/dmd/dmodule.c
index 1f6fd9f10a6..bf1c0c1f0d9 100644
--- a/gcc/d/dmd/dmodule.c
+++ b/gcc/d/dmd/dmodule.c
@@ -679,7 +679,8 @@ void Module::importAll(Scope *)
     // If it isn't there, some compiler rewrites, like
     //    classinst == classinst -> .object.opEquals(classinst, classinst)
     // would fail inside object.d.
-    if (members->dim == 0 || ((*members)[0])->ident != Id::object)
+    if (members->dim == 0 || ((*members)[0])->ident != Id::object ||
+        (*members)[0]->isImport() == NULL)
     {
         Import *im = new Import(Loc(), NULL, Id::object, NULL, 0);
         members->shift(im);
diff --git a/gcc/testsuite/gdc.test/compilable/test19912.d b/gcc/testsuite/gdc.test/compilable/test19912.d
new file mode 100644
index 00000000000..7a6bc9eb063
--- /dev/null
+++ b/gcc/testsuite/gdc.test/compilable/test19912.d
@@ -0,0 +1,3 @@
+// PERMUTE_ARGS:
+import object;
+void fun(string) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19912a.d b/gcc/testsuite/gdc.test/fail_compilation/fail19912a.d
new file mode 100644
index 00000000000..47d3cf2e5bc
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19912a.d
@@ -0,0 +1,9 @@
+// PERMUTE_ARGS:
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19912a.d(8): Error: struct `fail19912a.object` conflicts with import `fail19912a.object` at fail_compilation/fail19912a.d
+---
+*/
+struct object { }
+void fun(string) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19912b.d b/gcc/testsuite/gdc.test/fail_compilation/fail19912b.d
new file mode 100644
index 00000000000..b3bd56dde46
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19912b.d
@@ -0,0 +1,9 @@
+// PERMUTE_ARGS:
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19912b.d(8): Error: class `fail19912b.object` conflicts with import `fail19912b.object` at fail_compilation/fail19912b.d
+---
+*/
+class object { }
+void fun(string) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19912c.d b/gcc/testsuite/gdc.test/fail_compilation/fail19912c.d
new file mode 100644
index 00000000000..a4656cc856b
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19912c.d
@@ -0,0 +1,9 @@
+// PERMUTE_ARGS:
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19912c.d(8): Error: alias `fail19912c.object` conflicts with import `fail19912c.object` at fail_compilation/fail19912c.d
+---
+*/
+alias object = int;
+void fun(string) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19912d.d b/gcc/testsuite/gdc.test/fail_compilation/fail19912d.d
new file mode 100644
index 00000000000..fdc8dcb9244
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19912d.d
@@ -0,0 +1,9 @@
+// PERMUTE_ARGS:
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19912d.d(8): Error: enum `fail19912d.object` conflicts with import `fail19912d.object` at fail_compilation/fail19912d.d
+---
+*/
+enum object { }
+void fun(string) { }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19912e.d b/gcc/testsuite/gdc.test/fail_compilation/fail19912e.d
new file mode 100644
index 00000000000..19cc9a619d1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19912e.d
@@ -0,0 +1,9 @@
+// PERMUTE_ARGS:
+/*
+TEST_OUTPUT:
+---
+fail_compilation/fail19912e.d(8): Error: function `fail19912e.object` conflicts with import `fail19912e.object` at fail_compilation/fail19912e.d
+---
+*/
+void object() { }
+void fun(string) { }

commit feb0e6d041fb6b7616451a3b32aad350d2ebc338

    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@272339 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index b81cfc64d70..99499252279 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-423758078f8fcd945815a5294806915a8a01d392
+bbc5ea66ab41ebd14abd9a0fbb9ca6ef6b2dcb14
 
 The first line of this file holds the git revision number of the last
 merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c
index d0e73967d45..058738ec825 100644
--- a/gcc/d/dmd/mtype.c
+++ b/gcc/d/dmd/mtype.c
@@ -6734,6 +6734,10 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc,
                 goto L3;
             if (VarDeclaration *v = s->isVarDeclaration())
             {
+                // https://issues.dlang.org/show_bug.cgi?id=19913
+                // v->type would be null if it is a forward referenced member.
+                if (v->type == NULL)
+                    v->semantic(sc);
                 if (v->storage_class & (STCconst | STCimmutable | STCmanifest) ||
                     v->type->isConst() || v->type->isImmutable())
                 {
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail19913.d b/gcc/testsuite/gdc.test/fail_compilation/fail19913.d
new file mode 100644
index 00000000000..b0f31b5aea4
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail19913.d
@@ -0,0 +1,13 @@
+/* PERMUTE_ARGS:
+ * TEST_OUTPUT:
+---
+fail_compilation/fail19913.d(11): Error: no property `b` for type `int`
+fail_compilation/fail19913.d(11): Error: mixin `fail19913.S.b!()` is not defined
+---
+ */
+
+struct S
+{
+    mixin a.b;
+    enum { a }
+}

Reply via email to