Need help locating AA bug

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Feb 27 17:28:17 PST 2012


On Mon, Feb 27, 2012 at 02:41:27PM -0800, H. S. Teoh wrote:
> I'm investigating issue 7512, and narrowed down the problem to a bug
> somewhere in the code that handles AA literals.
[...]

OK, I've found the cause of the problem. Suppose you have an int array:

	const int[] key = [1,2,3,4];

and you create an AA out of it with an AA literal:

	int[int[]] map1 = [ key: 1234 ];

then internally, map1's key TypeInfo points to const(int)[].

However, if you do this:

	int[int[]] map2;
	map2[key] = 1234;

then internally, map2's key TypeInfo points to int[]. (Non-const!)

This difference means that the hash value of 'key' in map1 is
*different* from the hash value of 'key' in map2.  But if you now write
this:

	map1[key] = 1234;

for some reason, the hash value of 'key' is *still* computed using
int[], even though map1's key TypeInfo points to const(int)[]. So the
wrong hash value is computed, and the entry is not found. This means
that you will never find anything in map1 using map1.get or map1[...].
But foreach works 'cos no hash values are involved.

The above line will actually create a duplicate entry in the hash table,
because 'key' is hashed to a different value than the one set by the AA
literal.

So the question is:

1) Why does map2's internal TypeInfo get set to int[] instead of
const(int)[]?

2) Why does map1[key] use int[]'s version of getHash() even though
map1's TypeInfo actually points to const(int)[]?


This completely breaks AA literals for wstring keys, dstring keys, and
in fact *any* array-typed key except for string (which for some blessed
reason doesn't suffer from this breakage).

Question: is this a compiler bug, or a druntime bug?


T

-- 
2+2=4. 2*2=4. 2^2=4. Therefore, +, *, and ^ are the same operation.


More information about the Digitalmars-d mailing list