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

D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 929 - Resizing array of associative arrays (uint[char[]][]) causes infinite loop / hang
Summary: Resizing array of associative arrays (uint[char[]][]) causes infinite loop / ...
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: x86 All
: P1 regression
Assignee: Walter Bright
URL:
Keywords: patch, wrong-code
: 1321 1898 2135 (view as issue list)
Depends on:
Blocks:
Reported: 2007年02月04日 01:08 UTC by Nick Atamas
Modified: 2014年02月16日 15:23 UTC (History)
8 users (show)

See Also:


Attachments
Add an attachment (proposed patch, testcase, etc.)

Note You need to log in before you can comment on or make changes to this issue.
Description Nick Atamas 2007年02月04日 01:08:45 UTC
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 Frits van Bommel 2007年02月04日 04:41:41 UTC
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 torhu 2007年02月04日 08:11:26 UTC
(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 Frits van Bommel 2007年02月04日 08:20:57 UTC
(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 Nick Atamas 2007年02月04日 11:35:04 UTC
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 Thomas Kühne 2007年04月05日 11:33:49 UTC
Added to DStress as
http://dstress.kuehne.cn/run/l/length_11_A.d
http://dstress.kuehne.cn/run/l/length_11_B.d 
Comment 6 Manfred Nowak 2007年05月24日 13:23:10 UTC
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 Bill Baxter 2007年05月28日 02:28:44 UTC
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 Matti Niemenmaa 2007年07月07日 09:43:27 UTC
*** Bug 1321 has been marked as a duplicate of this bug. ***
Comment 9 FeepingCreature 2007年09月08日 11:32:44 UTC
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 FeepingCreature 2007年09月08日 11:44:14 UTC
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 wade 2008年02月02日 19:27:45 UTC
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 Gide Nwawudu 2008年06月05日 16:18:47 UTC
*** Bug 2135 has been marked as a duplicate of this bug. ***
Comment 13 Christian Kamm 2008年07月29日 01:56:44 UTC
If I am not mistaken, Tomas fixed this in LLVMDC by providing an isZeroInit() overload in TypeAArray that returns TRUE.
Comment 14 Bill Baxter 2008年10月02日 22:56:20 UTC
(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 Christian Kamm 2008年10月21日 12:40:55 UTC
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 Jarrett Billingsley 2008年11月14日 21:55:20 UTC
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 Stewart Gordon 2008年11月20日 13:28:48 UTC
*** Bug 1898 has been marked as a duplicate of this bug. ***
Comment 18 Stewart Gordon 2008年11月20日 13:31:31 UTC
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 Christian Kamm 2008年12月02日 12:36:57 UTC
has been fixed in DMD 1.037 and 2.021
Comment 20 Arthur Loiret 2008年12月13日 04:41:08 UTC
Fixed in gdc SVN revision 244 as well, thanks!


AltStyle によって変換されたページ (->オリジナル) /