Bug 14699 – [REG2.062] ICE: segfaults on array with zero size

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2015-06-14T12:20:00Z
Last change time
2017-07-22T12:35:30Z
Keywords
ice, pull
Assigned to
nobody
Creator
tomer

Comments

Comment #0 by tomer — 2015-06-14T12:20:08Z
The code crashes both dmd2.66 and 2.67 struct Table(K, V, ushort capacity_) { V[capacity_] values; } struct Set(K, ushort capacity_) { Table!(K, ubyte[0], capacity_) tbl; } // this works Table!(uint, ubyte[0], 10) thisWorks; // this crashes Set!(uint, 10) thisCrashesDmd; void main() {} The segfault: Program received signal SIGSEGV, Segmentation fault. 0x00000000005639c0 in dtcat(dt_t**, dt_t*) () (gdb) bt #0 0x00000000005639c0 in dtcat(dt_t**, dt_t*) () #1 0x0000000000550157 in Expression_toDt(Expression*, dt_t**)::ExpToDt::visit(ArrayLiteralExp*) () #2 0x00000000005500d8 in Expression_toDt(Expression*, dt_t**)::ExpToDt::visit(ArrayLiteralExp*) () #3 0x0000000000550910 in toDtElem(TypeSArray*, dt_t**, Expression*) () #4 0x0000000000550d6c in Expression_toDt(Expression*, dt_t**)::ExpToDt::visit(StructLiteralExp*) () #5 0x0000000000550c73 in Expression_toDt(Expression*, dt_t**)::ExpToDt::visit(StructLiteralExp*) () #6 0x00000000005506a7 in StructDeclaration_toDt(StructDeclaration*, dt_t**) () #7 0x000000000055086d in Type_toDt(Type*, dt_t**) () #8 0x0000000000543595 in toObjFile(Dsymbol*, bool)::ToObjFile::visit(VarDeclaration*) () #9 0x000000000054504d in toObjFile(Dsymbol*, bool) () #10 0x000000000052c974 in genObjFile(Module*, bool) () #11 0x0000000000405bf2 in tryMain(unsigned long, char const**) ()
Comment #1 by ketmar — 2015-06-14T16:04:16Z
it asserts on GNU/Linux: "Internal error: backend/dt.c 120". and it asserts even with only "this works" line (i.e. having "this crashes" commented). the following code triggers the bug on GNU/Linux, x86: struct Table(K, V, ushort capacity_) { V[capacity_] values; } Table!(uint, ubyte[0], 10) thisWorks; dmd -c z00.d —> ICE. it does so on git HEAD too. this is triggered by `ubyte[0]`, changing it to `ubyte[1]` avoids the bug. so i'm changing hardware info and subject. p.s. it seems that there is unguarded `-1` somewhere in the compiler code, so `0‒1` results in `-1`, which triggers assertion in dt.c:120.
Comment #2 by ketmar — 2015-06-14T16:05:22Z
p.s. actually, it's enough to have a single line to trigger the bug: ubyte[0][1] test; that's it.
Comment #3 by ketmar — 2015-06-14T16:09:55Z
and here is the patch: diff --git a/src/mtype.c b/src/mtype.c index e15206d..4cbff57 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -4076,6 +4076,11 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) error(loc, "index %llu overflow for static array", (unsigned long long)d1); goto Lerror; } + else if (mulu(tbn->size(loc), d2, overflow) == 0) + { + error(loc, "index %llu underflow for static array", (unsigned long long)d1); + goto Lerror; + } } } switch (tbn->ty)
Comment #4 by ketmar — 2015-06-14T16:11:20Z
sorry, slightly better patch: diff --git a/src/mtype.c b/src/mtype.c index e15206d..a464b49 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -4076,6 +4076,11 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc) error(loc, "index %llu overflow for static array", (unsigned long long)d1); goto Lerror; } + else if (d2 == 0) + { + error(loc, "index %llu underflow for static array", (unsigned long long)d1); + goto Lerror; + } } } switch (tbn->ty)
Comment #5 by ketmar — 2015-06-14T16:26:45Z
or a patch for those who prefers `ubyte[0]` to be valid (phobos using such thing, hehe): diff --git a/src/todt.c b/src/todt.c index 8ae752f..101d0bb 100644 --- a/src/todt.c +++ b/src/todt.c @@ -810,7 +810,7 @@ dt_t **toDtElem(TypeSArray *tsa, dt_t **pdt, Expression *e) len /= ((StringExp *)e)->len; if (e->op == TOKarrayliteral) len /= ((ArrayLiteralExp *)e)->elements->dim; - pdt = dtrepeat(pdt, *pdt, len - 1); + pdt = dtrepeat(pdt, *pdt, (len ? len - 1 : 0)); } return pdt; }
Comment #6 by k.hara.pg — 2015-06-15T10:45:49Z
(In reply to Ketmar Dark from comment #5) > or a patch for those who prefers `ubyte[0]` to be valid (phobos using such > thing, hehe): [snip] When tsa->size() == 0, toDtElem can return a dummy zero as the dt. diff --git a/src/todt.c b/src/todt.c index cd45664..6d5a476 100644 --- a/src/todt.c +++ b/src/todt.c @@ -773,10 +773,15 @@ dt_t **Type_toDt(Type *t, dt_t **pdt) dt_t **toDtElem(TypeSArray *tsa, dt_t **pdt, Expression *e) { - //printf("TypeSArray::toDtElem()\n"); - size_t len = tsa->dim->toInteger(); - if (len) + //printf("TypeSArray::toDtElem() tsa = %s\n", tsa->toChars()); + if (tsa->size(Loc()) == 0) { + pdt = dtnzeros(pdt, 0); + } + else + { + size_t len = tsa->dim->toInteger(); + assert(len); pdt = dtend(pdt); Type *tnext = tsa->next; Type *tbn = tnext->toBasetype();
Comment #7 by ketmar — 2015-06-15T11:08:06Z
thanks. i don't know anything about glue code and backend, so i did it the least intrusive way i can. your fix is definitely better.
Comment #8 by k.hara.pg — 2015-06-15T12:34:24Z
Comment #9 by dlang-bugzilla — 2015-06-16T04:13:40Z
Comment #10 by github-bugzilla — 2015-06-17T18:52:00Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/5d70b1a0d07cc16ef579360fc697116f5ef630d0 fix Issue 14699 - ICE: segfaults on array with zero size https://github.com/D-Programming-Language/dmd/commit/94a6afd4f7c0ad60a6eab608ee28b15bd4e264d8 Merge pull request #4744 from 9rnsr/fix14699 Issue 14699 - ICE: segfaults on array with zero size
Comment #11 by github-bugzilla — 2015-06-26T14:11:51Z
Commit pushed to stable at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/72f759961d08ed9a4e0da2e1d81608fed9a0d7b6 Merge pull request #4744 from 9rnsr/fix14699 Issue 14699 - ICE: segfaults on array with zero size
Comment #12 by github-bugzilla — 2015-07-24T03:20:08Z
Comment #13 by github-bugzilla — 2015-10-04T18:18:31Z
Comment #14 by github-bugzilla — 2017-07-22T12:35:30Z
Commits pushed to dmd-cxx at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/5d70b1a0d07cc16ef579360fc697116f5ef630d0 fix Issue 14699 - ICE: segfaults on array with zero size https://github.com/dlang/dmd/commit/94a6afd4f7c0ad60a6eab608ee28b15bd4e264d8 Merge pull request #4744 from 9rnsr/fix14699