Showing with 33 additions and 11 deletions.
  1. +20 −11 src/mtype.c
  2. +13 −0 test/fail_compilation/fail12436.d
31 changes: 20 additions & 11 deletions src/mtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -4049,11 +4049,23 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
if (dim->op == TOKerror)
goto Lerror;

bool overflow = false;
if (d1 != d2)
goto Loverflow;
{
Loverflow:
error(loc, "%s size %llu * %llu exceeds 16MiB size limit for static array",
toChars(), (unsigned long long)tbn->size(loc), (unsigned long long)d1);
goto Lerror;
}

if (tbn->isintegral() ||
Type *tbx = tbn->baseElemOf();
if (tbx->ty == Tstruct && !((TypeStruct *)tbx)->sym->members ||
tbx->ty == Tenum && !((TypeEnum *)tbx)->sym->members)
{
/* To avoid meaningess error message, skip the total size limit check
* when the bottom of element type is opaque.
*/
}
else if (tbn->isintegral() ||
tbn->isfloating() ||
tbn->ty == Tpointer ||
tbn->ty == Tarray ||
Expand All @@ -4065,13 +4077,9 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
/* Only do this for types that don't need to have semantic()
* run on them for the size, since they may be forward referenced.
*/
bool overflow = false;
if (mulu(tbn->size(loc), d2, overflow) >= 0x1000000 || overflow) // put a 'reasonable' limit on it
{
Loverflow:
error(loc, "%s size %llu * %llu exceeds 16MiB size limit for static array",
toChars(), (unsigned long long)tbn->size(loc), (unsigned long long)d1);
goto Lerror;
}
goto Loverflow;
}
}
switch (tbn->ty)
Expand Down Expand Up @@ -5471,10 +5479,11 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc)
errors = true;
}
else if (!(fparam->storageClass & (STCref | STCout)) &&
(t->ty == Tstruct || t->ty == Tsarray))
(t->ty == Tstruct || t->ty == Tsarray || t->ty == Tenum))
{
Type *tb2 = t->baseElemOf();
if (tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members)
if (tb2->ty == Tstruct && !((TypeStruct *)tb2)->sym->members ||
tb2->ty == Tenum && !((TypeEnum *)tb2)->sym->memtype)
{
error(loc, "cannot have parameter of opaque type %s by value", fparam->type->toChars());
errors = true;
Expand Down
13 changes: 13 additions & 0 deletions test/fail_compilation/fail12436.d
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,16 @@ void param12436f(ref Opaque); // no error
void param12436g(ref Opaque[1]); // no error
void param12436h(out Opaque); // no error
void param12436i(out Opaque[1]); // no error

/*
TEST_OUTPUT:
---
fail_compilation/fail12436.d(75): Error: cannot have parameter of opaque type A14906 by value
fail_compilation/fail12436.d(76): Error: cannot have parameter of opaque type A14906[3] by value
fail_compilation/fail12436.d(77): Error: cannot have parameter of opaque type A14906[3][3] by value
---
*/
enum A14906;
void f14906a(A14906) {}
void f14906b(A14906[3]) {}
void f14906c(A14906[3][3]) {}