Commit b0a55e66 by Iain Buclaw Committed by Iain Buclaw

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
parent e5d0ba59
2019-06-16 Iain Buclaw <ibuclaw@gdcproject.org> 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 PR d/90651
* typeinfo.cc (object_module): New variable. * typeinfo.cc (object_module): New variable.
(make_frontend_typeinfo): Update signature. Set temporary on (make_frontend_typeinfo): Update signature. Set temporary on
......
...@@ -140,8 +140,9 @@ Target::_init (void) ...@@ -140,8 +140,9 @@ Target::_init (void)
/* Size of run-time TypeInfo object. */ /* Size of run-time TypeInfo object. */
Target::classinfosize = 19 * Target::ptrsize; Target::classinfosize = 19 * Target::ptrsize;
/* Allow data sizes up to half of the address space. */ /* Much of the dmd front-end uses ints for sizes and offsets, and cannot
Target::maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node)); 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. */ /* Define what type to use for size_t, ptrdiff_t. */
if (POINTER_SIZE == 64) if (POINTER_SIZE == 64)
......
f8e38c001b9d7bd6586ee5b3dab7f7f199a69be7 7afcc60c30554e452eacdfbefc4951ebf601fccd
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository. merge done from the dlang/dmd repository.
...@@ -841,12 +841,7 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc) ...@@ -841,12 +841,7 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
{ {
// __ArrayPostblit((cast(S*)this.v.ptr)[0 .. n]) // __ArrayPostblit((cast(S*)this.v.ptr)[0 .. n])
uinteger_t n = 1; uinteger_t n = tv->numberOfElems(loc);
while (tv->ty == Tsarray)
{
n *= ((TypeSArray *)tv)->dim->toUInteger();
tv = tv->nextOf()->toBasetype();
}
if (n == 0) if (n == 0)
continue; continue;
...@@ -898,12 +893,7 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc) ...@@ -898,12 +893,7 @@ FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc)
{ {
// __ArrayDtor((cast(S*)this.v.ptr)[0 .. n]) // __ArrayDtor((cast(S*)this.v.ptr)[0 .. n])
uinteger_t n = 1; uinteger_t n = tv->numberOfElems(loc);
while (tv->ty == Tsarray)
{
n *= ((TypeSArray *)tv)->dim->toUInteger();
tv = tv->nextOf()->toBasetype();
}
//if (n == 0) //if (n == 0)
// continue; // continue;
...@@ -1049,12 +1039,7 @@ FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc) ...@@ -1049,12 +1039,7 @@ FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc)
{ {
// __ArrayDtor((cast(S*)this.v.ptr)[0 .. n]) // __ArrayDtor((cast(S*)this.v.ptr)[0 .. n])
uinteger_t n = 1; uinteger_t n = tv->numberOfElems(loc);
while (tv->ty == Tsarray)
{
n *= ((TypeSArray *)tv)->dim->toUInteger();
tv = tv->nextOf()->toBasetype();
}
if (n == 0) if (n == 0)
continue; continue;
......
...@@ -5851,16 +5851,8 @@ public: ...@@ -5851,16 +5851,8 @@ public:
if (exp->op != TOKassign) if (exp->op != TOKassign)
{ {
// If multidimensional static array, treat as one large array // If multidimensional static array, treat as one large array
dinteger_t dim = ((TypeSArray *)t1)->dim->toInteger(); dinteger_t dim = t1->numberOfElems(exp->loc);
Type *t = t1; e1x->type = t1->baseElemOf()->sarrayOf(dim);
while (1)
{
t = t->nextOf()->toBasetype();
if (t->ty != Tsarray)
break;
dim *= ((TypeSArray *)t)->dim->toInteger();
e1x->type = t->nextOf()->sarrayOf(dim);
}
} }
SliceExp *sle = new SliceExp(e1x->loc, e1x, NULL, NULL); SliceExp *sle = new SliceExp(e1x->loc, e1x, NULL, NULL);
sle->arrayop = true; sle->arrayop = true;
......
...@@ -2517,6 +2517,33 @@ void Type::checkComplexTransition(Loc loc) ...@@ -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 * Return the mask that an integral type will
* fit into. * fit into.
...@@ -3900,25 +3927,17 @@ Type *TypeSArray::syntaxCopy() ...@@ -3900,25 +3927,17 @@ Type *TypeSArray::syntaxCopy()
d_uns64 TypeSArray::size(Loc loc) d_uns64 TypeSArray::size(Loc loc)
{ {
//printf("TypeSArray::size()\n"); //printf("TypeSArray::size()\n");
dinteger_t sz; uinteger_t n = numberOfElems(loc);
if (!dim) uinteger_t elemsize = baseElemOf()->size();
return Type::size(loc); bool overflow = false;
sz = dim->toInteger(); uinteger_t sz = mulu(n, elemsize, overflow);
if (overflow || sz >= UINT32_MAX)
{ {
bool overflow = false; if (elemsize != SIZE_INVALID && n != UINT32_MAX)
error(loc, "static array `%s` size overflowed to %lld", toChars(), (long long)sz);
sz = mulu(next->size(), sz, overflow); return SIZE_INVALID;
if (overflow)
goto Loverflow;
} }
if (sz > UINT32_MAX)
goto Loverflow;
return sz; return sz;
Loverflow:
error(loc, "static array %s size overflowed to %lld", toChars(), (long long)sz);
return SIZE_INVALID;
} }
unsigned TypeSArray::alignsize() unsigned TypeSArray::alignsize()
......
...@@ -332,6 +332,7 @@ public: ...@@ -332,6 +332,7 @@ public:
virtual Type *nextOf(); virtual Type *nextOf();
Type *baseElemOf(); Type *baseElemOf();
uinteger_t sizemask(); uinteger_t sizemask();
unsigned numberOfElems(const Loc &loc);
virtual bool needsDestruction(); virtual bool needsDestruction();
virtual bool needsNested(); virtual bool needsNested();
void checkComplexTransition(Loc loc); void checkComplexTransition(Loc loc);
......
...@@ -2,11 +2,14 @@ ...@@ -2,11 +2,14 @@
REQUIRED_ARGS: -m64 REQUIRED_ARGS: -m64
PERMUTE_ARGS: PERMUTE_ARGS:
--- ---
fail_compilation/staticarrayoverflow.d(21): Error: static array S[1879048192] size overflowed to 7516192768000 fail_compilation/staticarrayoverflow.d(24): Error: static array `S[1879048192]` size overflowed to 7516192768000
fail_compilation/staticarrayoverflow.d(21): Error: variable staticarrayoverflow.y size overflow fail_compilation/staticarrayoverflow.d(24): 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(26): Error: static array `S[8070450532247928832]` size overflowed to 8070450532247928832
fail_compilation/staticarrayoverflow.d(23): Error: static array S[8070450532247928832] size overflowed to 0 fail_compilation/staticarrayoverflow.d(26): Error: variable `staticarrayoverflow.a` size overflow
fail_compilation/staticarrayoverflow.d(23): 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 ...@@ -20,4 +23,5 @@ struct S
S[0x7000_0000] y; S[0x7000_0000] y;
S[0x100_0000/(4*1000 - 1)] z; S[0x100_0000/(4*1000 - 1)] z;
S[0x7000_0000_0000_0000] a; S[0x7000_0000_0000_0000] a;
S[0][-1] b;
S[0][uint.max] c;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment