xref: /netbsd-src/external/gpl3/gcc/dist/libphobos/testsuite/libphobos.hash/test_hash.d (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 // { dg-prune-output "Warning: struct HasNonConstToHash has method toHash" }
2 // { dg-prune-output "HasNonConstToHash.toHash defined here:" }
main()3 void main()
4 {
5     issue19562();
6     issue15111();
7     issues16654And16764();
8     issue18918();
9     issue18925();
10     issue19005();
11     issue19204();
12     issue19262();
13     issue19282();
14     issue19332(); // Support might be removed in the future!
15     issue19568();
16     issue19582();
17     issue20034();
18     issue21642();
19     issue22024();
20     issue22076();
21     testTypeInfoArrayGetHash1();
22     testTypeInfoArrayGetHash2();
23     pr2243();
24 }
25 
26 /// Check hashOf an array of void pointers or delegates is @safe.
issue19562()27 void issue19562() @nogc nothrow pure @safe
28 {
29     void*[10] val;
30     size_t h = hashOf(val[]);
31 
32     alias D = void delegate();
33     D[10] ds;
34     h = hashOf(ds[]);
35 }
36 
37 /// hashOf was failing for structs that had an `alias this` to a dynamic array.
issue15111()38 void issue15111()
39 {
40     void testAlias(T)()
41     {
42         static struct Foo
43         {
44             T t;
45             alias t this;
46         }
47         Foo foo;
48         static assert(is(typeof(hashOf(foo))));
49     }
50     // was fixed
51     testAlias!(int[]);
52     testAlias!(int*);
53     // was not affected
54     testAlias!int;
55     testAlias!(void delegate());
56     testAlias!(string[string]);
57     testAlias!(int[8]);
58 }
59 
issues16654And16764()60 void issues16654And16764()
61 {
62     auto a = [1];
63     auto b = a.dup;
64     assert(hashOf(a) == hashOf(b));
65 }
66 
67 /// Check hashOf dynamic array of scalars is usable in @safe code.
issue18918()68 void issue18918() nothrow pure @safe
69 {
70     const _ = (() @nogc => hashOf("abc"))();
71 
72     static struct S { string array; }
73     auto s1 = S("abc");
74     auto s2 = S(s1.array.idup);
75     assert(hashOf(s1) == hashOf(s2));
76     enum e = hashOf(S("abc"));
77     assert(hashOf(s1) == e);
78 }
79 
80 /// Check hashOf struct of scalar fields is usable in @safe code.
issue18925()81 void issue18925() @nogc nothrow pure @safe
82 {
83 
84     static struct S { int a; int b; }
85     auto h = hashOf(S.init);
86 }
87 
issue19005()88 void issue19005() @nogc nothrow pure @safe
89 {
90     enum Month : ubyte
91     {
92         jan = 1
93     }
94     static struct Date
95     {
96         short _year;
97         Month _month;
98         ubyte _day;
99     }
100     Date date;
101     auto hash = date.hashOf;
102 }
103 
104 /// Accept SIMD vectors.
issue19204()105 void issue19204() @nogc nothrow pure @safe
106 {
107     version (D_SIMD)
108     {
109         static import simd = core.simd;
110         static if (is(simd.int4)) // __traits(isArithmetic)
111         {{
112             enum simd.int4 val = [1,2,3,4];
113             enum ctfeHash = hashOf(val);
114             simd.int4 rtVal = val;
115             auto rtHash = hashOf(rtVal);
116             assert(ctfeHash == rtHash);
117         }}
118         static if (is(simd.void16)) // non __traits(isArithmetic)
119         {{
120             auto h = hashOf(simd.void16.init);
121         }}
122         static if (is(simd.float4)) // __traits(isArithmetic) and __traits(isFloating)
123         {{
124             enum simd.float4 val = [1.1f, 2.2f, 3.3f, 4.4f];
125             enum ctfeHash = hashOf(val);
126             simd.float4 rtVal = val;
127             auto rtHash = hashOf(rtVal);
128             assert(ctfeHash == rtHash);
129         }}
130     }
131 }
132 
133 /// hashOf associative array should infer nothrow
issue19262()134 void issue19262() nothrow
135 {
136     int[int] aa;
137     auto h = hashOf(aa);
138     h = hashOf(aa, h);
139 }
140 
141 extern(C++) class Issue19282CppClass {}
142 
143 /// test that hashOf doesn't crash for non-null C++ objects.
issue19282()144 void issue19282()
145 {
146     Issue19282CppClass c = new Issue19282CppClass();
147     size_t h = hashOf(c);
148     h = hashOf(c, h);
149 }
150 
151 /// Ensure hashOf works for const struct that has non-const toHash & has all
152 /// fields bitwise-hashable. (Support might be removed in the future!)
issue19332()153 void issue19332()
154 {
155     static struct HasNonConstToHash
156     {
157         int a;
158         size_t toHash() { return a; }
159     }
160     const HasNonConstToHash val;
161     size_t h = hashOf(val);
162     h = hashOf!(const HasNonConstToHash)(val); // Ensure doesn't match more than one overload.
163 }
164 
165 /// hashOf should not unnecessarily call a struct's fields' postblits & dtors in CTFE
issue19568()166 void issue19568()
167 {
168     static struct S1
169     {
170         @disable this(this);
171 
172         ~this() @nogc nothrow
173         {
174             import core.stdc.stdio;
175             if (mptr) puts("impure");
176         }
177 
178         size_t[2] pad;
179         void* mptr;
180     }
181 
182     static struct S2
183     {
184         @disable this(this);
185 
186         ~this() @nogc nothrow
187         {
188             import core.stdc.stdio;
189             if (fd != -1) puts("impure");
190         }
191 
192         int fd = -1;
193         S1 s1;
194     }
195 
196     static struct S3
197     {
198         private S2 s2;
199     }
200 
201     S3 s3;
202     size_t h = ((ref S3 s3) pure => hashOf(s3))(s3);
203 }
204 
205 /// Check core.internal.convert.toUbyte in CTFE for arrays works with
206 /// reference type elements and doesn't call postblits/dtors.
issue19582()207 void issue19582()
208 {
209     import core.internal.convert : toUbyte;
210     final static class C : Object {}
211     enum b1 = (() @nogc nothrow pure @safe { C[10] o; return toUbyte(o[])[0]; })();
212 
213     static struct S
214     {
215         int x;
216         @disable this(this);
217         ~this() @nogc nothrow
218         {
219             import core.stdc.stdio : puts;
220             if (x) puts("impure");
221         }
222     }
223     enum b2 = () {
224             return ((const S[] a) @nogc nothrow pure @safe => toUbyte(a))(new S[10]);
225         }();
226 }
227 
228 /// Check core.internal.hash.hashOf works with enums of non-scalar values
issue20034()229 void issue20034()
230 {
231     enum E
232     {
233         a = "foo"
234     }
235     // should compile
236     assert(hashOf(E.a, 1));
237 }
238 
239 /// [REG 2.084] hashOf will fail to compile for some structs/unions that recursively contain shared enums
issue21642()240 void issue21642() @safe nothrow pure
241 {
242     enum C : char { _ = 1, }
243     union U { C c; void[0] _; }
244     shared union V { U u; }
245     cast(void) hashOf(V.init);
246     // Also test the underlying reason the above was failing.
247     import core.internal.convert : toUbyte;
248     shared C c;
249     assert(toUbyte(c) == [ubyte(1)]);
250 }
251 
252 /// Accept enum type whose ultimate base type is a SIMD vector.
issue22024()253 void issue22024() @nogc nothrow pure @safe
254 {
255     static if (is(__vector(float[2])))
256     {
257         enum E2 : __vector(float[2]) { a = __vector(float[2]).init, }
258         enum F2 : E2 { a = E2.init, }
259         assert(hashOf(E2.init) == hashOf(F2.init));
260         assert(hashOf(E2.init, 1) == hashOf(F2.init, 1));
261     }
262     static if (is(__vector(float[4])))
263     {
264         enum E4 : __vector(float[4]) { a = __vector(float[4]).init, }
265         enum F4 : E4 { a = E4.init, }
266         assert(hashOf(E4.init) == hashOf(F4.init));
267         assert(hashOf(E4.init, 1) == hashOf(F4.init, 1));
268     }
269 }
270 
271 /// hashOf(S) can segfault if S.toHash is forwarded via `alias this` to a
272 /// receiver which may be null.
issue22076()273 void issue22076()
274 {
275     static struct S0 { Object a; alias a this; }
276 
277     static struct S1
278     {
279         S0 a;
280         inout(S0)* b() inout return nothrow { return &a; }
281         alias b this;
282     }
283 
284     static struct S2
285     {
286         S0 a;
287         S1 b;
288     }
289 
290     extern(C++) static class C0
291     {
292         int foo() { return 0; } // Need at least one function in vtable.
293         S0 a; alias a this;
294     }
295 
296     extern(C++) static class C1
297     {
298         S1 a;
299         inout(S1)* b() inout nothrow { return &a; }
300         alias b this;
301     }
302 
303     cast(void) hashOf(S0.init);
304     cast(void) hashOf(S0.init, 0);
305     cast(void) hashOf(S1.init);
306     cast(void) hashOf(S1.init, 0);
307     cast(void) hashOf(S2.init);
308     cast(void) hashOf(S2.init, 0);
309     auto c0 = new C0();
310     cast(void) hashOf(c0);
311     cast(void) hashOf(c0, 0);
312     auto c1 = new C1();
313     cast(void) hashOf(c1);
314     cast(void) hashOf(c1, 0);
315 }
316 
317 /// Tests ensure TypeInfo_Array.getHash uses element hash functions instead
318 /// of hashing array data.
testTypeInfoArrayGetHash1()319 void testTypeInfoArrayGetHash1()
320 {
321     class C
322     {
323         int i;
324         this(in int i) { this.i = i; }
325         override hash_t toHash() { return 0; }
326     }
327     C[] a1 = [new C(11)], a2 = [new C(12)];
328     assert(typeid(C[]).getHash(&a1) == typeid(C[]).getHash(&a2));
329 }
330 
331 /// ditto
testTypeInfoArrayGetHash2()332 void testTypeInfoArrayGetHash2()
333 {
334     struct S
335     {
336         int i;
337         hash_t toHash() const @safe nothrow { return 0; }
338     }
339     S[] a1 = [S(11)], a2 = [S(12)];
340     assert(typeid(S[]).getHash(&a1) == typeid(S[]).getHash(&a2));
341 }
342 
343 /++
344 Use the new `core.internal.hash.hashOf` in all `TypeInfo.getHash` instead of
345 the `old rt.util.hash.hashOf`. Also make `typeid(T).getHash(&val)` get the
346 same result as `hashOf(val)`.
347 +/
pr2243()348 void pr2243()
349 {
350     static struct Foo
351     {
352         int a = 99;
353         float b = 4.0;
354         size_t toHash() const pure @safe nothrow
355         {
356             return a;
357         }
358     }
359 
360     static struct Bar
361     {
362         char c = 'x';
363         int a = 99;
364         float b = 4.0;
365         void* d = null;
366     }
367 
368     static struct Boom
369     {
370         char c = 'M';
371         int* a = null;
372     }
373 
374     static struct Plain
375     {
376         int a = 1;
377         int b = 2;
378     }
379 
380     interface IBoo
381     {
382         void boo();
383     }
384 
385     static class Boo: IBoo
386     {
387         override void boo()
388         {
389         }
390 
391         override size_t toHash()
392         {
393             return 1;
394         }
395     }
396 
397     static struct Goo
398     {
399         size_t toHash() pure @safe nothrow
400         {
401             return 1;
402         }
403     }
404 
405     enum Gun: long
406     {
407         A = 99,
408         B = 17
409     }
410 
411     enum double dexpr = 3.14;
412     enum float fexpr = 2.71;
413     enum wstring wsexpr = "abcdef"w;
414     enum string csexpr = "abcdef";
415     enum int iexpr = 7;
416     enum long lexpr = 42;
417     enum int[2][3] saexpr = [[1, 2], [3, 4], [5, 6]];
418     enum int[] daexpr = [7,8,9];
419     enum Foo thsexpr = Foo();
420     enum Bar vsexpr = Bar();
421     enum int[int] aaexpr = [99:2, 12:6, 45:4];
422     enum Gun eexpr = Gun.A;
423     enum Foo[] staexpr = [Foo(), Foo(), Foo()];
424     enum Bar[] vsaexpr = [Bar(), Bar(), Bar()];
425     enum realexpr = 7.88;
426     enum nullexpr = null;
427     enum plstr = Plain();
428     enum plarrstr = [Plain(), Plain(), Plain()];
429     //No CTFE:
430     Boom rstructexpr = Boom();
431     Boom[] rstrarrexpr = [Boom(), Boom(), Boom()];
432     int delegate() dgexpr  = (){return 78;};
433     void* ptrexpr = &dgexpr;
434 
435 
436     //CTFE hashes
437     enum h1 = dexpr.hashOf();
438     enum h2 = fexpr.hashOf();
439     enum h3 = wsexpr.hashOf();
440     enum h4 = csexpr.hashOf();
441     enum h5 = iexpr.hashOf();
442     enum h6 = lexpr.hashOf();
443     enum h7 = saexpr.hashOf();
444     enum h8 = daexpr.hashOf();
445     enum h9 = thsexpr.hashOf();
446     enum h10 = vsexpr.hashOf();
447     enum h11 = aaexpr.hashOf();
448     enum h12 = eexpr.hashOf();
449     enum h14 = hashOf(new Boo);
450     enum h15 = staexpr.hashOf();
451     enum h16 = hashOf([new Boo, new Boo, new Boo]);
452     enum h17 = hashOf([cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo]);
453     enum h18 = hashOf(cast(IBoo)new Boo);
454     enum h19 = vsaexpr.hashOf();
455     enum h20 = hashOf(cast(Foo[3])staexpr);
456 
457     //BUG: cannot cast [Boo(), Boo(), Boo()][0] to object.Object at compile time
458     auto h21 = hashOf(cast(Boo[3])[new Boo, new Boo, new Boo]);
459     auto h22 = hashOf(cast(IBoo[3])[cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo]);
460     enum h23 = hashOf(cast(Bar[3])vsaexpr);
461 
462     //NO CTFE (Compute, but don't check correctness):
463     auto h24 = rstructexpr.hashOf();
464     auto h25 = rstrarrexpr.hashOf();
465     auto h26 = dgexpr.hashOf();
466     auto h27 = ptrexpr.hashOf();
467 
468     enum h28 = realexpr.hashOf();
469     enum h30 = nullexpr.hashOf();
470     enum h31 = plstr.hashOf();
471     enum h32 = plarrstr.hashOf();
472     enum h33 = hashOf(cast(Plain[3])plarrstr);
473 
474     auto v1 = dexpr;
475     auto v2 = fexpr;
476     auto v3 = wsexpr;
477     auto v4 = csexpr;
478     auto v5 = iexpr;
479     auto v6 = lexpr;
480     auto v7 = saexpr;
481     auto v8 = daexpr;
482     auto v9 = thsexpr;
483     auto v10 = vsexpr;
484     auto v11 = aaexpr;
485     auto v12 = eexpr;
486     auto v14 = new Boo;
487     auto v15 = staexpr;
488     auto v16 = [new Boo, new Boo, new Boo];
489     auto v17 = [cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo];
490     auto v18 = cast(IBoo)new Boo;
491     auto v19 = vsaexpr;
492     auto v20 = cast(Foo[3])staexpr;
493     auto v21 = cast(Boo[3])[new Boo, new Boo, new Boo];
494     auto v22 = cast(IBoo[3])[cast(IBoo)new Boo, cast(IBoo)new Boo, cast(IBoo)new Boo];
495     auto v23 = cast(Bar[3])vsaexpr;
496     auto v30 = null;
497     auto v31 = plstr;
498     auto v32 = plarrstr;
499     auto v33 = cast(Plain[3])plarrstr;
500 
501     //NO CTFE:
502     auto v24 = rstructexpr;
503     auto v25 = rstrarrexpr;
504     auto v26 = dgexpr;
505     auto v27 = ptrexpr;
506     auto v28 = realexpr;
507 
508     //runtime hashes
509     auto rth1 = hashOf(v1);
510     auto rth2 = hashOf(v2);
511     auto rth3 = hashOf(v3);
512     auto rth4 = hashOf(v4);
513     auto rth5 = hashOf(v5);
514     auto rth6 = hashOf(v6);
515     auto rth7 = hashOf(v7);
516     auto rth8 = hashOf(v8);
517     auto rth9 = hashOf(v9);
518     auto rth10 = hashOf(v10);
519     auto rth11 = hashOf(v11);
520     auto rth12 = hashOf(v12);
521     auto rth14 = hashOf(v14);
522     auto rth15 = hashOf(v15);
523     auto rth16 = hashOf(v16);
524     auto rth17 = hashOf(v17);
525     auto rth18 = hashOf(v18);
526     auto rth19 = hashOf(v19);
527     auto rth20 = hashOf(v20);
528     auto rth21 = hashOf(v21);
529     auto rth22 = hashOf(v22);
530     auto rth23 = hashOf(v23);
531     auto rth30 = hashOf(v30);
532     //NO CTFE:
533     auto rth24 = hashOf(v24);
534     auto rth25 = hashOf(v25);
535     auto rth26 = hashOf(v26);
536     auto rth27 = hashOf(v27);
537     auto rth28 = hashOf(v28);
538 
539     auto rth31 = hashOf(v31);
540     auto rth32 = hashOf(v32);
541     auto rth33 = hashOf(v33);
542 
543     assert(h1 == rth1);
544     assert(h2 == rth2);
545     assert(h3 == rth3);
546     assert(h4 == rth4);
547     assert(h5 == rth5);
548     assert(h6 == rth6);
549     assert(h7 == rth7);
550     assert(h8 == rth8);
551     assert(h9 == rth9);
552     assert(h10 == rth10);
553     assert(h11 == rth11);
554     assert(h12 == rth12);
555     assert(h14 == rth14);
556     assert(h15 == rth15);
557     assert(h16 == rth16);
558     assert(h17 == rth17);
559     assert(h18 == rth18);
560     assert(h19 == rth19);
561     assert(h20 == rth20);
562     assert(h21 == rth21);
563     assert(h22 == rth22);
564     assert(h23 == rth23);
565     /*assert(h24 == rth24);
566     assert(h25 == rth25);
567     assert(h26 == rth26);
568     assert(h27 == rth27);
569     assert(h28 == rth28);*/
570     assert(h30 == rth30);
571     assert(h31 == rth31);
572     assert(h32 == rth32);
573     assert(h33 == rth33);
574 
575     // https://issues.dlang.org/show_bug.cgi?id=18932
576     assert(hashOf(null, 0) != hashOf(null, 123456789));
577 
578     static size_t tiHashOf(T)(T var)
579     {
580         return typeid(T).getHash(&var);
581     }
582 
583     auto tih1 = tiHashOf(v1);
584     auto tih2 = tiHashOf(v2);
585     auto tih3 = tiHashOf(v3);
586     auto tih4 = tiHashOf(v4);
587     auto tih5 = tiHashOf(v5);
588     auto tih6 = tiHashOf(v6);
589     auto tih7 = tiHashOf(v7);
590     auto tih8 = tiHashOf(v8);
591     auto tih9 = tiHashOf(v9);
592     auto tih10 = tiHashOf(v10);
593     auto tih11 = tiHashOf(v11);
594     auto tih12 = tiHashOf(v12);
595     auto tih14 = tiHashOf(v14);
596     auto tih15 = tiHashOf(v15);
597     auto tih16 = tiHashOf(v16);
598     auto tih17 = tiHashOf(v17);
599     auto tih18 = tiHashOf(v18);
600     auto tih19 = tiHashOf(v19);
601     auto tih20 = tiHashOf(v20);
602     auto tih21 = tiHashOf(v21);
603     auto tih22 = tiHashOf(v22);
604     auto tih23 = tiHashOf(v23);
605     auto tih24 = tiHashOf(v24);
606     auto tih25 = tiHashOf(v25);
607     auto tih26 = tiHashOf(v26);
608     auto tih27 = tiHashOf(v27);
609     auto tih28 = tiHashOf(v28);
610     auto tih30 = tiHashOf(v30);
611     auto tih31 = tiHashOf(v31);
612     auto tih32 = tiHashOf(v32);
613     auto tih33 = tiHashOf(v33);
614 
615     assert(tih1 == rth1);
616     assert(tih2 == rth2);
617     assert(tih3 == rth3);
618     assert(tih4 == rth4);
619     assert(tih5 == rth5);
620     assert(tih6 == rth6);
621     assert(tih7 == rth7);
622     assert(tih8 == rth8);
623     assert(tih9 == rth9);
624     //assert(tih10 == rth10); // need compiler-generated __xtoHash changes
625     assert(tih11 == rth11);
626     assert(tih12 == rth12);
627     assert(tih14 == rth14);
628     assert(tih15 == rth15);
629     assert(tih16 == rth16);
630     assert(tih17 == rth17);
631     assert(tih18 == rth18);
632     //assert(tih19 == rth19); // need compiler-generated __xtoHash changes
633     assert(tih20 == rth20);
634     assert(tih21 == rth21);
635     assert(tih22 == rth22);
636     //assert(tih23 == rth23); // need compiler-generated __xtoHash changes
637     //assert(tih24 == rth24);
638     //assert(tih25 == rth25);
639     assert(tih26 == rth26);
640     assert(tih27 == rth27);
641     assert(tih28 == rth28);
642     assert(tih30 == rth30);
643     assert(tih31 == rth31);
644     assert(tih32 == rth32);
645     assert(tih33 == rth33);
646 }
647