xref: /llvm-project/llvm/unittests/ADT/HashingTest.cpp (revision c3c9312f7049e8a9b1bf05db877b4b39df897416)
1 //===- llvm/unittest/ADT/HashingTest.cpp ----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Hashing.h unit tests.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/ADT/Hashing.h"
14 #include "llvm/Support/DataTypes.h"
15 #include "llvm/Support/HashBuilder.h"
16 #include "gtest/gtest.h"
17 #include <deque>
18 #include <list>
19 #include <map>
20 #include <vector>
21 
22 namespace llvm {
23 
24 // Helper for test code to print hash codes.
25 void PrintTo(const hash_code &code, std::ostream *os) {
26   *os << static_cast<size_t>(code);
27 }
28 
29 // Fake an object that is recognized as hashable data to test super large
30 // objects.
31 struct LargeTestInteger { uint64_t arr[8]; };
32 
33 struct NonPOD {
34   uint64_t x, y;
35   NonPOD(uint64_t x, uint64_t y) : x(x), y(y) {}
36   friend hash_code hash_value(const NonPOD &obj) {
37     return hash_combine(obj.x, obj.y);
38   }
39 };
40 
41 namespace hashing {
42 namespace detail {
43 template <> struct is_hashable_data<LargeTestInteger> : std::true_type {};
44 } // namespace detail
45 } // namespace hashing
46 
47 } // namespace llvm
48 
49 using namespace llvm;
50 
51 namespace {
52 
53 enum TestEnumeration {
54   TE_Foo = 42,
55   TE_Bar = 43
56 };
57 
58 TEST(HashingTest, HashValueBasicTest) {
59   int x = 42, y = 43, c = 'x';
60   void *p = nullptr;
61   uint64_t i = 71;
62   const unsigned ci = 71;
63   volatile int vi = 71;
64   const volatile int cvi = 71;
65   uintptr_t addr = reinterpret_cast<uintptr_t>(&y);
66   EXPECT_EQ(hash_value(42), hash_value(x));
67   EXPECT_EQ(hash_value(42), hash_value(TE_Foo));
68   EXPECT_NE(hash_value(42), hash_value(y));
69   EXPECT_NE(hash_value(42), hash_value(TE_Bar));
70   EXPECT_NE(hash_value(42), hash_value(p));
71   EXPECT_EQ(hash_value(71), hash_value(i));
72   EXPECT_EQ(hash_value(71), hash_value(ci));
73   EXPECT_EQ(hash_value(71), hash_value(vi));
74   EXPECT_EQ(hash_value(71), hash_value(cvi));
75   EXPECT_EQ(hash_value(c), hash_value('x'));
76   EXPECT_EQ(hash_value('4'), hash_value('0' + 4));
77   EXPECT_EQ(hash_value(addr), hash_value(&y));
78 }
79 
80 TEST(HashingTest, HashValueStdPair) {
81   EXPECT_EQ(hash_combine(42, 43), hash_value(std::make_pair(42, 43)));
82   EXPECT_NE(hash_combine(43, 42), hash_value(std::make_pair(42, 43)));
83   EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43ull)));
84   EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42, 43ull)));
85   EXPECT_NE(hash_combine(42, 43), hash_value(std::make_pair(42ull, 43)));
86 
87   // Note that pairs are implicitly flattened to a direct sequence of data and
88   // hashed efficiently as a consequence.
89   EXPECT_EQ(hash_combine(42, 43, 44),
90             hash_value(std::make_pair(42, std::make_pair(43, 44))));
91   EXPECT_EQ(hash_value(std::make_pair(42, std::make_pair(43, 44))),
92             hash_value(std::make_pair(std::make_pair(42, 43), 44)));
93 
94   // Ensure that pairs which have padding bytes *inside* them don't get treated
95   // this way.
96   EXPECT_EQ(hash_combine('0', hash_combine(1ull, '2')),
97             hash_value(std::make_pair('0', std::make_pair(1ull, '2'))));
98 
99   // Ensure that non-POD pairs don't explode the traits used.
100   NonPOD obj1(1, 2), obj2(3, 4), obj3(5, 6);
101   EXPECT_EQ(hash_combine(obj1, hash_combine(obj2, obj3)),
102             hash_value(std::make_pair(obj1, std::make_pair(obj2, obj3))));
103 }
104 
105 TEST(HashingTest, HashValueStdTuple) {
106   EXPECT_EQ(hash_combine(), hash_value(std::make_tuple()));
107   EXPECT_EQ(hash_combine(42), hash_value(std::make_tuple(42)));
108   EXPECT_EQ(hash_combine(42, 'c'), hash_value(std::make_tuple(42, 'c')));
109 
110   EXPECT_NE(hash_combine(43, 42), hash_value(std::make_tuple(42, 43)));
111   EXPECT_NE(hash_combine(42, 43), hash_value(std::make_tuple(42ull, 43ull)));
112   EXPECT_NE(hash_combine(42, 43), hash_value(std::make_tuple(42, 43ull)));
113   EXPECT_NE(hash_combine(42, 43), hash_value(std::make_tuple(42ull, 43)));
114 }
115 
116 TEST(HashingTest, HashValueStdString) {
117   std::string s = "Hello World!";
118   EXPECT_EQ(hash_combine_range(s.c_str(), s.c_str() + s.size()), hash_value(s));
119   EXPECT_EQ(hash_combine_range(s.c_str(), s.c_str() + s.size() - 1),
120             hash_value(s.substr(0, s.size() - 1)));
121   EXPECT_EQ(hash_combine_range(s.c_str() + 1, s.c_str() + s.size() - 1),
122             hash_value(s.substr(1, s.size() - 2)));
123 
124   std::wstring ws = L"Hello Wide World!";
125   EXPECT_EQ(hash_combine_range(ws.c_str(), ws.c_str() + ws.size()),
126             hash_value(ws));
127   EXPECT_EQ(hash_combine_range(ws.c_str(), ws.c_str() + ws.size() - 1),
128             hash_value(ws.substr(0, ws.size() - 1)));
129   EXPECT_EQ(hash_combine_range(ws.c_str() + 1, ws.c_str() + ws.size() - 1),
130             hash_value(ws.substr(1, ws.size() - 2)));
131 }
132 
133 template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }
134 template <typename T, size_t N> T *end(T (&arr)[N]) { return arr + N; }
135 
136 // Provide a dummy, hashable type designed for easy verification: its hash is
137 // the same as its value.
138 struct HashableDummy { size_t value; };
139 hash_code hash_value(HashableDummy dummy) { return dummy.value; }
140 
141 TEST(HashingTest, HashCombineRangeBasicTest) {
142   // Leave this uninitialized in the hope that valgrind will catch bad reads.
143   int dummy;
144   hash_code dummy_hash = hash_combine_range(&dummy, &dummy);
145   EXPECT_NE(hash_code(0), dummy_hash);
146 
147   const int arr1[] = { 1, 2, 3 };
148   hash_code arr1_hash = hash_combine_range(begin(arr1), end(arr1));
149   EXPECT_NE(dummy_hash, arr1_hash);
150   EXPECT_EQ(arr1_hash, hash_combine_range(begin(arr1), end(arr1)));
151 
152   const std::vector<int> vec(begin(arr1), end(arr1));
153   EXPECT_EQ(arr1_hash, hash_combine_range(vec.begin(), vec.end()));
154 
155   const std::list<int> list(begin(arr1), end(arr1));
156   EXPECT_EQ(arr1_hash, hash_combine_range(list.begin(), list.end()));
157 
158   const std::deque<int> deque(begin(arr1), end(arr1));
159   EXPECT_EQ(arr1_hash, hash_combine_range(deque.begin(), deque.end()));
160 
161   const int arr2[] = { 3, 2, 1 };
162   hash_code arr2_hash = hash_combine_range(begin(arr2), end(arr2));
163   EXPECT_NE(dummy_hash, arr2_hash);
164   EXPECT_NE(arr1_hash, arr2_hash);
165 
166   const int arr3[] = { 1, 1, 2, 3 };
167   hash_code arr3_hash = hash_combine_range(begin(arr3), end(arr3));
168   EXPECT_NE(dummy_hash, arr3_hash);
169   EXPECT_NE(arr1_hash, arr3_hash);
170 
171   const int arr4[] = { 1, 2, 3, 3 };
172   hash_code arr4_hash = hash_combine_range(begin(arr4), end(arr4));
173   EXPECT_NE(dummy_hash, arr4_hash);
174   EXPECT_NE(arr1_hash, arr4_hash);
175 
176   const size_t arr5[] = { 1, 2, 3 };
177   const HashableDummy d_arr5[] = { {1}, {2}, {3} };
178   hash_code arr5_hash = hash_combine_range(begin(arr5), end(arr5));
179   hash_code d_arr5_hash = hash_combine_range(begin(d_arr5), end(d_arr5));
180   EXPECT_EQ(arr5_hash, d_arr5_hash);
181 }
182 
183 TEST(HashingTest, HashCombineRangeLengthDiff) {
184   // Test that as only the length varies, we compute different hash codes for
185   // sequences.
186   std::map<size_t, size_t> code_to_size;
187   std::vector<char> all_one_c(256, '\xff');
188   for (unsigned Idx = 1, Size = all_one_c.size(); Idx < Size; ++Idx) {
189     hash_code code = hash_combine_range(&all_one_c[0], &all_one_c[0] + Idx);
190     std::map<size_t, size_t>::iterator
191       I = code_to_size.insert(std::make_pair(code, Idx)).first;
192     EXPECT_EQ(Idx, I->second);
193   }
194   code_to_size.clear();
195   std::vector<char> all_zero_c(256, '\0');
196   for (unsigned Idx = 1, Size = all_zero_c.size(); Idx < Size; ++Idx) {
197     hash_code code = hash_combine_range(&all_zero_c[0], &all_zero_c[0] + Idx);
198     std::map<size_t, size_t>::iterator
199       I = code_to_size.insert(std::make_pair(code, Idx)).first;
200     EXPECT_EQ(Idx, I->second);
201   }
202   code_to_size.clear();
203   std::vector<unsigned> all_one_int(512, -1);
204   for (unsigned Idx = 1, Size = all_one_int.size(); Idx < Size; ++Idx) {
205     hash_code code = hash_combine_range(&all_one_int[0], &all_one_int[0] + Idx);
206     std::map<size_t, size_t>::iterator
207       I = code_to_size.insert(std::make_pair(code, Idx)).first;
208     EXPECT_EQ(Idx, I->second);
209   }
210   code_to_size.clear();
211   std::vector<unsigned> all_zero_int(512, 0);
212   for (unsigned Idx = 1, Size = all_zero_int.size(); Idx < Size; ++Idx) {
213     hash_code code = hash_combine_range(&all_zero_int[0], &all_zero_int[0] + Idx);
214     std::map<size_t, size_t>::iterator
215       I = code_to_size.insert(std::make_pair(code, Idx)).first;
216     EXPECT_EQ(Idx, I->second);
217   }
218 }
219 
220 TEST(HashingTest, HashCombineRangeGoldenTest) {
221   struct { const char *s; uint64_t hash; } golden_data[] = {
222 #if SIZE_MAX == UINT64_MAX || SIZE_MAX == UINT32_MAX
223     { "a",                                0xaeb6f9d5517c61f8ULL },
224     { "ab",                               0x7ab1edb96be496b4ULL },
225     { "abc",                              0xe38e60bf19c71a3fULL },
226     { "abcde",                            0xd24461a66de97f6eULL },
227     { "abcdefgh",                         0x4ef872ec411dec9dULL },
228     { "abcdefghijklm",                    0xe8a865539f4eadfeULL },
229     { "abcdefghijklmnopqrstu",            0x261cdf85faaf4e79ULL },
230     { "abcdefghijklmnopqrstuvwxyzabcdef", 0x43ba70e4198e3b2aULL },
231     { "abcdefghijklmnopqrstuvwxyzabcdef"
232       "abcdefghijklmnopqrstuvwxyzghijkl"
233       "abcdefghijklmnopqrstuvwxyzmnopqr"
234       "abcdefghijklmnopqrstuvwxyzstuvwx"
235       "abcdefghijklmnopqrstuvwxyzyzabcd", 0xdcd57fb2afdf72beULL },
236     { "a",                                0xaeb6f9d5517c61f8ULL },
237     { "aa",                               0xf2b3b69a9736a1ebULL },
238     { "aaa",                              0xf752eb6f07b1cafeULL },
239     { "aaaaa",                            0x812bd21e1236954cULL },
240     { "aaaaaaaa",                         0xff07a2cff08ac587ULL },
241     { "aaaaaaaaaaaaa",                    0x84ac949d54d704ecULL },
242     { "aaaaaaaaaaaaaaaaaaaaa",            0xcb2c8fb6be8f5648ULL },
243     { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xcc40ab7f164091b6ULL },
244     { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
245       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
246       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
247       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
248       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0xc58e174c1e78ffe9ULL },
249     { "z",                                0x1ba160d7e8f8785cULL },
250     { "zz",                               0x2c5c03172f1285d7ULL },
251     { "zzz",                              0x9d2c4f4b507a2ac3ULL },
252     { "zzzzz",                            0x0f03b9031735693aULL },
253     { "zzzzzzzz",                         0xe674147c8582c08eULL },
254     { "zzzzzzzzzzzzz",                    0x3162d9fa6938db83ULL },
255     { "zzzzzzzzzzzzzzzzzzzzz",            0x37b9a549e013620cULL },
256     { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0x8921470aff885016ULL },
257     { "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
258       "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
259       "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
260       "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
261       "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 0xf60fdcd9beb08441ULL },
262     { "a",                                0xaeb6f9d5517c61f8ULL },
263     { "ab",                               0x7ab1edb96be496b4ULL },
264     { "aba",                              0x3edb049950884d0aULL },
265     { "ababa",                            0x8f2de9e73a97714bULL },
266     { "abababab",                         0xee14a29ddf0ce54cULL },
267     { "ababababababa",                    0x38b3ddaada2d52b4ULL },
268     { "ababababababababababa",            0xd3665364219f2b85ULL },
269     { "abababababababababababababababab", 0xa75cd6afbf1bc972ULL },
270     { "abababababababababababababababab"
271       "abababababababababababababababab"
272       "abababababababababababababababab"
273       "abababababababababababababababab"
274       "abababababababababababababababab", 0x840192d129f7a22bULL }
275 #else
276 #error This test only supports 64-bit and 32-bit systems.
277 #endif
278   };
279   for (unsigned i = 0; i < sizeof(golden_data)/sizeof(*golden_data); ++i) {
280     StringRef str = golden_data[i].s;
281     hash_code hash = hash_combine_range(str.begin(), str.end());
282 #if 0 // Enable this to generate paste-able text for the above structure.
283     std::string member_str = "\"" + str.str() + "\",";
284     fprintf(stderr, " { %-35s 0x%016llxULL },\n",
285             member_str.c_str(), static_cast<uint64_t>(hash));
286 #endif
287     EXPECT_EQ(static_cast<size_t>(golden_data[i].hash),
288               static_cast<size_t>(hash));
289   }
290 }
291 
292 TEST(HashingTest, HashCombineBasicTest) {
293   // Hashing a sequence of homogenous types matches range hashing.
294   const int i1 = 42, i2 = 43, i3 = 123, i4 = 999, i5 = 0, i6 = 79;
295   const int arr1[] = { i1, i2, i3, i4, i5, i6 };
296   EXPECT_EQ(hash_combine_range(arr1, arr1 + 1), hash_combine(i1));
297   EXPECT_EQ(hash_combine_range(arr1, arr1 + 2), hash_combine(i1, i2));
298   EXPECT_EQ(hash_combine_range(arr1, arr1 + 3), hash_combine(i1, i2, i3));
299   EXPECT_EQ(hash_combine_range(arr1, arr1 + 4), hash_combine(i1, i2, i3, i4));
300   EXPECT_EQ(hash_combine_range(arr1, arr1 + 5),
301             hash_combine(i1, i2, i3, i4, i5));
302   EXPECT_EQ(hash_combine_range(arr1, arr1 + 6),
303             hash_combine(i1, i2, i3, i4, i5, i6));
304 
305   // Hashing a sequence of heterogeneous types which *happen* to all produce the
306   // same data for hashing produces the same as a range-based hash of the
307   // fundamental values.
308   const size_t s1 = 1024, s2 = 8888, s3 = 9000000;
309   const HashableDummy d1 = { 1024 }, d2 = { 8888 }, d3 = { 9000000 };
310   const size_t arr2[] = { s1, s2, s3 };
311   EXPECT_EQ(hash_combine_range(begin(arr2), end(arr2)),
312             hash_combine(s1, s2, s3));
313   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, s2, d3));
314   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(s1, d2, s3));
315   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, s2, s3));
316   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, s3));
317   EXPECT_EQ(hash_combine(s1, s2, s3), hash_combine(d1, d2, d3));
318 
319   // Permuting values causes hashes to change.
320   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i1, i2));
321   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i1, i2, i1));
322   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i1, i1));
323   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i1));
324   EXPECT_NE(hash_combine(i1, i1, i1), hash_combine(i2, i2, i2));
325   EXPECT_NE(hash_combine(i2, i1, i1), hash_combine(i1, i1, i2));
326   EXPECT_NE(hash_combine(i1, i1, i2), hash_combine(i1, i2, i1));
327   EXPECT_NE(hash_combine(i1, i2, i1), hash_combine(i2, i1, i1));
328 
329   // Changing type w/o changing value causes hashes to change.
330   EXPECT_NE(hash_combine(i1, i2, i3), hash_combine((char)i1, i2, i3));
331   EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, (char)i2, i3));
332   EXPECT_NE(hash_combine(i1, i2, i3), hash_combine(i1, i2, (char)i3));
333 
334   // This is array of uint64, but it should have the exact same byte pattern as
335   // an array of LargeTestIntegers.
336   const uint64_t bigarr[] = {
337     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
338     0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
339     0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
340     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
341     0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
342     0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
343     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
344     0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
345     0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
346   };
347   // Hash a preposterously large integer, both aligned with the buffer and
348   // misaligned.
349   const LargeTestInteger li = { {
350     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL,
351     0xdeadbeafdeadbeefULL, 0xfefefefededededeULL, 0xafafafafededededULL,
352     0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL
353   } };
354   // Rotate the storage from 'li'.
355   const LargeTestInteger l2 = { {
356     0xacacacacbcbcbcbcULL, 0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL,
357     0xfefefefededededeULL, 0xafafafafededededULL, 0xffffeeeeddddccccULL,
358     0xaaaacbcbffffababULL, 0xaaaaaaaaababababULL
359   } };
360   const LargeTestInteger l3 = { {
361     0xccddeeffeeddccbbULL, 0xdeadbeafdeadbeefULL, 0xfefefefededededeULL,
362     0xafafafafededededULL, 0xffffeeeeddddccccULL, 0xaaaacbcbffffababULL,
363     0xaaaaaaaaababababULL, 0xacacacacbcbcbcbcULL
364   } };
365   EXPECT_EQ(hash_combine_range(begin(bigarr), end(bigarr)),
366             hash_combine(li, li, li));
367   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 9),
368             hash_combine(bigarr[0], l2));
369   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 10),
370             hash_combine(bigarr[0], bigarr[1], l3));
371   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 17),
372             hash_combine(li, bigarr[0], l2));
373   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
374             hash_combine(li, bigarr[0], bigarr[1], l3));
375   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 18),
376             hash_combine(bigarr[0], l2, bigarr[9], l3));
377   EXPECT_EQ(hash_combine_range(bigarr, bigarr + 20),
378             hash_combine(bigarr[0], l2, bigarr[9], l3, bigarr[18], bigarr[19]));
379 }
380 
381 TEST(HashingTest, HashCombineArgs18) {
382   // This tests that we can pass in up to 18 args.
383 #define CHECK_SAME(...)                                                        \
384   EXPECT_EQ(hash_combine(__VA_ARGS__), hash_combine(__VA_ARGS__))
385   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18);
386   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
387   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
388   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
389   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
390   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
391   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
392   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
393   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
394   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8, 9);
395   CHECK_SAME(1, 2, 3, 4, 5, 6, 7, 8);
396   CHECK_SAME(1, 2, 3, 4, 5, 6, 7);
397   CHECK_SAME(1, 2, 3, 4, 5, 6);
398   CHECK_SAME(1, 2, 3, 4, 5);
399   CHECK_SAME(1, 2, 3, 4);
400   CHECK_SAME(1, 2, 3);
401   CHECK_SAME(1, 2);
402   CHECK_SAME(1);
403 #undef CHECK_SAME
404 }
405 
406 struct StructWithHashBuilderSupport {
407   char C;
408   int I;
409   template <typename HasherT, llvm::support::endianness Endianness>
410   friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
411                       const StructWithHashBuilderSupport &Value) {
412     HBuilder.add(Value.C, Value.I);
413   }
414 };
415 
416 TEST(HashingTest, HashWithHashBuilder) {
417   StructWithHashBuilderSupport S{'c', 1};
418   EXPECT_NE(static_cast<size_t>(llvm::hash_value(S)), static_cast<size_t>(0));
419 }
420 
421 struct StructWithHashBuilderAndHashValueSupport {
422   char C;
423   int I;
424   template <typename HasherT, llvm::support::endianness Endianness>
425   friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
426                       const StructWithHashBuilderAndHashValueSupport &Value) {}
427   friend hash_code
428   hash_value(const StructWithHashBuilderAndHashValueSupport &Value) {
429     return 0xbeef;
430   }
431 };
432 
433 TEST(HashingTest, HashBuilderAndHashValue) {
434   StructWithHashBuilderAndHashValueSupport S{'c', 1};
435   EXPECT_EQ(static_cast<size_t>(hash_value(S)), static_cast<size_t>(0xbeef));
436 }
437 
438 } // namespace
439