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