1 /* Unit tests for hash-map.h.
2 Copyright (C) 2015-2020 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
26 #include "fixed-value.h"
30 #include "tree-core.h"
31 #include "stor-layout.h"
33 #include "stringpool.h"
40 /* Construct a hash_map <const char *, int> and verify that
41 various operations work correctly. */
44 test_map_of_strings_to_int ()
46 hash_map
<const char *, int> m
;
48 const char *ostrich
= "ostrich";
49 const char *elephant
= "elephant";
50 const char *ant
= "ant";
51 const char *spider
= "spider";
52 const char *millipede
= "Illacme plenipes";
53 const char *eric
= "half a bee";
55 /* A fresh hash_map should be empty. */
56 ASSERT_TRUE (m
.is_empty ());
57 ASSERT_EQ (NULL
, m
.get (ostrich
));
59 /* Populate the hash_map. */
60 ASSERT_EQ (false, m
.put (ostrich
, 2));
61 ASSERT_EQ (false, m
.put (elephant
, 4));
62 ASSERT_EQ (false, m
.put (ant
, 6));
63 ASSERT_EQ (false, m
.put (spider
, 8));
64 ASSERT_EQ (false, m
.put (millipede
, 750));
65 ASSERT_EQ (false, m
.put (eric
, 3));
67 /* Verify that we can recover the stored values. */
68 ASSERT_EQ (6, m
.elements ());
69 ASSERT_EQ (2, *m
.get (ostrich
));
70 ASSERT_EQ (4, *m
.get (elephant
));
71 ASSERT_EQ (6, *m
.get (ant
));
72 ASSERT_EQ (8, *m
.get (spider
));
73 ASSERT_EQ (750, *m
.get (millipede
));
74 ASSERT_EQ (3, *m
.get (eric
));
76 /* Verify removing an item. */
78 ASSERT_EQ (5, m
.elements ());
79 ASSERT_EQ (NULL
, m
.get (eric
));
82 ASSERT_EQ (5, m
.elements ());
83 ASSERT_EQ (NULL
, m
.get (eric
));
85 /* A plain char * key is hashed based on its value (address), rather
86 than the string it points to. */
87 char *another_ant
= static_cast <char *> (xcalloc (4, 1));
92 ASSERT_NE (ant
, another_ant
);
93 unsigned prev_size
= m
.elements ();
94 ASSERT_EQ (false, m
.put (another_ant
, 7));
95 ASSERT_EQ (prev_size
+ 1, m
.elements ());
97 /* Need to use string_hash or nofree_string_hash key types to hash
98 based on the string contents. */
99 hash_map
<nofree_string_hash
, int> string_map
;
100 ASSERT_EQ (false, string_map
.put (ant
, 1));
101 ASSERT_EQ (1, string_map
.elements ());
102 ASSERT_EQ (true, string_map
.put (another_ant
, 5));
103 ASSERT_EQ (1, string_map
.elements ());
108 /* Construct a hash_map using int_hash and verify that
109 various operations work correctly. */
112 test_map_of_int_to_strings ()
114 const int EMPTY
= -1;
115 const int DELETED
= -2;
116 typedef int_hash
<int, EMPTY
, DELETED
> int_hash_t
;
117 hash_map
<int_hash_t
, const char *> m
;
119 const char *ostrich
= "ostrich";
120 const char *elephant
= "elephant";
121 const char *ant
= "ant";
122 const char *spider
= "spider";
123 const char *millipede
= "Illacme plenipes";
124 const char *eric
= "half a bee";
126 /* A fresh hash_map should be empty. */
127 ASSERT_EQ (0, m
.elements ());
128 ASSERT_EQ (NULL
, m
.get (2));
130 /* Populate the hash_map. */
131 ASSERT_EQ (false, m
.put (2, ostrich
));
132 ASSERT_EQ (false, m
.put (4, elephant
));
133 ASSERT_EQ (false, m
.put (6, ant
));
134 ASSERT_EQ (false, m
.put (8, spider
));
135 ASSERT_EQ (false, m
.put (750, millipede
));
136 ASSERT_EQ (false, m
.put (3, eric
));
138 /* Verify that we can recover the stored values. */
139 ASSERT_EQ (6, m
.elements ());
140 ASSERT_EQ (*m
.get (2), ostrich
);
141 ASSERT_EQ (*m
.get (4), elephant
);
142 ASSERT_EQ (*m
.get (6), ant
);
143 ASSERT_EQ (*m
.get (8), spider
);
144 ASSERT_EQ (*m
.get (750), millipede
);
145 ASSERT_EQ (*m
.get (3), eric
);
148 typedef class hash_map_test_val_t
156 hash_map_test_val_t ()
162 hash_map_test_val_t (const hash_map_test_val_t
&rhs
)
166 gcc_assert (rhs
.ptr
== &rhs
.ptr
);
169 hash_map_test_val_t
& operator= (const hash_map_test_val_t
&rhs
)
172 gcc_assert (ptr
== &ptr
);
173 gcc_assert (rhs
.ptr
== &rhs
.ptr
);
177 ~hash_map_test_val_t ()
179 gcc_assert (ptr
== &ptr
);
192 test_map_of_type_with_ctor_and_dtor ()
194 typedef hash_map
<void *, val_t
> Map
;
197 /* Test default ctor. */
202 ASSERT_TRUE (val_t::ndefault
== 0);
203 ASSERT_TRUE (val_t::ncopy
== 0);
204 ASSERT_TRUE (val_t::nassign
== 0);
205 ASSERT_TRUE (val_t::ndtor
== 0);
208 /* Test single insertion. */
214 ASSERT_TRUE (val_t::ndefault
+ val_t::ncopy
== val_t::ndtor
);
217 /* Test copy ctor. */
220 val_t
&rv1
= m1
.get_or_insert (p
);
222 int ncopy
= val_t::ncopy
;
223 int nassign
= val_t::nassign
;
226 val_t
*pv2
= m2
.get (p
);
228 ASSERT_TRUE (ncopy
+ 1 == val_t::ncopy
);
229 ASSERT_TRUE (nassign
== val_t::nassign
);
231 ASSERT_TRUE (&rv1
!= pv2
);
234 ASSERT_TRUE (val_t::ndefault
+ val_t::ncopy
== val_t::ndtor
);
236 #if 0 /* Avoid testing until bug 90959 is fixed. */
238 /* Test copy assignment into an empty map. */
241 val_t
&rv1
= m1
.get_or_insert (p
);
243 int ncopy
= val_t::ncopy
;
244 int nassign
= val_t::nassign
;
248 val_t
*pv2
= m2
.get (p
);
250 ASSERT_TRUE (ncopy
== val_t::ncopy
);
251 ASSERT_TRUE (nassign
+ 1 == val_t::nassign
);
253 ASSERT_TRUE (&rv1
!= pv2
);
256 ASSERT_TRUE (val_t::ndefault
+ val_t::ncopy
== val_t::ndtor
);
262 void *p
= &p
, *q
= &q
;
263 val_t
&v1
= m
.get_or_insert (p
);
264 val_t
&v2
= m
.get_or_insert (q
);
266 ASSERT_TRUE (v1
.ptr
== &v1
.ptr
&& &v2
.ptr
== v2
.ptr
);
269 ASSERT_TRUE (val_t::ndefault
+ val_t::ncopy
== val_t::ndtor
);
273 void *p
= &p
, *q
= &q
;
279 ASSERT_TRUE (val_t::ndefault
+ val_t::ncopy
== val_t::ndtor
);
283 /* Test calling empty on a hash_map that has a key type with non-zero
287 test_nonzero_empty_key ()
289 typedef int_hash
<int, INT_MIN
, INT_MAX
> IntHash
;
290 hash_map
<int, int, simple_hashmap_traits
<IntHash
, int> > x
;
292 for (int i
= 1; i
!= 32; ++i
)
295 ASSERT_EQ (x
.get (0), NULL
);
296 ASSERT_EQ (*x
.get (1), 1);
300 ASSERT_EQ (x
.get (0), NULL
);
301 ASSERT_EQ (x
.get (1), NULL
);
304 /* Run all of the selftests within this file. */
307 hash_map_tests_c_tests ()
309 test_map_of_strings_to_int ();
310 test_map_of_int_to_strings ();
311 test_map_of_type_with_ctor_and_dtor ();
312 test_nonzero_empty_key ();
315 } // namespace selftest
317 #endif /* CHECKING_P */