https://gcc.gnu.org/g:613ade639ab886f853f3713b1ef4587fdcebe6d8
commit r17-2489-g613ade639ab886f853f3713b1ef4587fdcebe6d8 Author: Lewis Hyatt <[email protected]> Date: Sat Jul 11 14:21:12 2026 -0400 diagnostics: Preparation for LTO diagnostic pragma support The next patches in this series will enable support for `#pragma GCC diagnostic' in the LTO streaming code. This requires some minor changes to the diagnostics interface so that LTO can access what it needs: 1) Make the name of the type option_classifier::classification_change_t publicly accessible. The actual m_classification_history object is already public via an accessor function, which was needed for C++ modules; this patch just additionally makes the name of the type accessible for convenience. 2) Add a trailing member to enum diagnostics::kind indicating the maximum possible value. This is for the benefit of LTO streaming that can make use of the range information. 3) The function option_classifier::classify_diagnostic() does some work to return a value; when a diagnostic kind is changed, it claims to return the previous kind. The returned value is incorrect, however; it does not attempt to follow the history of diagnostic pop pragmas to return the actual previous value, and it could also misinterpret a pop directive if the pop index happens to match the index of the option being processed. There is no actual need to compute this value, and it has never been used by any callers, so remove it entirely. This change is not strictly necessary for the rest of this patch series, but the extra work being done here may be a bigger concern for LTO, which could potentially have a rather large list of diagnostic pragmas to work with, so it seemed worthwhile to include this fix now. gcc/ChangeLog: * diagnostic.h (diagnostic_classify_diagnostic): Adapt for removal of return value in option_classifier::classify_diagnostic. * diagnostics/context.h: Likewise. * diagnostics/kinds.h (enum kind): Add trailing element to indicate the total number of kinds. * diagnostics/option-classifier.cc (option_classifier::classify_diagnostic): Remove the return value, which was not correct and which was not used anyway. * diagnostics/option-classifier.h (class option_classifier): Adjust prototype for classify_diagnostic. Make the name of nested strruct classification_change_t publicly accessible. Diff: --- gcc/diagnostic.h | 4 ++-- gcc/diagnostics/context.h | 7 ++----- gcc/diagnostics/kinds.h | 4 +++- gcc/diagnostics/option-classifier.cc | 37 +++++++++--------------------------- gcc/diagnostics/option-classifier.h | 4 ++-- 5 files changed, 18 insertions(+), 38 deletions(-) diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index 37e48d771872..9f7b2089e387 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -141,13 +141,13 @@ diagnostic_initialize_input_context (diagnostics::context *context, } /* Force diagnostics controlled by OPTIDX to be kind KIND. */ -inline diagnostics::kind +inline void diagnostic_classify_diagnostic (diagnostics::context *context, diagnostics::option_id opt_id, enum diagnostics::kind kind, location_t where) { - return context->classify_diagnostic (opt_id, kind, where); + context->classify_diagnostic (opt_id, kind, where); } inline void diff --git a/gcc/diagnostics/context.h b/gcc/diagnostics/context.h index 44ec55820f6f..a7a4bf77985d 100644 --- a/gcc/diagnostics/context.h +++ b/gcc/diagnostics/context.h @@ -339,7 +339,7 @@ public: void report_global_digraph (const lazily_created<digraphs::digraph> &); - enum kind + void classify_diagnostic (option_id opt_id, enum kind new_kind, location_t where) @@ -351,10 +351,7 @@ public: .log_param_location_t ("where", where); logging::auto_inc_depth depth_sentinel (m_logger); - return m_option_classifier.classify_diagnostic (this, - opt_id, - new_kind, - where); + m_option_classifier.classify_diagnostic (this, opt_id, new_kind, where); } void push_diagnostics (location_t where) diff --git a/gcc/diagnostics/kinds.h b/gcc/diagnostics/kinds.h index b7977e1cea3e..15c032f53acd 100644 --- a/gcc/diagnostics/kinds.h +++ b/gcc/diagnostics/kinds.h @@ -34,7 +34,9 @@ enum class kind pop, /* This is used internally to note that a diagnostic is enabled without mandating any specific type. */ - any + any, + + tot_num_diagnostic_kinds }; extern const char *get_text_for_kind (enum diagnostics::kind); diff --git a/gcc/diagnostics/option-classifier.cc b/gcc/diagnostics/option-classifier.cc index 1016cca3ff18..60dd1dda49a8 100644 --- a/gcc/diagnostics/option-classifier.cc +++ b/gcc/diagnostics/option-classifier.cc @@ -115,56 +115,37 @@ option_classifier::pop (location_t where) m_classification_history.safe_push (v); } -/* Interface to specify diagnostic kind overrides. Returns the - previous setting, or kind::unspecified if the parameters are out of - range. If OPTION_ID is zero, the new setting is for all the - diagnostics. */ +/* Interface to specify diagnostic kind overrides. If OPTION_ID is zero, the + new setting is for all the diagnostics. */ -enum kind +void option_classifier::classify_diagnostic (const context *dc, option_id opt_id, enum kind new_kind, location_t where) { - enum kind old_kind; - if (opt_id.m_idx < 0 || opt_id.m_idx >= m_n_opts || new_kind >= kind::last_diagnostic_kind) - return kind::unspecified; + return; - old_kind = m_classify_diagnostic[opt_id.m_idx]; + auto &base_kind = m_classify_diagnostic[opt_id.m_idx]; /* Handle pragmas separately, since we need to keep track of *where* the pragmas were. */ if (where != UNKNOWN_LOCATION) { - unsigned i; - /* Record the command-line status, so we can reset it back on kind::pop. */ - if (old_kind == kind::unspecified) - { - old_kind = (!dc->option_enabled_p (opt_id) - ? kind::ignored : kind::any); - m_classify_diagnostic[opt_id.m_idx] = old_kind; - } - - classification_change_t *p; - FOR_EACH_VEC_ELT_REVERSE (m_classification_history, i, p) - if (p->option == opt_id.m_idx) - { - old_kind = p->kind; - break; - } + if (base_kind == kind::unspecified) + base_kind = (!dc->option_enabled_p (opt_id) + ? kind::ignored : kind::any); classification_change_t v = { where, opt_id.m_idx, new_kind }; m_classification_history.safe_push (v); } else - m_classify_diagnostic[opt_id.m_idx] = new_kind; - - return old_kind; + base_kind = new_kind; } /* Update the kind of DIAGNOSTIC based on its location(s), including diff --git a/gcc/diagnostics/option-classifier.h b/gcc/diagnostics/option-classifier.h index acdfec1df4b9..2acc32d435b2 100644 --- a/gcc/diagnostics/option-classifier.h +++ b/gcc/diagnostics/option-classifier.h @@ -57,7 +57,7 @@ public: return m_classify_diagnostic[opt_id.m_idx]; } - enum kind + void classify_diagnostic (const context *context, option_id opt_id, enum kind new_kind, @@ -69,7 +69,6 @@ public: int pch_save (FILE *); int pch_restore (FILE *); -private: /* Each time a diagnostic's classification is changed with a pragma, we record the change and the location of the change in an array of these structs. */ @@ -85,6 +84,7 @@ private: enum kind kind; }; +private: int m_n_opts; /* For each option index that can be passed to warning() et al
