Hi! diagnostic.h already relies on vec.h, it uses auto_vec in one spot.
The following patch converts m_classification_history and m_push_list hand-managed arrays to vec templates. The main advantage is exponential rather than linear reallocation, e.g. with current libstdc++ headers if one includes all the standard headers there could be ~ 300 reallocations of the m_classification_history array (sure, not all of them will result in actually copying the data, but still). In addition to that it fixes some formatting issues in the code. Bootstrapped on i686-linux so far, bootstrap/regtest on x86_64-linux and i686-linux still pending, ok for trunk if it passes it? 2024-09-26 Jakub Jelinek <ja...@redhat.com> PR libstdc++/116847 * diagnostic.h (diagnostic_option_classifier): Change type of m_classification_history from diagnostic_classification_change_t * to vec<diagnostic_classification_change_t>. Change type of m_push_list from int * to vec<int>. Remove m_n_classification_history and m_n_push members. * diagnostic.cc (diagnostic_option_classifier::init): Set m_push_list to vNULL rather than nullptr. Don't initialize m_n_push. Initialize m_classification_history to vNULL. (diagnostic_option_classifier::fini): Call release () method on m_push_list instead of free on it. Call release () on m_classification_history. Don't clear m_n_push. (diagnostic_option_classifier::push): Adjust for m_push_list and m_classification_history being vectors rather than custom allocated arrays with counter. (diagnostic_option_classifier::pop): Likewise. (classify_diagnostic): Adjust for m_classification_history being vector rather than custom allocated array with counter. (update_effective_level_from_pragmas): Likewise. --- gcc/diagnostic.h.jj 2024-09-21 12:28:13.452940750 +0200 +++ gcc/diagnostic.h 2024-09-26 15:42:05.696731787 +0200 @@ -287,14 +287,10 @@ private: binary-wise or end-to-front, to find the most recent classification for a given diagnostic, given the location of the diagnostic. */ - diagnostic_classification_change_t *m_classification_history; - - /* The size of the above array. */ - int m_n_classification_history; + vec<diagnostic_classification_change_t> m_classification_history; /* For pragma push/pop. */ - int *m_push_list; - int m_n_push; + vec<int> m_push_list; }; /* A bundle of options relating to printing the user's source code --- gcc/diagnostic.cc.jj 2024-09-21 12:28:13.438940942 +0200 +++ gcc/diagnostic.cc 2024-09-26 16:11:51.664502977 +0200 @@ -143,8 +143,8 @@ diagnostic_option_classifier::init (int m_classify_diagnostic = XNEWVEC (diagnostic_t, n_opts); for (int i = 0; i < n_opts; i++) m_classify_diagnostic[i] = DK_UNSPECIFIED; - m_push_list = nullptr; - m_n_push = 0; + m_push_list = vNULL; + m_classification_history = vNULL; } void @@ -152,8 +152,8 @@ diagnostic_option_classifier::fini () { XDELETEVEC (m_classify_diagnostic); m_classify_diagnostic = nullptr; - free (m_push_list); - m_n_push = 0; + m_classification_history.release (); + m_push_list.release (); } /* Save all diagnostic classifications in a stack. */ @@ -161,8 +161,7 @@ diagnostic_option_classifier::fini () void diagnostic_option_classifier::push () { - m_push_list = (int *) xrealloc (m_push_list, (m_n_push + 1) * sizeof (int)); - m_push_list[m_n_push ++] = m_n_classification_history; + m_push_list.safe_push (m_classification_history.length ()); } /* Restore the topmost classification set off the stack. If the stack @@ -173,19 +172,13 @@ diagnostic_option_classifier::pop (locat { int jump_to; - if (m_n_push) - jump_to = m_push_list [-- m_n_push]; + if (!m_push_list.is_empty ()) + jump_to = m_push_list.pop (); else jump_to = 0; - const int i = m_n_classification_history; - m_classification_history = - (diagnostic_classification_change_t *) xrealloc (m_classification_history, (i + 1) - * sizeof (diagnostic_classification_change_t)); - m_classification_history[i].location = where; - m_classification_history[i].option = jump_to; - m_classification_history[i].kind = DK_POP; - m_n_classification_history ++; + diagnostic_classification_change_t v = { where, jump_to, DK_POP }; + m_classification_history.safe_push (v); } /* Initialize the diagnostic message outputting machinery. */ @@ -880,31 +873,27 @@ classify_diagnostic (const diagnostic_co the pragmas were. */ if (where != UNKNOWN_LOCATION) { - int i; + unsigned i; /* Record the command-line status, so we can reset it back on DK_POP. */ if (old_kind == DK_UNSPECIFIED) { - old_kind = !context->option_enabled_p (option_id) - ? DK_IGNORED : DK_ANY; + old_kind = (!context->option_enabled_p (option_id) + ? DK_IGNORED : DK_ANY); m_classify_diagnostic[option_id.m_idx] = old_kind; } - for (i = m_n_classification_history - 1; i >= 0; i --) - if (m_classification_history[i].option == option_id.m_idx) + diagnostic_classification_change_t *p; + FOR_EACH_VEC_ELT_REVERSE (m_classification_history, i, p) + if (p->option == option_id.m_idx) { - old_kind = m_classification_history[i].kind; + old_kind = p->kind; break; } - i = m_n_classification_history; - m_classification_history = - (diagnostic_classification_change_t *) xrealloc (m_classification_history, (i + 1) - * sizeof (diagnostic_classification_change_t)); - m_classification_history[i].location = where; - m_classification_history[i].option = option_id.m_idx; - m_classification_history[i].kind = new_kind; - m_n_classification_history ++; + diagnostic_classification_change_t v + = { where, option_id.m_idx, new_kind }; + m_classification_history.safe_push (v); } else m_classify_diagnostic[option_id.m_idx] = new_kind; @@ -1033,7 +1022,7 @@ diagnostic_t diagnostic_option_classifier:: update_effective_level_from_pragmas (diagnostic_info *diagnostic) const { - if (m_n_classification_history <= 0) + if (m_classification_history.is_empty ()) return DK_UNSPECIFIED; /* Iterate over the locations, checking the diagnostic disposition @@ -1043,27 +1032,26 @@ update_effective_level_from_pragmas (dia for (location_t loc: diagnostic->m_iinfo.m_ilocs) { /* FIXME: Stupid search. Optimize later. */ - for (int i = m_n_classification_history - 1; i >= 0; i --) + unsigned int i; + diagnostic_classification_change_t *p; + FOR_EACH_VEC_ELT_REVERSE (m_classification_history, i, p) { - const diagnostic_classification_change_t &hist - = m_classification_history[i]; - - location_t pragloc = hist.location; + location_t pragloc = p->location; if (!linemap_location_before_p (line_table, pragloc, loc)) continue; - if (hist.kind == (int) DK_POP) + if (p->kind == (int) DK_POP) { /* Move on to the next region. */ - i = hist.option; + i = p->option; continue; } - diagnostic_option_id option = hist.option; + diagnostic_option_id option = p->option; /* The option 0 is for all the diagnostics. */ if (option == 0 || option == diagnostic->option_id) { - diagnostic_t kind = hist.kind; + diagnostic_t kind = p->kind; if (kind != DK_UNSPECIFIED) diagnostic->kind = kind; return kind; Jakub