LCOV - code coverage report
Current view: top level - gcc - vec.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.2 % 453 386
Test Date: 2026-08-22 16:33:35 Functions: 78.9 % 38 30
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Vector API for GNU compiler.
       2              :    Copyright (C) 2004-2026 Free Software Foundation, Inc.
       3              :    Contributed by Nathan Sidwell <nathan@codesourcery.com>
       4              :    Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : /* This file is compiled twice: once for the generator programs
      23              :    once for the compiler.  */
      24              : #ifdef GENERATOR_FILE
      25              : #include "bconfig.h"
      26              : #else
      27              : #include "config.h"
      28              : #endif
      29              : 
      30              : #include "system.h"
      31              : #include "coretypes.h"
      32              : #include "hash-table.h"
      33              : #include "selftest.h"
      34              : #ifdef GENERATOR_FILE
      35              : #include "errors.h"
      36              : #else
      37              : #include "input.h"
      38              : #include "diagnostic-core.h"
      39              : #endif
      40              : 
      41              : /* Vector memory usage.  */
      42              : class vec_usage: public mem_usage
      43              : {
      44              : public:
      45              :   /* Default constructor.  */
      46            0 :   vec_usage (): m_items (0), m_items_peak (0), m_element_size (0) {}
      47              : 
      48              :   /* Constructor.  */
      49            0 :   vec_usage (size_t allocated, size_t times, size_t peak,
      50              :              size_t items, size_t items_peak, size_t element_size)
      51              :     : mem_usage (allocated, times, peak),
      52            0 :     m_items (items), m_items_peak (items_peak),
      53            0 :     m_element_size (element_size) {}
      54              : 
      55              :   /* Sum the usage with SECOND usage.  */
      56              :   vec_usage
      57            0 :   operator+ (const vec_usage &second)
      58              :   {
      59            0 :     return vec_usage (m_allocated + second.m_allocated,
      60            0 :                       m_times + second.m_times,
      61            0 :                       m_peak + second.m_peak,
      62            0 :                       m_items + second.m_items,
      63            0 :                       m_items_peak + second.m_items_peak, 0);
      64              :   }
      65              : 
      66              :   /* Dump usage coupled to LOC location, where TOTAL is sum of all rows.  */
      67              :   inline void
      68            0 :   dump (mem_location *loc, mem_usage &total) const
      69              :   {
      70            0 :     char s[4096];
      71            0 :     sprintf (s, "%s:%i (%s)", loc->get_trimmed_filename (),
      72              :              loc->m_line, loc->m_function);
      73              : 
      74            0 :     s[48] = '\0';
      75              : 
      76            0 :     fprintf (stderr,
      77              :              "%-48s %10" PRIu64 PRsa (10) ":%4.1f%%" PRsa (9) "%10" PRIu64
      78              :              ":%4.1f%%" PRsa (10) PRsa (10) "\n",
      79              :              s,
      80            0 :              (uint64_t)m_element_size,
      81            0 :              SIZE_AMOUNT (m_allocated),
      82            0 :              m_allocated * 100.0 / total.m_allocated,
      83            0 :              SIZE_AMOUNT (m_peak), (uint64_t)m_times,
      84            0 :              m_times * 100.0 / total.m_times,
      85            0 :              SIZE_AMOUNT (m_items), SIZE_AMOUNT (m_items_peak));
      86            0 :   }
      87              : 
      88              :   /* Dump footer.  */
      89              :   inline void
      90            0 :   dump_footer ()
      91              :   {
      92            0 :     fprintf (stderr, "%s" PRsa (64) PRsa (25) PRsa (16) "\n",
      93            0 :              "Total", SIZE_AMOUNT (m_allocated),
      94            0 :              SIZE_AMOUNT (m_times), SIZE_AMOUNT (m_items));
      95            0 :   }
      96              : 
      97              :   /* Dump header with NAME.  */
      98              :   static inline void
      99            0 :   dump_header (const char *name)
     100              :   {
     101            0 :     fprintf (stderr, "%-48s %10s%11s%16s%10s%17s%11s\n", name, "sizeof(T)",
     102              :              "Leak", "Peak", "Times", "Leak items", "Peak items");
     103            0 :   }
     104              : 
     105              :   /* Current number of items allocated.  */
     106              :   size_t m_items;
     107              :   /* Peak value of number of allocated items.  */
     108              :   size_t m_items_peak;
     109              :   /* Size of element of the vector.  */
     110              :   size_t m_element_size;
     111              : };
     112              : 
     113              : /* Vector memory description.  */
     114              : inline auto &
     115            0 : vec_mem_desc ()
     116              : {
     117            0 :   return mem_alloc_description<vec_usage>::instance<VEC_ORIGIN> ();
     118              : }
     119              : 
     120              : /* Account the overhead.  */
     121              : 
     122              : void
     123            0 : vec_prefix::register_overhead (void *ptr, size_t elements,
     124              :                                size_t element_size MEM_STAT_DECL)
     125              : {
     126            0 :   vec_mem_desc ().register_descriptor (ptr, VEC_ORIGIN, false
     127              :                                        FINAL_PASS_MEM_STAT);
     128            0 :   vec_usage *usage
     129            0 :     = vec_mem_desc ().register_instance_overhead (elements * element_size, ptr);
     130            0 :   usage->m_element_size = element_size;
     131            0 :   usage->m_items += elements;
     132            0 :   if (usage->m_items_peak < usage->m_items)
     133            0 :     usage->m_items_peak = usage->m_items;
     134            0 : }
     135              : 
     136              : /* Notice that the memory allocated for the vector has been freed.  */
     137              : 
     138              : void
     139            0 : vec_prefix::release_overhead (void *ptr, size_t size, size_t elements,
     140              :                               bool in_dtor MEM_STAT_DECL)
     141              : {
     142            0 :   if (!vec_mem_desc ().contains_descriptor_for_instance (ptr))
     143            0 :     vec_mem_desc ().register_descriptor (ptr, VEC_ORIGIN,
     144              :                                       false FINAL_PASS_MEM_STAT);
     145            0 :   vec_usage *usage = vec_mem_desc ().release_instance_overhead (ptr, size,
     146              :                                                                 in_dtor);
     147            0 :   usage->m_items -= elements;
     148            0 : }
     149              : 
     150              : /* Calculate the number of slots to reserve a vector, making sure that
     151              :    it is of at least DESIRED size by growing ALLOC exponentially.  */
     152              : 
     153              : unsigned
     154   1042562611 : vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired)
     155              : {
     156              :   /* We must have run out of room.  */
     157   1042562611 :   gcc_assert (alloc < desired);
     158              : 
     159              :   /* Exponential growth. */
     160   1042562611 :   if (!alloc)
     161              :     alloc = 4;
     162   1042562611 :   else if (alloc < 16)
     163              :     /* Double when small.  */
     164    883986575 :     alloc = alloc * 2;
     165              :   else
     166              :     /* Grow slower when large.  */
     167    158576036 :     alloc = (alloc * 3 / 2);
     168              : 
     169              :   /* If this is still too small, set it to the right size. */
     170   1042562611 :   if (alloc < desired)
     171              :     alloc = desired;
     172   1042562611 :   return alloc;
     173              : }
     174              : 
     175              : /* Dump per-site memory statistics.  */
     176              : 
     177              : void
     178            0 : dump_vec_loc_statistics (void)
     179              : {
     180            0 :   vec_mem_desc ().dump (VEC_ORIGIN);
     181            0 : }
     182              : 
     183              : /* Gets the next token from STR delimited by DELIMS (deliminator not included
     184              :    in returned string).
     185              : 
     186              :    Updates STR to be the remaining string after the given token.
     187              : 
     188              :    STR and DELIMS must both be valid string_slices.
     189              : 
     190              :    If there aren't any of the chars in DELIM in STR (ie no more tokens in STR)
     191              :    then returns the string, and updates STR to be invalid.  */
     192              : string_slice
     193          648 : string_slice::tokenize (string_slice *str, string_slice delims)
     194              : {
     195          648 :   const char *ptr = str->begin ();
     196              : 
     197          648 :   gcc_assert (str->is_valid () && delims.is_valid ());
     198              : 
     199         5176 :   for (; ptr < str->end (); ptr++)
     200         9400 :     for (char c : delims)
     201         4872 :       if (*ptr == c)
     202              :         {
     203              :           /* Update the input string to be the remaining string.  */
     204           76 :           const char *str_begin = str->begin ();
     205           76 :           *str = string_slice (ptr  + 1, str->end ());
     206           76 :           return string_slice (str_begin, ptr);
     207              :         }
     208              : 
     209              :   /* If no deliminators between the start and end, return the whole string.  */
     210          572 :   string_slice res = *str;
     211          572 :   *str = string_slice::invalid ();
     212          572 :   return res;
     213              : }
     214              : 
     215              : /* Compares the string_slices STR1 and STR2 giving a lexograpical ordering.
     216              :    Returns -1 if STR1 comes before STR2, 1 if STR1 comes after, and 0 if the
     217              :    string_slices have the same contents.  */
     218              : 
     219              : int
     220           32 : string_slice::strcmp (string_slice str1, string_slice str2)
     221              : {
     222           56 :   for (unsigned int i = 0; i < str1.size () && i < str2.size (); i++)
     223              :     {
     224           32 :       if (str1[i] < str2[i])
     225              :         return -1;
     226           28 :       if (str1[i] > str2[i])
     227              :         return 1;
     228              :     }
     229              : 
     230           24 :   if (str1.size () < str2.size ())
     231              :     return -1;
     232           20 :   if (str1.size () > str2.size ())
     233            8 :     return 1;
     234              :   return 0;
     235              : }
     236              : 
     237              : string_slice
     238          604 : string_slice::strip ()
     239              : {
     240          604 :   const char *start = this->begin ();
     241          604 :   const char *end = this->end ();
     242              : 
     243         1272 :   while (start < end && ISSPACE (*start))
     244           64 :     start++;
     245          640 :   while (end > start && ISSPACE (*(end-1)))
     246           36 :     end--;
     247              : 
     248          604 :   return string_slice (start, end);
     249              : }
     250              : 
     251              : #if CHECKING_P
     252              : /* Report qsort comparator CMP consistency check failure with P1, P2, P3 as
     253              :    witness elements.  */
     254              : ATTRIBUTE_NORETURN ATTRIBUTE_COLD
     255              : static void
     256            0 : qsort_chk_error (const void *p1, const void *p2, const void *p3,
     257              :                  sort_r_cmp_fn *cmp, void *data)
     258              : {
     259            0 :   if (!p3)
     260              :     {
     261            0 :       int r1 = cmp (p1, p2, data), r2 = cmp (p2, p1, data);
     262            0 :       error ("qsort comparator not anti-symmetric: %d, %d", r1, r2);
     263              :     }
     264            0 :   else if (p1 == p2)
     265              :     {
     266            0 :       int r = cmp (p1, p3, data);
     267            0 :       error ("qsort comparator non-negative on sorted output: %d", r);
     268              :     }
     269              :   else
     270              :     {
     271            0 :       int r1 = cmp (p1, p2, data);
     272            0 :       int r2 = cmp (p2, p3, data);
     273            0 :       int r3 = cmp (p1, p3, data);
     274            0 :       error ("qsort comparator not transitive: %d, %d, %d", r1, r2, r3);
     275              :     }
     276            0 :   internal_error ("qsort checking failed");
     277              : }
     278              : 
     279              : /* Verify anti-symmetry and transitivity for comparator CMP on sorted array
     280              :    of N SIZE-sized elements pointed to by BASE.  */
     281              : void
     282    182255001 : qsort_chk (void *base, size_t n, size_t size, sort_r_cmp_fn *cmp, void *data)
     283              : {
     284              : #if 0
     285              : #define LIM(n) (n)
     286              : #else
     287              :   /* Limit overall time complexity to O(n log n).  */
     288              : #define LIM(n) ((n) <= 16 ? (n) : 12 + floor_log2 (n))
     289              : #endif
     290              : #define ELT(i) ((const char *) base + (i) * size)
     291              : #define CMP(i, j) cmp (ELT (i), ELT (j), data)
     292              : #define ERR2(i, j) qsort_chk_error (ELT (i), ELT (j), NULL, cmp, data)
     293              : #define ERR3(i, j, k) qsort_chk_error (ELT (i), ELT (j), ELT (k), cmp, data)
     294    182255001 :   size_t i1, i2, i, j;
     295              :   /* This outer loop iterates over maximum spans [i1, i2) such that
     296              :      elements within each span compare equal to each other.  */
     297   1393034620 :   for (i1 = 0; i1 < n; i1 = i2)
     298              :     {
     299              :       /* Position i2 one past last element that compares equal to i1'th.  */
     300   1309669551 :       for (i2 = i1 + 1; i2 < n; i2++)
     301   1127414550 :         if (CMP (i1, i2))
     302              :           break;
     303     98889932 :         else if (CMP (i2, i1))
     304            0 :           ERR2 (i1, i2);
     305   1210779619 :       size_t lim1 = LIM (i2 - i1), lim2 = LIM (n - i2);
     306              :       /* Verify that other pairs within current span compare equal.  */
     307   1299159242 :       for (i = i1 + 1; i + 1 < i2; i++)
     308    190632668 :         for (j = i + 1; j < i1 + lim1; j++)
     309    102253045 :           if (CMP (i, j))
     310            0 :             ERR3 (i, i1, j);
     311    102253045 :           else if (CMP (j, i))
     312            0 :             ERR2 (i, j);
     313              :       /* Verify that elements within this span compare less than
     314              :          elements beyond the span.  */
     315   2520449170 :       for (i = i1; i < i2; i++)
     316  13585435010 :         for (j = i2; j < i2 + lim2; j++)
     317  12275765459 :           if (CMP (i, j) >= 0)
     318            0 :             ERR3 (i, i1, j);
     319  12275765459 :           else if (CMP (j, i) <= 0)
     320            0 :             ERR2 (i, j);
     321              :     }
     322              : #undef ERR3
     323              : #undef ERR2
     324              : #undef CMP
     325              : #undef ELT
     326              : #undef LIM
     327    182255001 : }
     328              : #endif /* #if CHECKING_P */
     329              : 
     330              : #ifndef GENERATOR_FILE
     331              : #if CHECKING_P
     332              : 
     333              : namespace selftest {
     334              : 
     335              : /* Selftests.  */
     336              : 
     337              : /* Call V.safe_push for all ints from START up to, but not including LIMIT.
     338              :    Helper function for selftests.  */
     339              : 
     340              : static void
     341           52 : safe_push_range (vec <int>&v, int start, int limit)
     342              : {
     343          540 :   for (int i = start; i < limit; i++)
     344          488 :     v.safe_push (i);
     345           52 : }
     346              : 
     347              : /* Verify forms of initialization.  */
     348              : 
     349              : static void
     350            4 : test_init ()
     351              : {
     352            4 :   {
     353            4 :     vec<int> v1{ };
     354            4 :     ASSERT_EQ (0, v1.length ());
     355              : 
     356            4 :     vec<int> v2 (v1);
     357            4 :     ASSERT_EQ (0, v2.length ());
     358              :   }
     359              : 
     360            4 :   {
     361            4 :     vec<int> v1 = vec<int>();
     362            4 :     ASSERT_EQ (0, v1.length ());
     363              : 
     364            4 :     vec<int> v2 = v1;
     365            4 :     ASSERT_EQ (0, v2.length ());
     366              :   }
     367              : 
     368            4 :   {
     369            4 :     vec<int> v1 (vNULL);
     370            4 :     ASSERT_EQ (0, v1.length ());
     371            4 :     v1.safe_push (1);
     372              : 
     373            4 :     vec<int> v2 (v1);
     374            4 :     ASSERT_EQ (1, v1.length ());
     375            4 :     v2.safe_push (1);
     376              : 
     377            4 :     ASSERT_EQ (2, v1.length ());
     378            4 :     ASSERT_EQ (2, v2.length ());
     379            4 :     v1.release ();
     380              :   }
     381            4 : }
     382              : 
     383              : /* Verify that vec::quick_push works correctly.  */
     384              : 
     385              : static void
     386            4 : test_quick_push ()
     387              : {
     388            4 :   auto_vec <int> v;
     389            4 :   ASSERT_EQ (0, v.length ());
     390            4 :   v.reserve (3);
     391            4 :   ASSERT_EQ (0, v.length ());
     392            4 :   ASSERT_TRUE (v.space (3));
     393            4 :   v.quick_push (5);
     394            4 :   v.quick_push (6);
     395            4 :   v.quick_push (7);
     396            4 :   ASSERT_EQ (3, v.length ());
     397            4 :   ASSERT_EQ (5, v[0]);
     398            4 :   ASSERT_EQ (6, v[1]);
     399            4 :   ASSERT_EQ (7, v[2]);
     400            4 : }
     401              : 
     402              : /* Verify that vec::safe_push works correctly.  */
     403              : 
     404              : static void
     405            4 : test_safe_push ()
     406              : {
     407            4 :   auto_vec <int> v;
     408            4 :   ASSERT_EQ (0, v.length ());
     409            4 :   v.safe_push (5);
     410            4 :   v.safe_push (6);
     411            4 :   v.safe_push (7);
     412            4 :   ASSERT_EQ (3, v.length ());
     413            4 :   ASSERT_EQ (5, v[0]);
     414            4 :   ASSERT_EQ (6, v[1]);
     415            4 :   ASSERT_EQ (7, v[2]);
     416            4 : }
     417              : 
     418              : /* Verify that vec::truncate works correctly.  */
     419              : 
     420              : static void
     421            4 : test_truncate ()
     422              : {
     423            4 :   auto_vec <int> v;
     424            4 :   ASSERT_EQ (0, v.length ());
     425            4 :   safe_push_range (v, 0, 10);
     426            4 :   ASSERT_EQ (10, v.length ());
     427              : 
     428            4 :   v.truncate (5);
     429            4 :   ASSERT_EQ (5, v.length ());
     430            4 : }
     431              : 
     432              : /* Verify that vec::safe_grow_cleared works correctly.  */
     433              : 
     434              : static void
     435            4 : test_safe_grow_cleared ()
     436              : {
     437            4 :   auto_vec <int> v;
     438            4 :   ASSERT_EQ (0, v.length ());
     439            4 :   v.safe_grow_cleared (50, true);
     440            4 :   ASSERT_EQ (50, v.length ());
     441            4 :   ASSERT_EQ (0, v[0]);
     442            4 :   ASSERT_EQ (0, v[49]);
     443            4 : }
     444              : 
     445              : /* Verify that vec::pop works correctly.  */
     446              : 
     447              : static void
     448            4 : test_pop ()
     449              : {
     450            4 :   auto_vec <int> v;
     451            4 :   safe_push_range (v, 5, 20);
     452            4 :   ASSERT_EQ (15, v.length ());
     453              : 
     454            4 :   int last = v.pop ();
     455            4 :   ASSERT_EQ (19, last);
     456            4 :   ASSERT_EQ (14, v.length ());
     457            4 : }
     458              : 
     459              : /* Verify that vec::safe_insert works correctly.  */
     460              : 
     461              : static void
     462            4 : test_safe_insert ()
     463              : {
     464            4 :   auto_vec <int> v;
     465            4 :   safe_push_range (v, 0, 10);
     466            4 :   v.safe_insert (5, 42);
     467            4 :   ASSERT_EQ (4, v[4]);
     468            4 :   ASSERT_EQ (42, v[5]);
     469            4 :   ASSERT_EQ (5, v[6]);
     470            4 :   ASSERT_EQ (11, v.length ());
     471            4 : }
     472              : 
     473              : /* Verify that vec::ordered_remove works correctly.  */
     474              : 
     475              : static void
     476            4 : test_ordered_remove ()
     477              : {
     478            4 :   auto_vec <int> v;
     479            4 :   safe_push_range (v, 0, 10);
     480            4 :   v.ordered_remove (5);
     481            4 :   ASSERT_EQ (4, v[4]);
     482            4 :   ASSERT_EQ (6, v[5]);
     483            4 :   ASSERT_EQ (9, v.length ());
     484            4 : }
     485              : 
     486              : /* Verify that vec::ordered_remove_if works correctly.  */
     487              : 
     488              : static void
     489            4 : test_ordered_remove_if (void)
     490              : {
     491            4 :   auto_vec <int> v;
     492            4 :   safe_push_range (v, 0, 10);
     493            4 :   unsigned ix, ix2;
     494            4 :   int *elem_ptr;
     495           44 :   VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr,
     496            4 :                          *elem_ptr == 5 || *elem_ptr == 7);
     497            4 :   ASSERT_EQ (4, v[4]);
     498            4 :   ASSERT_EQ (6, v[5]);
     499            4 :   ASSERT_EQ (8, v[6]);
     500            4 :   ASSERT_EQ (8, v.length ());
     501              : 
     502            4 :   v.truncate (0);
     503            4 :   safe_push_range (v, 0, 10);
     504           28 :   VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 6,
     505            4 :                                  *elem_ptr == 5 || *elem_ptr == 7);
     506            4 :   ASSERT_EQ (4, v[4]);
     507            4 :   ASSERT_EQ (6, v[5]);
     508            4 :   ASSERT_EQ (7, v[6]);
     509            4 :   ASSERT_EQ (9, v.length ());
     510              : 
     511            4 :   v.truncate (0);
     512            4 :   safe_push_range (v, 0, 10);
     513           24 :   VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 5,
     514            4 :                                  *elem_ptr == 5 || *elem_ptr == 7);
     515           12 :   VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 8, 10,
     516            4 :                                  *elem_ptr == 5 || *elem_ptr == 7);
     517            4 :   ASSERT_EQ (4, v[4]);
     518            4 :   ASSERT_EQ (5, v[5]);
     519            4 :   ASSERT_EQ (6, v[6]);
     520            4 :   ASSERT_EQ (10, v.length ());
     521              : 
     522            4 :   v.truncate (0);
     523            4 :   safe_push_range (v, 0, 10);
     524           44 :   VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr, *elem_ptr == 5);
     525            4 :   ASSERT_EQ (4, v[4]);
     526            4 :   ASSERT_EQ (6, v[5]);
     527            4 :   ASSERT_EQ (7, v[6]);
     528            4 :   ASSERT_EQ (9, v.length ());
     529            4 : }
     530              : 
     531              : /* Verify that vec::unordered_remove works correctly.  */
     532              : 
     533              : static void
     534            4 : test_unordered_remove ()
     535              : {
     536            4 :   auto_vec <int> v;
     537            4 :   safe_push_range (v, 0, 10);
     538            4 :   v.unordered_remove (5);
     539            4 :   ASSERT_EQ (9, v.length ());
     540            4 : }
     541              : 
     542              : /* Verify that vec::block_remove works correctly.  */
     543              : 
     544              : static void
     545            4 : test_block_remove ()
     546              : {
     547            4 :   auto_vec <int> v;
     548            4 :   safe_push_range (v, 0, 10);
     549            4 :   v.block_remove (5, 3);
     550            4 :   ASSERT_EQ (3, v[3]);
     551            4 :   ASSERT_EQ (4, v[4]);
     552            4 :   ASSERT_EQ (8, v[5]);
     553            4 :   ASSERT_EQ (9, v[6]);
     554            4 :   ASSERT_EQ (7, v.length ());
     555            4 : }
     556              : 
     557              : /* Comparator for use by test_qsort.  */
     558              : 
     559              : static int
     560          492 : reverse_cmp (const void *p_i, const void *p_j)
     561              : {
     562          492 :   return *(const int *)p_j - *(const int *)p_i;
     563              : }
     564              : 
     565              : /* Verify that vec::qsort works correctly.  */
     566              : 
     567              : static void
     568            4 : test_qsort ()
     569              : {
     570            4 :   auto_vec <int> v;
     571            4 :   safe_push_range (v, 0, 10);
     572            4 :   v.qsort (reverse_cmp);
     573            4 :   ASSERT_EQ (9, v[0]);
     574            4 :   ASSERT_EQ (8, v[1]);
     575            4 :   ASSERT_EQ (1, v[8]);
     576            4 :   ASSERT_EQ (0, v[9]);
     577            4 :   ASSERT_EQ (10, v.length ());
     578            4 : }
     579              : 
     580              : /* Verify that vec::reverse works correctly.  */
     581              : 
     582              : static void
     583            4 : test_reverse ()
     584              : {
     585              :   /* Reversing an empty vec ought to be a no-op.  */
     586            4 :   {
     587            4 :     auto_vec <int> v;
     588            4 :     ASSERT_EQ (0, v.length ());
     589            4 :     v.reverse ();
     590            4 :     ASSERT_EQ (0, v.length ());
     591            4 :   }
     592              : 
     593              :   /* Verify reversing a vec with even length.  */
     594            4 :   {
     595            4 :     auto_vec <int> v;
     596            4 :     safe_push_range (v, 0, 4);
     597            4 :     v.reverse ();
     598            4 :     ASSERT_EQ (3, v[0]);
     599            4 :     ASSERT_EQ (2, v[1]);
     600            4 :     ASSERT_EQ (1, v[2]);
     601            4 :     ASSERT_EQ (0, v[3]);
     602            4 :     ASSERT_EQ (4, v.length ());
     603            4 :   }
     604              : 
     605              :   /* Verify reversing a vec with odd length.  */
     606            4 :   {
     607            4 :     auto_vec <int> v;
     608            4 :     safe_push_range (v, 0, 3);
     609            4 :     v.reverse ();
     610            4 :     ASSERT_EQ (2, v[0]);
     611            4 :     ASSERT_EQ (1, v[1]);
     612            4 :     ASSERT_EQ (0, v[2]);
     613            4 :     ASSERT_EQ (3, v.length ());
     614            4 :   }
     615            4 : }
     616              : 
     617              : /* A test class that increments a counter every time its dtor is called.  */
     618              : 
     619              : class count_dtor
     620              : {
     621              :  public:
     622            8 :   count_dtor (int *counter) : m_counter (counter) {}
     623            8 :   ~count_dtor () { (*m_counter)++; }
     624              : 
     625              :  private:
     626              :   int *m_counter;
     627              : };
     628              : 
     629              : /* Verify that auto_delete_vec deletes the elements within it.  */
     630              : 
     631              : static void
     632            4 : test_auto_delete_vec ()
     633              : {
     634            4 :   int dtor_count = 0;
     635            4 :   {
     636            4 :     auto_delete_vec <count_dtor> v;
     637            4 :     v.safe_push (new count_dtor (&dtor_count));
     638            4 :     v.safe_push (new count_dtor (&dtor_count));
     639            4 :   }
     640            4 :   ASSERT_EQ (dtor_count, 2);
     641            4 : }
     642              : 
     643              : /* Verify accesses to vector elements are done indirectly.  */
     644              : 
     645              : static void
     646            4 : test_auto_alias ()
     647              : {
     648            4 :   volatile int i = 1;
     649            4 :   auto_vec<int, 8> v;
     650            4 :   v.quick_grow (2);
     651            4 :   v[0] = 1;
     652            4 :   v[1] = 2;
     653            4 :   int val;
     654            8 :   for (int ix = i; v.iterate (ix, &val); ix++)
     655            4 :     ASSERT_EQ (val, 2);
     656            4 :   ASSERT_EQ (val, 0);
     657            4 : }
     658              : 
     659              : static void
     660            4 : test_string_slice_initializers ()
     661              : {
     662            4 :   string_slice str1 = string_slice ();
     663            4 :   ASSERT_TRUE (str1.is_valid ());
     664            4 :   ASSERT_EQ (str1.size (), 0);
     665              : 
     666            4 :   string_slice str2 = string_slice ("Test string");
     667            4 :   ASSERT_TRUE (str2.is_valid ());
     668            4 :   ASSERT_EQ (str2.size (), 11);
     669              : 
     670            4 :   string_slice str3 = "Test string the second";
     671            4 :   ASSERT_TRUE (str3.is_valid ());
     672            4 :   ASSERT_EQ (str3.size (), 22);
     673              : 
     674            4 :   string_slice str4 = string_slice ("Test string", 4);
     675            4 :   ASSERT_TRUE (str4.is_valid ());
     676            4 :   ASSERT_EQ (str4.size (), 4);
     677            4 : }
     678              : 
     679              : static void
     680            4 : test_string_slice_tokenize ()
     681              : {
     682            4 :   string_slice test_string_slice = "";
     683            4 :   string_slice test_delims = ",";
     684              : 
     685            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "");
     686            8 :   ASSERT_FALSE (test_string_slice.is_valid ());
     687              : 
     688            4 :   test_string_slice = ",";
     689            4 :   test_delims = ",";
     690            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     691              :              string_slice (""));
     692            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     693              :              string_slice (""));
     694            8 :   ASSERT_FALSE (test_string_slice.is_valid ());
     695              : 
     696            4 :   test_string_slice = ",test.,.test, ,  test  ";
     697            4 :   test_delims = ",.";
     698            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "");
     699            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "test");
     700            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "");
     701            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "");
     702            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), "test");
     703            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims), " ");
     704            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     705              :              "  test  ");
     706            8 :   ASSERT_FALSE (test_string_slice.is_valid ());
     707              : 
     708            4 :   const char *test_string
     709              :     = "This is the test string, it \0 is for testing, 123 ,,";
     710            4 :   test_string_slice = string_slice (test_string, 52);
     711            4 :   test_delims = string_slice (",\0", 2);
     712              : 
     713            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     714              :              "This is the test string");
     715            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     716              :              " it ");
     717            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     718              :              " is for testing");
     719            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     720              :              " 123 ");
     721            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     722              :              "");
     723            4 :   ASSERT_EQ (string_slice::tokenize (&test_string_slice, test_delims),
     724              :              "");
     725            8 :   ASSERT_FALSE (test_string_slice.is_valid ());
     726            4 : }
     727              : 
     728              : static void
     729            4 : test_string_slice_strcmp ()
     730              : {
     731            4 :   ASSERT_EQ (string_slice::strcmp (string_slice (),
     732              :                                    string_slice ()), 0);
     733            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("test"),
     734              :                                    string_slice ()), 1);
     735            4 :   ASSERT_EQ (string_slice::strcmp (string_slice (),
     736              :                                    string_slice ("test")), -1);
     737            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("test"),
     738              :                                    string_slice ("test")), 0);
     739            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("a"),
     740              :                                    string_slice ("b")), -1);
     741            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("b"),
     742              :                                    string_slice ("a")), 1);
     743            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("ab", 1),
     744              :                                    string_slice ("a")), 0);
     745            4 :   ASSERT_EQ (string_slice::strcmp (string_slice ("ab", 2),
     746              :                                    string_slice ("a")), 1);
     747            4 : }
     748              : 
     749              : static void
     750            4 : test_string_slice_equality ()
     751              : {
     752            4 :   ASSERT_TRUE (string_slice () == string_slice ());
     753            4 :   ASSERT_FALSE (string_slice ("test") == string_slice ());
     754            4 :   ASSERT_FALSE ("test" == string_slice ());
     755            4 :   ASSERT_FALSE (string_slice () == string_slice ("test"));
     756            4 :   ASSERT_FALSE (string_slice () == "test");
     757            4 :   ASSERT_TRUE (string_slice ("test") == string_slice ("test"));
     758            4 :   ASSERT_TRUE ("test" == string_slice ("test"));
     759            4 :   ASSERT_TRUE (string_slice ("test") == "test");
     760            4 :   ASSERT_FALSE (string_slice ("a") == string_slice ("b"));
     761            4 :   ASSERT_FALSE ("a" == string_slice ("b"));
     762            4 :   ASSERT_FALSE (string_slice ("a") == "b");
     763            4 :   ASSERT_FALSE (string_slice ("b") == string_slice ("a"));
     764            4 :   ASSERT_TRUE (string_slice ("ab", 1) == string_slice ("a"));
     765            4 :   ASSERT_TRUE (string_slice ("ab", 1) == "a");
     766            4 :   ASSERT_FALSE (string_slice ("ab", 2) == string_slice ("a"));
     767            4 :   ASSERT_FALSE (string_slice ("ab", 2) == "a");
     768            4 : }
     769              : 
     770              : static void
     771            4 : test_string_slice_inequality ()
     772              : {
     773            4 :   ASSERT_FALSE (string_slice () != string_slice ());
     774            4 :   ASSERT_TRUE (string_slice ("test") != string_slice ());
     775            4 :   ASSERT_TRUE ("test" != string_slice ());
     776            4 :   ASSERT_TRUE (string_slice () != string_slice ("test"));
     777            4 :   ASSERT_TRUE (string_slice () != "test");
     778            4 :   ASSERT_FALSE (string_slice ("test") != string_slice ("test"));
     779            4 :   ASSERT_FALSE ("test" != string_slice ("test"));
     780            4 :   ASSERT_FALSE (string_slice ("test") != "test");
     781            4 :   ASSERT_TRUE (string_slice ("a") != string_slice ("b"));
     782            4 :   ASSERT_TRUE ("a" != string_slice ("b"));
     783            4 :   ASSERT_TRUE (string_slice ("a") != "b");
     784            4 :   ASSERT_TRUE (string_slice ("b") != string_slice ("a"));
     785            4 :   ASSERT_FALSE (string_slice ("ab", 1) != string_slice ("a"));
     786            4 :   ASSERT_FALSE (string_slice ("ab", 1) != "a");
     787            4 :   ASSERT_TRUE (string_slice ("ab", 2) != string_slice ("a"));
     788            4 :   ASSERT_TRUE (string_slice ("ab", 2) != "a");
     789            4 : }
     790              : 
     791              : static void
     792            4 : test_string_slice_invalid ()
     793              : {
     794            4 :   ASSERT_FALSE (string_slice::invalid ().is_valid ());
     795            4 :   ASSERT_FALSE (string_slice (NULL, 1).is_valid ());
     796            4 :   ASSERT_TRUE (string_slice (NULL, (size_t) 0).is_valid ());
     797            4 :   ASSERT_TRUE (string_slice ("Test", (size_t) 0).is_valid ());
     798            4 :   ASSERT_TRUE (string_slice ().is_valid ());
     799            4 : }
     800              : 
     801              : static void
     802            4 : test_string_slice_strip ()
     803              : {
     804            4 :   ASSERT_EQ (string_slice ("   test   ").strip (), string_slice ("test"));
     805            4 :   ASSERT_EQ (string_slice ("\t   test string\t   \n ").strip (),
     806              :              string_slice ("test string"));
     807            4 :   ASSERT_EQ (string_slice ("test").strip (), string_slice ("test"));
     808            4 :   ASSERT_EQ (string_slice ().strip (), string_slice ());
     809            4 :   ASSERT_EQ (string_slice ("\t  \n \t   ").strip (), string_slice ());
     810            4 : }
     811              : 
     812              : /* Run all of the selftests within this file.  */
     813              : 
     814              : void
     815            4 : vec_cc_tests ()
     816              : {
     817            4 :   test_init ();
     818            4 :   test_quick_push ();
     819            4 :   test_safe_push ();
     820            4 :   test_truncate ();
     821            4 :   test_safe_grow_cleared ();
     822            4 :   test_pop ();
     823            4 :   test_safe_insert ();
     824            4 :   test_ordered_remove ();
     825            4 :   test_ordered_remove_if ();
     826            4 :   test_unordered_remove ();
     827            4 :   test_block_remove ();
     828            4 :   test_qsort ();
     829            4 :   test_reverse ();
     830            4 :   test_auto_delete_vec ();
     831            4 :   test_auto_alias ();
     832            4 :   test_string_slice_initializers ();
     833            4 :   test_string_slice_tokenize ();
     834            4 :   test_string_slice_strcmp ();
     835            4 :   test_string_slice_equality ();
     836            4 :   test_string_slice_inequality ();
     837            4 :   test_string_slice_invalid ();
     838            4 :   test_string_slice_strip ();
     839            4 : }
     840              : 
     841              : } // namespace selftest
     842              : 
     843              : #endif /* #if CHECKING_P */
     844              : #endif /* #ifndef GENERATOR_FILE */
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.