reboot #6081: Fix issue 14859 - 16MiB size limit for static array

This commit is contained in:
Walter Bright 2017-01-29 22:07:46 -08:00
parent 35303547f6
commit 07855a2f94
6 changed files with 25 additions and 8 deletions

View file

@ -4780,13 +4780,14 @@ extern (C++) final class TypeSArray : TypeArray
if (d1 != d2)
{
Loverflow:
error(loc, "%s size %llu * %llu exceeds 16MiB size limit for static array", toChars(), cast(ulong)tbn.size(loc), cast(ulong)d1);
error(loc, "%s size %llu * %llu exceeds 0x%llx size limit for static array",
toChars(), cast(ulong)tbn.size(loc), cast(ulong)d1, Target.maxStaticDataSize);
goto Lerror;
}
Type tbx = tbn.baseElemOf();
if (tbx.ty == Tstruct && !(cast(TypeStruct)tbx).sym.members || tbx.ty == Tenum && !(cast(TypeEnum)tbx).sym.members)
{
/* To avoid meaningess error message, skip the total size limit check
/* To avoid meaningless error message, skip the total size limit check
* when the bottom of element type is opaque.
*/
}
@ -4796,7 +4797,7 @@ extern (C++) final class TypeSArray : TypeArray
* run on them for the size, since they may be forward referenced.
*/
bool overflow = false;
if (mulu(tbn.size(loc), d2, overflow) >= 0x100_0000 || overflow) // put a 'reasonable' limit on it
if (mulu(tbn.size(loc), d2, overflow) >= Target.maxStaticDataSize || overflow)
goto Loverflow;
}
}

View file

@ -32,6 +32,7 @@ struct Target
extern (C++) static __gshared int c_longsize; // size of a C 'long' or 'unsigned long' type
extern (C++) static __gshared int c_long_doublesize; // size of a C 'long double'
extern (C++) static __gshared int classinfosize; // size of 'ClassInfo'
extern (C++) static __gshared ulong maxStaticDataSize; // maximum size of static data
template FPTypeProperties(T)
{
@ -66,6 +67,15 @@ struct Target
// adjusted for 64 bit code.
ptrsize = 4;
classinfosize = 0x4C; // 76
/* gcc uses int.max for 32 bit compilations, and long.max for 64 bit ones.
* Set to int.max for both, because the rest of the compiler cannot handle
* 2^64-1 without some pervasive rework. The trouble is that much of the
* front and back end uses 32 bit ints for sizes and offsets. Since C++
* silently truncates 64 bit ints to 32, finding all these dependencies will be a problem.
*/
maxStaticDataSize = int.max;
if (global.params.isLP64)
{
ptrsize = 8;
@ -92,6 +102,13 @@ struct Target
realalignsize = 2;
reverseCppOverloads = true;
c_longsize = 4;
if (ptrsize == 4)
{
/* Optlink cannot deal with individual data chunks
* larger than 16Mb
*/
maxStaticDataSize = 0x100_0000; // 16Mb
}
}
else
assert(0);

View file

@ -33,6 +33,7 @@ struct Target
static int c_longsize; // size of a C 'long' or 'unsigned long' type
static int c_long_doublesize; // size of a C 'long double'
static int classinfosize; // size of 'ClassInfo'
static unsigned long long maxStaticDataSize; // maximum size of static data
static void init();
// Type sizes and support.

View file

@ -851,9 +851,9 @@ void toObjFile(Dsymbol ds, bool multiobj)
vd.error("size overflow");
return;
}
if (sz64 >= 0x1000000) // there has to be some 'reasonable' limit on the size
if (sz64 >= Target.maxStaticDataSize)
{
vd.error("size of x%llx exceeds max allowed size 0x100_0000", sz64);
vd.error("size of 0x%llx exceeds max allowed size 0x%llx", sz64, Target.maxStaticDataSize);
}
uint sz = cast(uint)sz64;

View file

@ -1,7 +1,6 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail4611.d(15): Error: Vec[1000000000] size 4 * 1000000000 exceeds 16MiB size limit for static array
fail_compilation/fail4611.d(15): Error: Vec[1000000000] size 4 * 1000000000 exceeds 0x7fffffff size limit for static array
---
*/

View file

@ -1,7 +1,6 @@
/*
REQUIRED_ARGS: -m64
PERMUTE_ARGS:
TEST_OUTPUT:
---
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