re PR d/90559 (Out of memory because of negative length)
authorIain Buclaw <ibuclaw@gdcproject.org>
Sun, 16 Jun 2019 07:50:20 +0000 (07:50 +0000)
committerIain Buclaw <ibuclaw@gcc.gnu.org>
Sun, 16 Jun 2019 07:50:20 +0000 (07:50 +0000)
PR d/90559
d/dmd: Merge upstream dmd 7afcc60c3

Partially fixes out of memory because of negative length.

Reviewed-on: https://github.com/dlang/dmd/pull/10025

gcc/d/ChangeLog:

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

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

From-SVN: r272351

gcc/d/ChangeLog
gcc/d/d-target.cc
gcc/d/dmd/MERGE
gcc/d/dmd/clone.c
gcc/d/dmd/expressionsem.c
gcc/d/dmd/mtype.c
gcc/d/dmd/mtype.h
gcc/testsuite/gdc.test/fail_compilation/staticarrayoverflow.d

index 8b6ce8551c2f293448f9bfe176fbbaf8ca850033..51d17216816c695fd430ab63dae853e0fc60b1d6 100644 (file)
@@ -1,3 +1,8 @@
+2019-06-16  Iain Buclaw  <ibuclaw@gdcproject.org>
+
+       PR d/90559
+       * d-target.cc (Target::_init): Reduce max static data size to INT_MAX.
+
 2019-06-16  Iain Buclaw  <ibuclaw@gdcproject.org>
 
        PR d/90651
index e0cfbafe0b9e565983c6383651c4798009a52cd3..8d85534f05444c8612d07d055ee5ffb1b8d3abe8 100644 (file)
@@ -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)
index 01c8cb0325d6125b71378efe5f1b44833180fb00..4111fc97044b943ef638bf03f336c19c36d5f6ed 100644 (file)
@@ -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.
index d9a9055cb99b69c6c2e4eb0e3d3351930be35a37..45b4e00a68c1dbc280e684c8cc732be85916c57c 100644 (file)
@@ -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;
 
index 2957c09ca62bfde639b165c69e99464aea3532c1..88c59a9045b105cf96911749354ae99026a770a5 100644 (file)
@@ -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;
index 2b1c5a197e24d95bd3ebe4966ec08a972026fa46..906fb11b634c7475bd883ab86846d21721273887 100644 (file)
@@ -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()
index f1e357a3b1868e9a1e7705150eca67f5cd6a52e5..aab0d034cf05c3d75f98b1ae35af70867a7c3fc2 100644 (file)
@@ -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);
index 8743bf1993ecab2367b621b6e297d8244bc32127..f419869236bc2cd142e9122964a4c1075fff3048 100644 (file)
@@ -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;