aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2019-06-16 07:50:20 +0000
committerIain Buclaw <ibuclaw@gcc.gnu.org>2019-06-16 07:50:20 +0000
commitb0a55e6657cbb934837b293a9ea2810b1a74c7e0 (patch)
tree84e3d719a3b7181744a750bb09ccd7984f277ea4
parente5d0ba591e28d8be1fb5775fb0418fee04af17d7 (diff)
downloadgcc-b0a55e6657cbb934837b293a9ea2810b1a74c7e0.zip
gcc-b0a55e6657cbb934837b293a9ea2810b1a74c7e0.tar.gz
gcc-b0a55e6657cbb934837b293a9ea2810b1a74c7e0.tar.bz2
re PR d/90559 (Out of memory because of negative length)
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
-rw-r--r--gcc/d/ChangeLog5
-rw-r--r--gcc/d/d-target.cc5
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/clone.c21
-rw-r--r--gcc/d/dmd/expressionsem.c12
-rw-r--r--gcc/d/dmd/mtype.c51
-rw-r--r--gcc/d/dmd/mtype.h1
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/staticarrayoverflow.d16
8 files changed, 60 insertions, 53 deletions
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 8b6ce85..51d1721 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,5 +1,10 @@
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
* typeinfo.cc (object_module): New variable.
(make_frontend_typeinfo): Update signature. Set temporary on
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index e0cfbaf..8d85534 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 01c8cb0..4111fc9 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 d9a9055..45b4e00 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 2957c09..88c59a9 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 2b1c5a1..906fb11 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 f1e357a..aab0d03 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 8743bf1..f419869 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;