From b0a55e6657cbb934837b293a9ea2810b1a74c7e0 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Sun, 16 Jun 2019 07:50:20 +0000 Subject: [PATCH] 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 PR d/90559 * d-target.cc (Target::_init): Reduce max static data size to INT_MAX. From-SVN: r272351 --- gcc/d/ChangeLog | 5 +++ gcc/d/d-target.cc | 5 ++- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/clone.c | 21 ++------- gcc/d/dmd/expressionsem.c | 12 +---- gcc/d/dmd/mtype.c | 51 +++++++++++++++------- gcc/d/dmd/mtype.h | 1 + .../fail_compilation/staticarrayoverflow.d | 16 ++++--- 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 + PR d/90559 + * d-target.cc (Target::_init): Reduce max static data size to INT_MAX. + +2019-06-16 Iain Buclaw + 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; -- 2.7.4