Bug 929 – Resizing array of associative arrays (uint[char[]][]) causes infinite loop / hang

Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D1 (retired)
Platform
x86
OS
All
Creation time
2007-02-04T01:08:00Z
Last change time
2014-02-16T15:23:47Z
Keywords
patch, wrong-code
Assigned to
bugzilla
Creator
nick.atamas

Comments

Comment #0 by nick.atamas — 2007-02-04T01:08:45Z
The following code produces an infinite loop. When executed "before" is printed but "after" is never reached. import std.stdio; int main() { uint[char[]][] fractal; writefln("before"); fractal.length = 10; writefln("after"); return 0; }
Comment #1 by fvbommel — 2007-02-04T04:41:41Z
http://www.digitalmars.com/d/arrays.html#associative (under "Properties"): .length Returns number of values in the associative array. Unlike for dynamic arrays, it is read-only. So this shouldn't even compile...
Comment #2 by torhu — 2007-02-04T08:11:26Z
(In reply to comment #1) > http://www.digitalmars.com/d/arrays.html#associative (under "Properties"): > .length Returns number of values in the associative array. Unlike for > dynamic arrays, it is read-only. > > So this shouldn't even compile... > uint[char[]][] fractal; fractal is a dynamic array, so length is not read-only.
Comment #3 by fvbommel — 2007-02-04T08:20:57Z
(In reply to comment #2) > uint[char[]][] fractal; > > fractal is a dynamic array, so length is not read-only. Ah, I missed the last brackets. Sorry about that.
Comment #4 by nick.atamas — 2007-02-04T11:35:04Z
This worked just fine in DMD1.0. It was broken recently. I am currently using a workaround - encapsulating uint[char[]] into a class and making an array of those.
Comment #5 by thomas-dloop — 2007-04-05T11:33:49Z
Comment #6 by svv1999 — 2007-05-24T13:23:10Z
Just stumbled on this when recompiling an older project. To me dynamic and associative arrays are key features of D. The bug was introduced with version 1.001. Therefore increased priority as well as severity and set Version to 1.001. The bug shows up on upsizing only. Downsizing by assigning to length is possible. The type `int[int][]' is sufficient to show the bug.
Comment #7 by wbaxter — 2007-05-28T02:28:44Z
Ouch. This one just bit me too. So throw in my "vote" or whatever. This needs a-fixin' pronto. Thanks for the workaround suggestion, Nick.
Comment #8 by matti.niemenmaa+dbugzilla — 2007-07-07T09:43:27Z
*** Bug 1321 has been marked as a duplicate of this bug. ***
Comment #9 by default_357-line — 2007-09-08T11:32:44Z
Here's a patch against GDC's phobos/internal/gc/gc.d that fixes the issue. It was caused by incorrect/missing handling of the "init.length is 0" case in array resize (the correct behavior is filling with zeroes). diff ~/gcc/dgcc/d/phobos/internal/gc/gc.d ~/gcc/gcc-4.1.2/libphobos/internal/gc/gc.d 632c632 < assert(initsize); --- > // assert(initsize); // size 0 means fill with zeroes 634c634 < assert((sizeelem / initsize) * initsize == sizeelem); --- > assert(!initsize || ((sizeelem / initsize) * initsize == sizeelem)); 714a715,719 > if (initsize == 0) > { > memset(newdata + size, 0, newsize - size); > } > else
Comment #10 by default_357-line — 2007-09-08T11:44:14Z
Update: The underlying issue seems to be that the wrong version of _d_arraysetlength gets called - for zero initializers it should be ...lengthT but ...lengthiT is what ends up being called in this case. Seems to be a compiler bug of sorts.
Comment #11 by swadenator — 2008-02-02T19:27:45Z
Is there any update to this problem? I've been attempting to write some code like this and have been getting exactly this error with DMD 1.026 on a win32 box. thanks, wade
Comment #12 by gide — 2008-06-05T16:18:47Z
*** Bug 2135 has been marked as a duplicate of this bug. ***
Comment #13 by kamm-removethis — 2008-07-29T01:56:44Z
If I am not mistaken, Tomas fixed this in LLVMDC by providing an isZeroInit() overload in TypeAArray that returns TRUE.
Comment #14 by wbaxter — 2008-10-02T22:56:20Z
(In reply to comment #7) > Ouch. This one just bit me too. > So throw in my "vote" or whatever. > This needs a-fixin' pronto. > > Thanks for the workaround suggestion, Nick. > This just bit me again! Also one new tidbit of info: in addition to using a class to work around this you can also wrap the AA in a struct. struct CharToUint { uint[char[]] map; } CharToUint[] x; x.length = 20; // no probs
Comment #15 by kamm-removethis — 2008-10-21T12:40:55Z
Just to make the patch more explicit: Adding int TypeAArray::isZeroInit() { return 1; } to mtype.c and the matching prototype to mtype.h fixes it. Tested in LDC.
Comment #16 by jarrett.billingsley — 2008-11-14T21:55:20Z
If Walter's looking for low-hanging fruit, it doesn't get much lower than this. A 5-line diff? Why has this been open for almost 2 years, anyway?
Comment #17 by smjg — 2008-11-20T13:28:48Z
*** Bug 1898 has been marked as a duplicate of this bug. ***
Comment #18 by smjg — 2008-11-20T13:31:31Z
From issue 1898: allocating an array of AAs using new also hangs, as in int[int][] maps; maps = new int[int][3]; There's a workaround, calling .dup on a static array of AAs, but it requires that the length be known at compile time.
Comment #19 by kamm-removethis — 2008-12-02T12:36:57Z
has been fixed in DMD 1.037 and 2.021
Comment #20 by arthur.loiret — 2008-12-13T04:41:08Z
Fixed in gdc SVN revision 244 as well, thanks!