D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5835 - `TypeInfo_Array.getHash` creates raw data hash instead using array element hash function
Summary: `TypeInfo_Array.getHash` creates raw data hash instead using array element ha...
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: Denis Shelomovskii
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2011-04-11 05:52 UTC by Kenji Hara
Modified: 2014-03-08 07:47 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Kenji Hara 2011-04-11 05:52:31 UTC
Sample code:
----
import std.stdio;
class Foo{
  hash_t toHash(){ writeln("Foo.toHash"); return 0; }
}
void main(){
  Foo[] arr = [new Foo(), new Foo()];
  typeid(arr).getHash(&arr);  // doesn't call Foo.toHash()
}
----

The typeid(arr) returns instance of TypeInfo_Array, but its getHash is not call Object.toHash of each element.

The internal TypeInfo class rt.typeinfo.ti_AC.TypeInfo_AC supports it, but this is only used in array/associative-array operations.
Comment 1 Kenji Hara 2011-04-11 05:56:44 UTC
Patches:
https://github.com/9rnsr/dmd/compare/master...aa_hash_fix
https://github.com/9rnsr/druntime/compare/master...aa_hash_fix

Changes:
- TypeInfo_AC is derived from TypeInfo_Array.
- Class array's TypeInfo is instance of TypeInfo_AC.
Comment 2 Kenji Hara 2011-04-11 19:34:45 UTC
Sorry, this patch has disabling optimizing problem.
I'll fix it.
Comment 3 Kenji Hara 2011-04-11 22:55:45 UTC
Changed.
- Removing getInternalTypeInfo is too strict.
- Changed internal TypeInfo of class array -> typeid(Object[])
- TypeInfo_AC is only used for TypeInfo class of typeid(user class array).
Comment 4 yebblies 2012-02-04 20:50:53 UTC
Are these patches still valid?  Maybe worth turning them into pull requests.
Comment 5 Denis Shelomovskii 2014-03-06 01:57:36 UTC
Simplified original testcase:
---
class S
{
    int i;
    this(in int i) { this.i = i; }
    override hash_t toHash() { return 0; }
}

void main()
{
    S[] a1 = [new S(11)], a2 = [new S(12)];
    assert(typeid(S[]).getHash(&a1) == typeid(S[]).getHash(&a2)); // fails
}
---

With structs:
---
struct S
{
    int i;
    hash_t toHash() const @safe nothrow { return 0; }
}

void main()
{
    S[] a1 = [S(11)], a2 = [S(12)];
    assert(typeid(S[]).getHash(&a1) != typeid(S[]).getHash(&a2)); // fails
}
---

Associative arrays are affected too because of this:
---
struct S
{
    int i;
    hash_t toHash() const @safe nothrow { return 0; }
    bool opEquals(ref const S el) const { return true; }
    int opCmp(ref const S el) const { return 0; }
}

void main()
{
    int[S[]] aa = [[S(11)] : 13];
    assert([S(12)] in aa); // fails
}
---
Comment 6 Denis Shelomovskii 2014-03-06 02:09:12 UTC
Will fix soon.
Comment 7 Denis Shelomovskii 2014-03-06 03:28:11 UTC
(In reply to comment #5)
> ...
> With structs:
> ...
>     assert(typeid(S[]).getHash(&a1) != typeid(S[]).getHash(&a2)); // fails
> ...

Of course `==` was meant.

A fixing pull:
https://github.com/D-Programming-Language/druntime/pull/735
Comment 8 github-bugzilla 2014-03-08 04:32:32 UTC
Commits pushed to master at https://github.com/D-Programming-Language/druntime

https://github.com/D-Programming-Language/druntime/commit/1a3f6796270752ba0d770539392f2815f57e8181
Fix Issue 5835 - `TypeInfo_Array.getHash` creates raw data hash instead using array element hash function

Issue URL: https://d.puremagic.com/issues/show_bug.cgi?id=5835

https://github.com/D-Programming-Language/druntime/commit/dc3e69a24622331722978158cfef3df10204dcf9
Merge pull request #735 from denis-sh/fix-Issue-5835

Fix Issue 5835