xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/hash-map-tests.c (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
13ad841b2Smrg /* Unit tests for hash-map.h.
2*4c3eb207Smrg    Copyright (C) 2015-2020 Free Software Foundation, Inc.
33ad841b2Smrg 
43ad841b2Smrg This file is part of GCC.
53ad841b2Smrg 
63ad841b2Smrg GCC is free software; you can redistribute it and/or modify it under
73ad841b2Smrg the terms of the GNU General Public License as published by the Free
83ad841b2Smrg Software Foundation; either version 3, or (at your option) any later
93ad841b2Smrg version.
103ad841b2Smrg 
113ad841b2Smrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
123ad841b2Smrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
133ad841b2Smrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
143ad841b2Smrg for more details.
153ad841b2Smrg 
163ad841b2Smrg You should have received a copy of the GNU General Public License
173ad841b2Smrg along with GCC; see the file COPYING3.  If not see
183ad841b2Smrg <http://www.gnu.org/licenses/>.  */
193ad841b2Smrg 
203ad841b2Smrg #include "config.h"
213ad841b2Smrg #include "system.h"
223ad841b2Smrg #include "coretypes.h"
233ad841b2Smrg #include "tm.h"
243ad841b2Smrg #include "opts.h"
253ad841b2Smrg #include "hash-set.h"
263ad841b2Smrg #include "fixed-value.h"
273ad841b2Smrg #include "alias.h"
283ad841b2Smrg #include "flags.h"
293ad841b2Smrg #include "symtab.h"
303ad841b2Smrg #include "tree-core.h"
313ad841b2Smrg #include "stor-layout.h"
323ad841b2Smrg #include "tree.h"
333ad841b2Smrg #include "stringpool.h"
343ad841b2Smrg #include "selftest.h"
353ad841b2Smrg 
363ad841b2Smrg #if CHECKING_P
373ad841b2Smrg 
383ad841b2Smrg namespace selftest {
393ad841b2Smrg 
403ad841b2Smrg /* Construct a hash_map <const char *, int> and verify that
413ad841b2Smrg    various operations work correctly.  */
423ad841b2Smrg 
433ad841b2Smrg static void
test_map_of_strings_to_int()443ad841b2Smrg test_map_of_strings_to_int ()
453ad841b2Smrg {
463ad841b2Smrg   hash_map <const char *, int> m;
473ad841b2Smrg 
483ad841b2Smrg   const char *ostrich = "ostrich";
493ad841b2Smrg   const char *elephant = "elephant";
503ad841b2Smrg   const char *ant = "ant";
513ad841b2Smrg   const char *spider = "spider";
523ad841b2Smrg   const char *millipede = "Illacme plenipes";
533ad841b2Smrg   const char *eric = "half a bee";
543ad841b2Smrg 
553ad841b2Smrg   /* A fresh hash_map should be empty.  */
56*4c3eb207Smrg   ASSERT_TRUE (m.is_empty ());
573ad841b2Smrg   ASSERT_EQ (NULL, m.get (ostrich));
583ad841b2Smrg 
593ad841b2Smrg   /* Populate the hash_map.  */
603ad841b2Smrg   ASSERT_EQ (false, m.put (ostrich, 2));
613ad841b2Smrg   ASSERT_EQ (false, m.put (elephant, 4));
623ad841b2Smrg   ASSERT_EQ (false, m.put (ant, 6));
633ad841b2Smrg   ASSERT_EQ (false, m.put (spider, 8));
643ad841b2Smrg   ASSERT_EQ (false, m.put (millipede, 750));
653ad841b2Smrg   ASSERT_EQ (false, m.put (eric, 3));
663ad841b2Smrg 
673ad841b2Smrg   /* Verify that we can recover the stored values.  */
683ad841b2Smrg   ASSERT_EQ (6, m.elements ());
693ad841b2Smrg   ASSERT_EQ (2, *m.get (ostrich));
703ad841b2Smrg   ASSERT_EQ (4, *m.get (elephant));
713ad841b2Smrg   ASSERT_EQ (6, *m.get (ant));
723ad841b2Smrg   ASSERT_EQ (8, *m.get (spider));
733ad841b2Smrg   ASSERT_EQ (750, *m.get (millipede));
743ad841b2Smrg   ASSERT_EQ (3, *m.get (eric));
753ad841b2Smrg 
763ad841b2Smrg   /* Verify removing an item.  */
773ad841b2Smrg   m.remove (eric);
783ad841b2Smrg   ASSERT_EQ (5, m.elements ());
793ad841b2Smrg   ASSERT_EQ (NULL, m.get (eric));
80627f7eb2Smrg 
81627f7eb2Smrg   m.remove (eric);
82627f7eb2Smrg   ASSERT_EQ (5, m.elements ());
83627f7eb2Smrg   ASSERT_EQ (NULL, m.get (eric));
84627f7eb2Smrg 
85627f7eb2Smrg   /* A plain char * key is hashed based on its value (address), rather
86627f7eb2Smrg      than the string it points to.  */
87627f7eb2Smrg   char *another_ant = static_cast <char *> (xcalloc (4, 1));
88627f7eb2Smrg   another_ant[0] = 'a';
89627f7eb2Smrg   another_ant[1] = 'n';
90627f7eb2Smrg   another_ant[2] = 't';
91627f7eb2Smrg   another_ant[3] = 0;
92627f7eb2Smrg   ASSERT_NE (ant, another_ant);
93627f7eb2Smrg   unsigned prev_size = m.elements ();
94627f7eb2Smrg   ASSERT_EQ (false, m.put (another_ant, 7));
95627f7eb2Smrg   ASSERT_EQ (prev_size + 1, m.elements ());
96627f7eb2Smrg 
97627f7eb2Smrg   /* Need to use string_hash or nofree_string_hash key types to hash
98627f7eb2Smrg      based on the string contents.  */
99627f7eb2Smrg   hash_map <nofree_string_hash, int> string_map;
100627f7eb2Smrg   ASSERT_EQ (false, string_map.put (ant, 1));
101627f7eb2Smrg   ASSERT_EQ (1, string_map.elements ());
102627f7eb2Smrg   ASSERT_EQ (true, string_map.put (another_ant, 5));
103627f7eb2Smrg   ASSERT_EQ (1, string_map.elements ());
104*4c3eb207Smrg 
105*4c3eb207Smrg   free (another_ant);
106*4c3eb207Smrg }
107*4c3eb207Smrg 
108*4c3eb207Smrg /* Construct a hash_map using int_hash and verify that
109*4c3eb207Smrg    various operations work correctly.  */
110*4c3eb207Smrg 
111*4c3eb207Smrg static void
test_map_of_int_to_strings()112*4c3eb207Smrg test_map_of_int_to_strings ()
113*4c3eb207Smrg {
114*4c3eb207Smrg   const int EMPTY = -1;
115*4c3eb207Smrg   const int DELETED = -2;
116*4c3eb207Smrg   typedef int_hash <int, EMPTY, DELETED> int_hash_t;
117*4c3eb207Smrg   hash_map <int_hash_t, const char *> m;
118*4c3eb207Smrg 
119*4c3eb207Smrg   const char *ostrich = "ostrich";
120*4c3eb207Smrg   const char *elephant = "elephant";
121*4c3eb207Smrg   const char *ant = "ant";
122*4c3eb207Smrg   const char *spider = "spider";
123*4c3eb207Smrg   const char *millipede = "Illacme plenipes";
124*4c3eb207Smrg   const char *eric = "half a bee";
125*4c3eb207Smrg 
126*4c3eb207Smrg   /* A fresh hash_map should be empty.  */
127*4c3eb207Smrg   ASSERT_EQ (0, m.elements ());
128*4c3eb207Smrg   ASSERT_EQ (NULL, m.get (2));
129*4c3eb207Smrg 
130*4c3eb207Smrg   /* Populate the hash_map.  */
131*4c3eb207Smrg   ASSERT_EQ (false, m.put (2, ostrich));
132*4c3eb207Smrg   ASSERT_EQ (false, m.put (4, elephant));
133*4c3eb207Smrg   ASSERT_EQ (false, m.put (6, ant));
134*4c3eb207Smrg   ASSERT_EQ (false, m.put (8, spider));
135*4c3eb207Smrg   ASSERT_EQ (false, m.put (750, millipede));
136*4c3eb207Smrg   ASSERT_EQ (false, m.put (3, eric));
137*4c3eb207Smrg 
138*4c3eb207Smrg   /* Verify that we can recover the stored values.  */
139*4c3eb207Smrg   ASSERT_EQ (6, m.elements ());
140*4c3eb207Smrg   ASSERT_EQ (*m.get (2), ostrich);
141*4c3eb207Smrg   ASSERT_EQ (*m.get (4), elephant);
142*4c3eb207Smrg   ASSERT_EQ (*m.get (6), ant);
143*4c3eb207Smrg   ASSERT_EQ (*m.get (8), spider);
144*4c3eb207Smrg   ASSERT_EQ (*m.get (750), millipede);
145*4c3eb207Smrg   ASSERT_EQ (*m.get (3), eric);
146*4c3eb207Smrg }
147*4c3eb207Smrg 
148*4c3eb207Smrg typedef class hash_map_test_val_t
149*4c3eb207Smrg {
150*4c3eb207Smrg public:
151*4c3eb207Smrg   static int ndefault;
152*4c3eb207Smrg   static int ncopy;
153*4c3eb207Smrg   static int nassign;
154*4c3eb207Smrg   static int ndtor;
155*4c3eb207Smrg 
156*4c3eb207Smrg   hash_map_test_val_t ()
157*4c3eb207Smrg     : ptr (&ptr)
158*4c3eb207Smrg   {
159*4c3eb207Smrg     ++ndefault;
160*4c3eb207Smrg   }
161*4c3eb207Smrg 
162*4c3eb207Smrg   hash_map_test_val_t (const hash_map_test_val_t &rhs)
163*4c3eb207Smrg     : ptr (&ptr)
164*4c3eb207Smrg   {
165*4c3eb207Smrg     ++ncopy;
166*4c3eb207Smrg     gcc_assert (rhs.ptr == &rhs.ptr);
167*4c3eb207Smrg   }
168*4c3eb207Smrg 
169*4c3eb207Smrg   hash_map_test_val_t& operator= (const hash_map_test_val_t &rhs)
170*4c3eb207Smrg   {
171*4c3eb207Smrg     ++nassign;
172*4c3eb207Smrg     gcc_assert (ptr == &ptr);
173*4c3eb207Smrg     gcc_assert (rhs.ptr == &rhs.ptr);
174*4c3eb207Smrg     return *this;
175*4c3eb207Smrg   }
176*4c3eb207Smrg 
177*4c3eb207Smrg   ~hash_map_test_val_t ()
178*4c3eb207Smrg   {
179*4c3eb207Smrg     gcc_assert (ptr == &ptr);
180*4c3eb207Smrg     ++ndtor;
181*4c3eb207Smrg   }
182*4c3eb207Smrg 
183*4c3eb207Smrg   void *ptr;
184*4c3eb207Smrg } val_t;
185*4c3eb207Smrg 
186*4c3eb207Smrg int val_t::ndefault;
187*4c3eb207Smrg int val_t::ncopy;
188*4c3eb207Smrg int val_t::nassign;
189*4c3eb207Smrg int val_t::ndtor;
190*4c3eb207Smrg 
191*4c3eb207Smrg static void
test_map_of_type_with_ctor_and_dtor()192*4c3eb207Smrg test_map_of_type_with_ctor_and_dtor ()
193*4c3eb207Smrg {
194*4c3eb207Smrg   typedef hash_map <void *, val_t> Map;
195*4c3eb207Smrg 
196*4c3eb207Smrg   {
197*4c3eb207Smrg     /* Test default ctor.  */
198*4c3eb207Smrg     Map m;
199*4c3eb207Smrg     (void)&m;
200*4c3eb207Smrg   }
201*4c3eb207Smrg 
202*4c3eb207Smrg   ASSERT_TRUE (val_t::ndefault == 0);
203*4c3eb207Smrg   ASSERT_TRUE (val_t::ncopy == 0);
204*4c3eb207Smrg   ASSERT_TRUE (val_t::nassign == 0);
205*4c3eb207Smrg   ASSERT_TRUE (val_t::ndtor == 0);
206*4c3eb207Smrg 
207*4c3eb207Smrg   {
208*4c3eb207Smrg     /* Test single insertion.  */
209*4c3eb207Smrg     Map m;
210*4c3eb207Smrg     void *p = &p;
211*4c3eb207Smrg     m.get_or_insert (p);
212*4c3eb207Smrg   }
213*4c3eb207Smrg 
214*4c3eb207Smrg   ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
215*4c3eb207Smrg 
216*4c3eb207Smrg   {
217*4c3eb207Smrg     /* Test copy ctor.  */
218*4c3eb207Smrg     Map m1;
219*4c3eb207Smrg     void *p = &p;
220*4c3eb207Smrg     val_t &rv1 = m1.get_or_insert (p);
221*4c3eb207Smrg 
222*4c3eb207Smrg     int ncopy = val_t::ncopy;
223*4c3eb207Smrg     int nassign = val_t::nassign;
224*4c3eb207Smrg 
225*4c3eb207Smrg     Map m2 (m1);
226*4c3eb207Smrg     val_t *pv2 = m2.get (p);
227*4c3eb207Smrg 
228*4c3eb207Smrg     ASSERT_TRUE (ncopy + 1 == val_t::ncopy);
229*4c3eb207Smrg     ASSERT_TRUE (nassign == val_t::nassign);
230*4c3eb207Smrg 
231*4c3eb207Smrg     ASSERT_TRUE (&rv1 != pv2);
232*4c3eb207Smrg   }
233*4c3eb207Smrg 
234*4c3eb207Smrg   ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
235*4c3eb207Smrg 
236*4c3eb207Smrg #if 0   /* Avoid testing until bug 90959 is fixed.  */
237*4c3eb207Smrg   {
238*4c3eb207Smrg     /* Test copy assignment into an empty map.  */
239*4c3eb207Smrg     Map m1;
240*4c3eb207Smrg     void *p = &p;
241*4c3eb207Smrg     val_t &rv1 = m1.get_or_insert (p);
242*4c3eb207Smrg 
243*4c3eb207Smrg     int ncopy = val_t::ncopy;
244*4c3eb207Smrg     int nassign = val_t::nassign;
245*4c3eb207Smrg 
246*4c3eb207Smrg     Map m2;
247*4c3eb207Smrg     m2 = m1;
248*4c3eb207Smrg     val_t *pv2 = m2.get (p);
249*4c3eb207Smrg 
250*4c3eb207Smrg     ASSERT_TRUE (ncopy == val_t::ncopy);
251*4c3eb207Smrg     ASSERT_TRUE (nassign + 1 == val_t::nassign);
252*4c3eb207Smrg 
253*4c3eb207Smrg     ASSERT_TRUE (&rv1 != pv2);
254*4c3eb207Smrg   }
255*4c3eb207Smrg 
256*4c3eb207Smrg   ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
257*4c3eb207Smrg 
258*4c3eb207Smrg #endif
259*4c3eb207Smrg 
260*4c3eb207Smrg   {
261*4c3eb207Smrg     Map m;
262*4c3eb207Smrg     void *p = &p, *q = &q;
263*4c3eb207Smrg     val_t &v1 = m.get_or_insert (p);
264*4c3eb207Smrg     val_t &v2 = m.get_or_insert (q);
265*4c3eb207Smrg 
266*4c3eb207Smrg     ASSERT_TRUE (v1.ptr == &v1.ptr && &v2.ptr == v2.ptr);
267*4c3eb207Smrg   }
268*4c3eb207Smrg 
269*4c3eb207Smrg   ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
270*4c3eb207Smrg 
271*4c3eb207Smrg   {
272*4c3eb207Smrg     Map m;
273*4c3eb207Smrg     void *p = &p, *q = &q;
274*4c3eb207Smrg     m.get_or_insert (p);
275*4c3eb207Smrg     m.remove (p);
276*4c3eb207Smrg     m.get_or_insert (q);
277*4c3eb207Smrg     m.remove (q);
278*4c3eb207Smrg 
279*4c3eb207Smrg     ASSERT_TRUE (val_t::ndefault + val_t::ncopy == val_t::ndtor);
280*4c3eb207Smrg   }
281*4c3eb207Smrg }
282*4c3eb207Smrg 
283*4c3eb207Smrg /* Test calling empty on a hash_map that has a key type with non-zero
284*4c3eb207Smrg    "empty" value.  */
285*4c3eb207Smrg 
286*4c3eb207Smrg static void
test_nonzero_empty_key()287*4c3eb207Smrg test_nonzero_empty_key ()
288*4c3eb207Smrg {
289*4c3eb207Smrg   typedef int_hash<int, INT_MIN, INT_MAX> IntHash;
290*4c3eb207Smrg   hash_map<int, int, simple_hashmap_traits<IntHash, int> > x;
291*4c3eb207Smrg 
292*4c3eb207Smrg   for (int i = 1; i != 32; ++i)
293*4c3eb207Smrg     x.put (i, i);
294*4c3eb207Smrg 
295*4c3eb207Smrg   ASSERT_EQ (x.get (0), NULL);
296*4c3eb207Smrg   ASSERT_EQ (*x.get (1), 1);
297*4c3eb207Smrg 
298*4c3eb207Smrg   x.empty ();
299*4c3eb207Smrg 
300*4c3eb207Smrg   ASSERT_EQ (x.get (0), NULL);
301*4c3eb207Smrg   ASSERT_EQ (x.get (1), NULL);
3023ad841b2Smrg }
3033ad841b2Smrg 
3043ad841b2Smrg /* Run all of the selftests within this file.  */
3053ad841b2Smrg 
3063ad841b2Smrg void
hash_map_tests_c_tests()3073ad841b2Smrg hash_map_tests_c_tests ()
3083ad841b2Smrg {
3093ad841b2Smrg   test_map_of_strings_to_int ();
310*4c3eb207Smrg   test_map_of_int_to_strings ();
311*4c3eb207Smrg   test_map_of_type_with_ctor_and_dtor ();
312*4c3eb207Smrg   test_nonzero_empty_key ();
3133ad841b2Smrg }
3143ad841b2Smrg 
3153ad841b2Smrg } // namespace selftest
3163ad841b2Smrg 
3173ad841b2Smrg #endif /* CHECKING_P */
318