xref: /dflybsd-src/contrib/gcc-8.0/gcc/vec.c (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* Vector API for GNU compiler.
2*38fd1498Szrj    Copyright (C) 2004-2018 Free Software Foundation, Inc.
3*38fd1498Szrj    Contributed by Nathan Sidwell <nathan@codesourcery.com>
4*38fd1498Szrj    Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
5*38fd1498Szrj 
6*38fd1498Szrj This file is part of GCC.
7*38fd1498Szrj 
8*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
9*38fd1498Szrj the terms of the GNU General Public License as published by the Free
10*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
11*38fd1498Szrj version.
12*38fd1498Szrj 
13*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*38fd1498Szrj for more details.
17*38fd1498Szrj 
18*38fd1498Szrj You should have received a copy of the GNU General Public License
19*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
20*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
21*38fd1498Szrj 
22*38fd1498Szrj /* This file is compiled twice: once for the generator programs
23*38fd1498Szrj    once for the compiler.  */
24*38fd1498Szrj #ifdef GENERATOR_FILE
25*38fd1498Szrj #include "bconfig.h"
26*38fd1498Szrj #else
27*38fd1498Szrj #include "config.h"
28*38fd1498Szrj #endif
29*38fd1498Szrj 
30*38fd1498Szrj #include "system.h"
31*38fd1498Szrj #include "coretypes.h"
32*38fd1498Szrj #include "hash-table.h"
33*38fd1498Szrj #include "selftest.h"
34*38fd1498Szrj #ifdef GENERATOR_FILE
35*38fd1498Szrj #include "errors.h"
36*38fd1498Szrj #else
37*38fd1498Szrj #include "input.h"
38*38fd1498Szrj #include "diagnostic-core.h"
39*38fd1498Szrj #endif
40*38fd1498Szrj 
41*38fd1498Szrj /* vNULL is an empty type with a template cast operation that returns
42*38fd1498Szrj    a zero-initialized vec<T, A, L> instance.  Use this when you want
43*38fd1498Szrj    to assign nil values to new vec instances or pass a nil vector as
44*38fd1498Szrj    a function call argument.
45*38fd1498Szrj 
46*38fd1498Szrj    We use this technique because vec<T, A, L> must be PODs (they are
47*38fd1498Szrj    stored in unions and passed in vararg functions), this means that
48*38fd1498Szrj    they cannot have ctors/dtors.  */
49*38fd1498Szrj vnull vNULL;
50*38fd1498Szrj 
51*38fd1498Szrj /* Vector memory usage.  */
52*38fd1498Szrj struct vec_usage: public mem_usage
53*38fd1498Szrj {
54*38fd1498Szrj   /* Default constructor.  */
vec_usagevec_usage55*38fd1498Szrj   vec_usage (): m_items (0), m_items_peak (0) {}
56*38fd1498Szrj 
57*38fd1498Szrj   /* Constructor.  */
vec_usagevec_usage58*38fd1498Szrj   vec_usage (size_t allocated, size_t times, size_t peak,
59*38fd1498Szrj 	     size_t items, size_t items_peak)
60*38fd1498Szrj     : mem_usage (allocated, times, peak),
61*38fd1498Szrj     m_items (items), m_items_peak (items_peak) {}
62*38fd1498Szrj 
63*38fd1498Szrj   /* Sum the usage with SECOND usage.  */
64*38fd1498Szrj   vec_usage
65*38fd1498Szrj   operator+ (const vec_usage &second)
66*38fd1498Szrj   {
67*38fd1498Szrj     return vec_usage (m_allocated + second.m_allocated,
68*38fd1498Szrj 		      m_times + second.m_times,
69*38fd1498Szrj 		      m_peak + second.m_peak,
70*38fd1498Szrj 		      m_items + second.m_items,
71*38fd1498Szrj 		      m_items_peak + second.m_items_peak);
72*38fd1498Szrj   }
73*38fd1498Szrj 
74*38fd1498Szrj   /* Dump usage coupled to LOC location, where TOTAL is sum of all rows.  */
75*38fd1498Szrj   inline void
dumpvec_usage76*38fd1498Szrj   dump (mem_location *loc, mem_usage &total) const
77*38fd1498Szrj   {
78*38fd1498Szrj     char s[4096];
79*38fd1498Szrj     sprintf (s, "%s:%i (%s)", loc->get_trimmed_filename (),
80*38fd1498Szrj 	     loc->m_line, loc->m_function);
81*38fd1498Szrj 
82*38fd1498Szrj     s[48] = '\0';
83*38fd1498Szrj 
84*38fd1498Szrj     fprintf (stderr, "%-48s %10li:%4.1f%%%10li%10li:%4.1f%%%11li%11li\n", s,
85*38fd1498Szrj 	     (long)m_allocated, m_allocated * 100.0 / total.m_allocated,
86*38fd1498Szrj 	     (long)m_peak, (long)m_times, m_times * 100.0 / total.m_times,
87*38fd1498Szrj 	     (long)m_items, (long)m_items_peak);
88*38fd1498Szrj   }
89*38fd1498Szrj 
90*38fd1498Szrj   /* Dump footer.  */
91*38fd1498Szrj   inline void
dump_footervec_usage92*38fd1498Szrj   dump_footer ()
93*38fd1498Szrj   {
94*38fd1498Szrj     print_dash_line ();
95*38fd1498Szrj     fprintf (stderr, "%s%55li%25li%17li\n", "Total", (long)m_allocated,
96*38fd1498Szrj 	     (long)m_times, (long)m_items);
97*38fd1498Szrj     print_dash_line ();
98*38fd1498Szrj   }
99*38fd1498Szrj 
100*38fd1498Szrj   /* Dump header with NAME.  */
101*38fd1498Szrj   static inline void
dump_headervec_usage102*38fd1498Szrj   dump_header (const char *name)
103*38fd1498Szrj   {
104*38fd1498Szrj     fprintf (stderr, "%-48s %11s%15s%10s%17s%11s\n", name, "Leak", "Peak",
105*38fd1498Szrj 	     "Times", "Leak items", "Peak items");
106*38fd1498Szrj     print_dash_line ();
107*38fd1498Szrj   }
108*38fd1498Szrj 
109*38fd1498Szrj   /* Current number of items allocated.  */
110*38fd1498Szrj   size_t m_items;
111*38fd1498Szrj   /* Peak value of number of allocated items.  */
112*38fd1498Szrj   size_t m_items_peak;
113*38fd1498Szrj };
114*38fd1498Szrj 
115*38fd1498Szrj /* Vector memory description.  */
116*38fd1498Szrj static mem_alloc_description <vec_usage> vec_mem_desc;
117*38fd1498Szrj 
118*38fd1498Szrj /* Account the overhead.  */
119*38fd1498Szrj 
120*38fd1498Szrj void
register_overhead(void * ptr,size_t size,size_t elements MEM_STAT_DECL)121*38fd1498Szrj vec_prefix::register_overhead (void *ptr, size_t size, size_t elements
122*38fd1498Szrj 			       MEM_STAT_DECL)
123*38fd1498Szrj {
124*38fd1498Szrj   vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN, false
125*38fd1498Szrj 				    FINAL_PASS_MEM_STAT);
126*38fd1498Szrj   vec_usage *usage = vec_mem_desc.register_instance_overhead (size, ptr);
127*38fd1498Szrj   usage->m_items += elements;
128*38fd1498Szrj   if (usage->m_items_peak < usage->m_items)
129*38fd1498Szrj     usage->m_items_peak = usage->m_items;
130*38fd1498Szrj }
131*38fd1498Szrj 
132*38fd1498Szrj /* Notice that the memory allocated for the vector has been freed.  */
133*38fd1498Szrj 
134*38fd1498Szrj void
release_overhead(void * ptr,size_t size,bool in_dtor MEM_STAT_DECL)135*38fd1498Szrj vec_prefix::release_overhead (void *ptr, size_t size, bool in_dtor
136*38fd1498Szrj 			      MEM_STAT_DECL)
137*38fd1498Szrj {
138*38fd1498Szrj   if (!vec_mem_desc.contains_descriptor_for_instance (ptr))
139*38fd1498Szrj     vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN,
140*38fd1498Szrj 				      false FINAL_PASS_MEM_STAT);
141*38fd1498Szrj   vec_mem_desc.release_instance_overhead (ptr, size, in_dtor);
142*38fd1498Szrj }
143*38fd1498Szrj 
144*38fd1498Szrj 
145*38fd1498Szrj /* Calculate the number of slots to reserve a vector, making sure that
146*38fd1498Szrj    it is of at least DESIRED size by growing ALLOC exponentially.  */
147*38fd1498Szrj 
148*38fd1498Szrj unsigned
calculate_allocation_1(unsigned alloc,unsigned desired)149*38fd1498Szrj vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired)
150*38fd1498Szrj {
151*38fd1498Szrj   /* We must have run out of room.  */
152*38fd1498Szrj   gcc_assert (alloc < desired);
153*38fd1498Szrj 
154*38fd1498Szrj   /* Exponential growth. */
155*38fd1498Szrj   if (!alloc)
156*38fd1498Szrj     alloc = 4;
157*38fd1498Szrj   else if (alloc < 16)
158*38fd1498Szrj     /* Double when small.  */
159*38fd1498Szrj     alloc = alloc * 2;
160*38fd1498Szrj   else
161*38fd1498Szrj     /* Grow slower when large.  */
162*38fd1498Szrj     alloc = (alloc * 3 / 2);
163*38fd1498Szrj 
164*38fd1498Szrj   /* If this is still too small, set it to the right size. */
165*38fd1498Szrj   if (alloc < desired)
166*38fd1498Szrj     alloc = desired;
167*38fd1498Szrj   return alloc;
168*38fd1498Szrj }
169*38fd1498Szrj 
170*38fd1498Szrj /* Dump per-site memory statistics.  */
171*38fd1498Szrj 
172*38fd1498Szrj void
dump_vec_loc_statistics(void)173*38fd1498Szrj dump_vec_loc_statistics (void)
174*38fd1498Szrj {
175*38fd1498Szrj   vec_mem_desc.dump (VEC_ORIGIN);
176*38fd1498Szrj }
177*38fd1498Szrj 
178*38fd1498Szrj #if CHECKING_P
179*38fd1498Szrj /* Report qsort comparator CMP consistency check failure with P1, P2, P3 as
180*38fd1498Szrj    witness elements.  */
181*38fd1498Szrj ATTRIBUTE_NORETURN ATTRIBUTE_COLD
182*38fd1498Szrj static void
qsort_chk_error(const void * p1,const void * p2,const void * p3,int (* cmp)(const void *,const void *))183*38fd1498Szrj qsort_chk_error (const void *p1, const void *p2, const void *p3,
184*38fd1498Szrj 		 int (*cmp) (const void *, const void *))
185*38fd1498Szrj {
186*38fd1498Szrj   if (!p3)
187*38fd1498Szrj     {
188*38fd1498Szrj       int r1 = cmp (p1, p2), r2 = cmp (p2, p1);
189*38fd1498Szrj       error ("qsort comparator not anti-commutative: %d, %d", r1, r2);
190*38fd1498Szrj     }
191*38fd1498Szrj   else if (p1 == p2)
192*38fd1498Szrj     {
193*38fd1498Szrj       int r = cmp (p1, p3);
194*38fd1498Szrj       error ("qsort comparator non-negative on sorted output: %d", r);
195*38fd1498Szrj     }
196*38fd1498Szrj   else
197*38fd1498Szrj     {
198*38fd1498Szrj       int r1 = cmp (p1, p2), r2 = cmp (p2, p3), r3 = cmp (p1, p3);
199*38fd1498Szrj       error ("qsort comparator not transitive: %d, %d, %d", r1, r2, r3);
200*38fd1498Szrj     }
201*38fd1498Szrj   internal_error ("qsort checking failed");
202*38fd1498Szrj }
203*38fd1498Szrj 
204*38fd1498Szrj /* Wrapper around qsort with checking that CMP is consistent on given input.
205*38fd1498Szrj 
206*38fd1498Szrj    Strictly speaking, passing invalid (non-transitive, non-anti-commutative)
207*38fd1498Szrj    comparators to libc qsort can result in undefined behavior.  Therefore we
208*38fd1498Szrj    should ideally perform consistency checks prior to invoking qsort, but in
209*38fd1498Szrj    order to do that optimally we'd need to sort the array ourselves beforehand
210*38fd1498Szrj    with a sorting routine known to be "safe".  Instead, we expect that most
211*38fd1498Szrj    implementations in practice will still produce some permutation of input
212*38fd1498Szrj    array even for invalid comparators, which enables us to perform checks on
213*38fd1498Szrj    the output array.  */
214*38fd1498Szrj void
qsort_chk(void * base,size_t n,size_t size,int (* cmp)(const void *,const void *))215*38fd1498Szrj qsort_chk (void *base, size_t n, size_t size,
216*38fd1498Szrj 	   int (*cmp)(const void *, const void *))
217*38fd1498Szrj {
218*38fd1498Szrj   (qsort) (base, n, size, cmp);
219*38fd1498Szrj #if 0
220*38fd1498Szrj #define LIM(n) (n)
221*38fd1498Szrj #else
222*38fd1498Szrj   /* Limit overall time complexity to O(n log n).  */
223*38fd1498Szrj #define LIM(n) ((n) <= 16 ? (n) : 12 + floor_log2 (n))
224*38fd1498Szrj #endif
225*38fd1498Szrj #define ELT(i) ((const char *) base + (i) * size)
226*38fd1498Szrj #define CMP(i, j) cmp (ELT (i), ELT (j))
227*38fd1498Szrj #define ERR2(i, j) qsort_chk_error (ELT (i), ELT (j), NULL, cmp)
228*38fd1498Szrj #define ERR3(i, j, k) qsort_chk_error (ELT (i), ELT (j), ELT (k), cmp)
229*38fd1498Szrj   size_t i1, i2, i, j;
230*38fd1498Szrj   /* This outer loop iterates over maximum spans [i1, i2) such that
231*38fd1498Szrj      elements within each span compare equal to each other.  */
232*38fd1498Szrj   for (i1 = 0; i1 < n; i1 = i2)
233*38fd1498Szrj     {
234*38fd1498Szrj       /* Position i2 one past last element that compares equal to i1'th.  */
235*38fd1498Szrj       for (i2 = i1 + 1; i2 < n; i2++)
236*38fd1498Szrj 	if (CMP (i1, i2))
237*38fd1498Szrj 	  break;
238*38fd1498Szrj 	else if (CMP (i2, i1))
239*38fd1498Szrj 	  return ERR2 (i1, i2);
240*38fd1498Szrj       size_t lim1 = LIM (i2 - i1), lim2 = LIM (n - i2);
241*38fd1498Szrj       /* Verify that other pairs within current span compare equal.  */
242*38fd1498Szrj       for (i = i1 + 1; i + 1 < i2; i++)
243*38fd1498Szrj 	for (j = i + 1; j < i1 + lim1; j++)
244*38fd1498Szrj 	  if (CMP (i, j))
245*38fd1498Szrj 	    return ERR3 (i, i1, j);
246*38fd1498Szrj 	  else if (CMP (j, i))
247*38fd1498Szrj 	    return ERR2 (i, j);
248*38fd1498Szrj       /* Verify that elements within this span compare less than
249*38fd1498Szrj          elements beyond the span.  */
250*38fd1498Szrj       for (i = i1; i < i2; i++)
251*38fd1498Szrj 	for (j = i2; j < i2 + lim2; j++)
252*38fd1498Szrj 	  if (CMP (i, j) >= 0)
253*38fd1498Szrj 	    return ERR3 (i, i1, j);
254*38fd1498Szrj 	  else if (CMP (j, i) <= 0)
255*38fd1498Szrj 	    return ERR2 (i, j);
256*38fd1498Szrj     }
257*38fd1498Szrj #undef ERR3
258*38fd1498Szrj #undef ERR2
259*38fd1498Szrj #undef CMP
260*38fd1498Szrj #undef ELT
261*38fd1498Szrj #undef LIM
262*38fd1498Szrj }
263*38fd1498Szrj #endif /* #if CHECKING_P */
264*38fd1498Szrj 
265*38fd1498Szrj #ifndef GENERATOR_FILE
266*38fd1498Szrj #if CHECKING_P
267*38fd1498Szrj 
268*38fd1498Szrj namespace selftest {
269*38fd1498Szrj 
270*38fd1498Szrj /* Selftests.  */
271*38fd1498Szrj 
272*38fd1498Szrj /* Call V.safe_push for all ints from START up to, but not including LIMIT.
273*38fd1498Szrj    Helper function for selftests.  */
274*38fd1498Szrj 
275*38fd1498Szrj static void
safe_push_range(vec<int> & v,int start,int limit)276*38fd1498Szrj safe_push_range (vec <int>&v, int start, int limit)
277*38fd1498Szrj {
278*38fd1498Szrj   for (int i = start; i < limit; i++)
279*38fd1498Szrj     v.safe_push (i);
280*38fd1498Szrj }
281*38fd1498Szrj 
282*38fd1498Szrj /* Verify that vec::quick_push works correctly.  */
283*38fd1498Szrj 
284*38fd1498Szrj static void
test_quick_push()285*38fd1498Szrj test_quick_push ()
286*38fd1498Szrj {
287*38fd1498Szrj   auto_vec <int> v;
288*38fd1498Szrj   ASSERT_EQ (0, v.length ());
289*38fd1498Szrj   v.reserve (3);
290*38fd1498Szrj   ASSERT_EQ (0, v.length ());
291*38fd1498Szrj   ASSERT_TRUE (v.space (3));
292*38fd1498Szrj   v.quick_push (5);
293*38fd1498Szrj   v.quick_push (6);
294*38fd1498Szrj   v.quick_push (7);
295*38fd1498Szrj   ASSERT_EQ (3, v.length ());
296*38fd1498Szrj   ASSERT_EQ (5, v[0]);
297*38fd1498Szrj   ASSERT_EQ (6, v[1]);
298*38fd1498Szrj   ASSERT_EQ (7, v[2]);
299*38fd1498Szrj }
300*38fd1498Szrj 
301*38fd1498Szrj /* Verify that vec::safe_push works correctly.  */
302*38fd1498Szrj 
303*38fd1498Szrj static void
test_safe_push()304*38fd1498Szrj test_safe_push ()
305*38fd1498Szrj {
306*38fd1498Szrj   auto_vec <int> v;
307*38fd1498Szrj   ASSERT_EQ (0, v.length ());
308*38fd1498Szrj   v.safe_push (5);
309*38fd1498Szrj   v.safe_push (6);
310*38fd1498Szrj   v.safe_push (7);
311*38fd1498Szrj   ASSERT_EQ (3, v.length ());
312*38fd1498Szrj   ASSERT_EQ (5, v[0]);
313*38fd1498Szrj   ASSERT_EQ (6, v[1]);
314*38fd1498Szrj   ASSERT_EQ (7, v[2]);
315*38fd1498Szrj }
316*38fd1498Szrj 
317*38fd1498Szrj /* Verify that vec::truncate works correctly.  */
318*38fd1498Szrj 
319*38fd1498Szrj static void
test_truncate()320*38fd1498Szrj test_truncate ()
321*38fd1498Szrj {
322*38fd1498Szrj   auto_vec <int> v;
323*38fd1498Szrj   ASSERT_EQ (0, v.length ());
324*38fd1498Szrj   safe_push_range (v, 0, 10);
325*38fd1498Szrj   ASSERT_EQ (10, v.length ());
326*38fd1498Szrj 
327*38fd1498Szrj   v.truncate (5);
328*38fd1498Szrj   ASSERT_EQ (5, v.length ());
329*38fd1498Szrj }
330*38fd1498Szrj 
331*38fd1498Szrj /* Verify that vec::safe_grow_cleared works correctly.  */
332*38fd1498Szrj 
333*38fd1498Szrj static void
test_safe_grow_cleared()334*38fd1498Szrj test_safe_grow_cleared ()
335*38fd1498Szrj {
336*38fd1498Szrj   auto_vec <int> v;
337*38fd1498Szrj   ASSERT_EQ (0, v.length ());
338*38fd1498Szrj   v.safe_grow_cleared (50);
339*38fd1498Szrj   ASSERT_EQ (50, v.length ());
340*38fd1498Szrj   ASSERT_EQ (0, v[0]);
341*38fd1498Szrj   ASSERT_EQ (0, v[49]);
342*38fd1498Szrj }
343*38fd1498Szrj 
344*38fd1498Szrj /* Verify that vec::pop works correctly.  */
345*38fd1498Szrj 
346*38fd1498Szrj static void
test_pop()347*38fd1498Szrj test_pop ()
348*38fd1498Szrj {
349*38fd1498Szrj   auto_vec <int> v;
350*38fd1498Szrj   safe_push_range (v, 5, 20);
351*38fd1498Szrj   ASSERT_EQ (15, v.length ());
352*38fd1498Szrj 
353*38fd1498Szrj   int last = v.pop ();
354*38fd1498Szrj   ASSERT_EQ (19, last);
355*38fd1498Szrj   ASSERT_EQ (14, v.length ());
356*38fd1498Szrj }
357*38fd1498Szrj 
358*38fd1498Szrj /* Verify that vec::safe_insert works correctly.  */
359*38fd1498Szrj 
360*38fd1498Szrj static void
test_safe_insert()361*38fd1498Szrj test_safe_insert ()
362*38fd1498Szrj {
363*38fd1498Szrj   auto_vec <int> v;
364*38fd1498Szrj   safe_push_range (v, 0, 10);
365*38fd1498Szrj   v.safe_insert (5, 42);
366*38fd1498Szrj   ASSERT_EQ (4, v[4]);
367*38fd1498Szrj   ASSERT_EQ (42, v[5]);
368*38fd1498Szrj   ASSERT_EQ (5, v[6]);
369*38fd1498Szrj   ASSERT_EQ (11, v.length ());
370*38fd1498Szrj }
371*38fd1498Szrj 
372*38fd1498Szrj /* Verify that vec::ordered_remove works correctly.  */
373*38fd1498Szrj 
374*38fd1498Szrj static void
test_ordered_remove()375*38fd1498Szrj test_ordered_remove ()
376*38fd1498Szrj {
377*38fd1498Szrj   auto_vec <int> v;
378*38fd1498Szrj   safe_push_range (v, 0, 10);
379*38fd1498Szrj   v.ordered_remove (5);
380*38fd1498Szrj   ASSERT_EQ (4, v[4]);
381*38fd1498Szrj   ASSERT_EQ (6, v[5]);
382*38fd1498Szrj   ASSERT_EQ (9, v.length ());
383*38fd1498Szrj }
384*38fd1498Szrj 
385*38fd1498Szrj /* Verify that vec::unordered_remove works correctly.  */
386*38fd1498Szrj 
387*38fd1498Szrj static void
test_unordered_remove()388*38fd1498Szrj test_unordered_remove ()
389*38fd1498Szrj {
390*38fd1498Szrj   auto_vec <int> v;
391*38fd1498Szrj   safe_push_range (v, 0, 10);
392*38fd1498Szrj   v.unordered_remove (5);
393*38fd1498Szrj   ASSERT_EQ (9, v.length ());
394*38fd1498Szrj }
395*38fd1498Szrj 
396*38fd1498Szrj /* Verify that vec::block_remove works correctly.  */
397*38fd1498Szrj 
398*38fd1498Szrj static void
test_block_remove()399*38fd1498Szrj test_block_remove ()
400*38fd1498Szrj {
401*38fd1498Szrj   auto_vec <int> v;
402*38fd1498Szrj   safe_push_range (v, 0, 10);
403*38fd1498Szrj   v.block_remove (5, 3);
404*38fd1498Szrj   ASSERT_EQ (3, v[3]);
405*38fd1498Szrj   ASSERT_EQ (4, v[4]);
406*38fd1498Szrj   ASSERT_EQ (8, v[5]);
407*38fd1498Szrj   ASSERT_EQ (9, v[6]);
408*38fd1498Szrj   ASSERT_EQ (7, v.length ());
409*38fd1498Szrj }
410*38fd1498Szrj 
411*38fd1498Szrj /* Comparator for use by test_qsort.  */
412*38fd1498Szrj 
413*38fd1498Szrj static int
reverse_cmp(const void * p_i,const void * p_j)414*38fd1498Szrj reverse_cmp (const void *p_i, const void *p_j)
415*38fd1498Szrj {
416*38fd1498Szrj   return *(const int *)p_j - *(const int *)p_i;
417*38fd1498Szrj }
418*38fd1498Szrj 
419*38fd1498Szrj /* Verify that vec::qsort works correctly.  */
420*38fd1498Szrj 
421*38fd1498Szrj static void
test_qsort()422*38fd1498Szrj test_qsort ()
423*38fd1498Szrj {
424*38fd1498Szrj   auto_vec <int> v;
425*38fd1498Szrj   safe_push_range (v, 0, 10);
426*38fd1498Szrj   v.qsort (reverse_cmp);
427*38fd1498Szrj   ASSERT_EQ (9, v[0]);
428*38fd1498Szrj   ASSERT_EQ (8, v[1]);
429*38fd1498Szrj   ASSERT_EQ (1, v[8]);
430*38fd1498Szrj   ASSERT_EQ (0, v[9]);
431*38fd1498Szrj   ASSERT_EQ (10, v.length ());
432*38fd1498Szrj }
433*38fd1498Szrj 
434*38fd1498Szrj /* Run all of the selftests within this file.  */
435*38fd1498Szrj 
436*38fd1498Szrj void
vec_c_tests()437*38fd1498Szrj vec_c_tests ()
438*38fd1498Szrj {
439*38fd1498Szrj   test_quick_push ();
440*38fd1498Szrj   test_safe_push ();
441*38fd1498Szrj   test_truncate ();
442*38fd1498Szrj   test_safe_grow_cleared ();
443*38fd1498Szrj   test_pop ();
444*38fd1498Szrj   test_safe_insert ();
445*38fd1498Szrj   test_ordered_remove ();
446*38fd1498Szrj   test_unordered_remove ();
447*38fd1498Szrj   test_block_remove ();
448*38fd1498Szrj   test_qsort ();
449*38fd1498Szrj }
450*38fd1498Szrj 
451*38fd1498Szrj } // namespace selftest
452*38fd1498Szrj 
453*38fd1498Szrj #endif /* #if CHECKING_P */
454*38fd1498Szrj #endif /* #ifndef GENERATOR_FILE */
455