diff options
author | David Malcolm <dmalcolm@redhat.com> | 2023-11-06 14:28:41 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2023-11-06 14:28:41 -0500 |
commit | 38763e2c188fa91dfba1a77206f12db41950935c (patch) | |
tree | cc6231694440857fc2d232dad8a28e8fe7074009 /gcc | |
parent | a526cc6ff32e22e1a948c1c5f30d977d440c8da5 (diff) | |
download | gcc-38763e2c188fa91dfba1a77206f12db41950935c.zip gcc-38763e2c188fa91dfba1a77206f12db41950935c.tar.gz gcc-38763e2c188fa91dfba1a77206f12db41950935c.tar.bz2 |
diagnostics: introduce class diagnostic_option_classifier
This patch gathers the 6 fields in diagnostic_context relating to
keeping track of overriding the severity of warnings, and
pushing/popping those severities, moving them all into a new class
diagnostic_option_classifier.
No functional change intended.
gcc/ChangeLog:
* diagnostic.cc (diagnostic_context::push_diagnostics): Convert
to...
(diagnostic_option_classifier::push): ...this.
(diagnostic_context::pop_diagnostics): Convert to...
(diagnostic_option_classifier::pop): ...this.
(diagnostic_context::initialize): Move code to...
(diagnostic_option_classifier::init): ...this new function.
(diagnostic_context::finish): Move code to...
(diagnostic_option_classifier::fini): ...this new function.
(diagnostic_context::classify_diagnostic): Convert to...
(diagnostic_option_classifier::classify_diagnostic): ...this.
(diagnostic_context::update_effective_level_from_pragmas): Convert
to...
(diagnostic_option_classifier::update_effective_level_from_pragmas):
...this.
(diagnostic_context::diagnostic_enabled): Update for refactoring.
* diagnostic.h (struct diagnostic_classification_change_t): Move into...
(class diagnostic_option_classifier): ...this new class.
(diagnostic_context::option_unspecified_p): Update for move of
fields into m_option_classifier.
(diagnostic_context::classify_diagnostic): Likewise.
(diagnostic_context::push_diagnostics): Likewise.
(diagnostic_context::pop_diagnostics): Likewise.
(diagnostic_context::update_effective_level_from_pragmas): Delete.
(diagnostic_context::m_classify_diagnostic): Move into class
diagnostic_option_classifier.
(diagnostic_context::m_option_classifier): Likewise.
(diagnostic_context::m_classification_history): Likewise.
(diagnostic_context::m_n_classification_history): Likewise.
(diagnostic_context::m_push_list): Likewise.
(diagnostic_context::m_n_push): Likewise.
(diagnostic_context::m_option_classifier): New.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/diagnostic.cc | 124 | ||||
-rw-r--r-- | gcc/diagnostic.h | 131 |
2 files changed, 163 insertions, 92 deletions
diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc index c617b34..addd660 100644 --- a/gcc/diagnostic.cc +++ b/gcc/diagnostic.cc @@ -149,13 +149,63 @@ diagnostic_set_caret_max_width (diagnostic_context *context, int value) context->m_source_printing.max_width = value; } +void +diagnostic_option_classifier::init (int n_opts) +{ + m_n_opts = n_opts; + 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; +} + +void +diagnostic_option_classifier::fini () +{ + XDELETEVEC (m_classify_diagnostic); + m_classify_diagnostic = nullptr; + free (m_push_list); + m_n_push = 0; +} + +/* Save all diagnostic classifications in a stack. */ + +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; +} + +/* Restore the topmost classification set off the stack. If the stack + is empty, revert to the state based on command line parameters. */ + +void +diagnostic_option_classifier::pop (location_t where) +{ + int jump_to; + + if (m_n_push) + jump_to = m_push_list [-- m_n_push]; + 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 ++; +} + /* Initialize the diagnostic message outputting machinery. */ void diagnostic_context::initialize (int n_opts) { - int i; - /* Allocate a basic pretty-printer. Clients will replace this a much more elaborated pretty-printer if they wish. */ this->printer = XNEW (pretty_printer); @@ -165,12 +215,10 @@ diagnostic_context::initialize (int n_opts) memset (m_diagnostic_count, 0, sizeof m_diagnostic_count); m_warning_as_error_requested = false; m_n_opts = n_opts; - m_classify_diagnostic = XNEWVEC (diagnostic_t, n_opts); - for (i = 0; i < n_opts; i++) - m_classify_diagnostic[i] = DK_UNSPECIFIED; + m_option_classifier.init (n_opts); m_source_printing.enabled = false; diagnostic_set_caret_max_width (this, pp_line_cutoff (this->printer)); - for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++) + for (int i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++) m_source_printing.caret_chars[i] = '^'; m_show_cwe = false; m_show_rules = false; @@ -326,8 +374,7 @@ diagnostic_context::finish () delete m_file_cache; m_file_cache = nullptr; - XDELETEVEC (m_classify_diagnostic); - m_classify_diagnostic = nullptr; + m_option_classifier.fini (); /* diagnostic_context::initialize allocates this->printer using XNEW and placement-new. */ @@ -1052,9 +1099,11 @@ default_diagnostic_finalizer (diagnostic_context *context, range. If OPTION_INDEX is zero, the new setting is for all the diagnostics. */ diagnostic_t -diagnostic_context::classify_diagnostic (int option_index, - diagnostic_t new_kind, - location_t where) +diagnostic_option_classifier:: +classify_diagnostic (const diagnostic_context *context, + int option_index, + diagnostic_t new_kind, + location_t where) { diagnostic_t old_kind; @@ -1074,10 +1123,10 @@ diagnostic_context::classify_diagnostic (int option_index, /* Record the command-line status, so we can reset it back on DK_POP. */ if (old_kind == DK_UNSPECIFIED) { - old_kind = !m_option_enabled (option_index, - m_lang_mask, - m_option_state) - ? DK_IGNORED : (m_warning_as_error_requested + old_kind = !context->m_option_enabled (option_index, + context->m_lang_mask, + context->m_option_state) + ? DK_IGNORED : (context->warning_as_error_requested_p () ? DK_ERROR : DK_WARNING); m_classify_diagnostic[option_index] = old_kind; } @@ -1104,37 +1153,6 @@ diagnostic_context::classify_diagnostic (int option_index, return old_kind; } -/* Save all diagnostic classifications in a stack. */ -void -diagnostic_context::push_diagnostics (location_t where ATTRIBUTE_UNUSED) -{ - m_push_list = (int *) xrealloc (m_push_list, (m_n_push + 1) * sizeof (int)); - m_push_list[m_n_push ++] = m_n_classification_history; -} - -/* Restore the topmost classification set off the stack. If the stack - is empty, revert to the state based on command line parameters. */ -void -diagnostic_context::pop_diagnostics (location_t where) -{ - int jump_to; - int i; - - if (m_n_push) - jump_to = m_push_list [-- m_n_push]; - else - jump_to = 0; - - 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 ++; -} - /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the escaping rules for -fdiagnostics-parseable-fixits. */ @@ -1246,14 +1264,14 @@ diagnostic_context::get_any_inlining_info (diagnostic_info *diagnostic) /* Update the kind of DIAGNOSTIC based on its location(s), including any of those in its inlining stack, relative to any #pragma GCC diagnostic - directives recorded within CONTEXT. + directives recorded within this object. Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED otherwise. */ diagnostic_t -diagnostic_context:: -update_effective_level_from_pragmas (diagnostic_info *diagnostic) +diagnostic_option_classifier:: +update_effective_level_from_pragmas (diagnostic_info *diagnostic) const { if (m_n_classification_history <= 0) return DK_UNSPECIFIED; @@ -1444,14 +1462,14 @@ diagnostic_context::diagnostic_enabled (diagnostic_info *diagnostic) return false; /* This tests for #pragma diagnostic changes. */ - diagnostic_t diag_class = update_effective_level_from_pragmas (diagnostic); + diagnostic_t diag_class + = m_option_classifier.update_effective_level_from_pragmas (diagnostic); /* This tests if the user provided the appropriate -Werror=foo option. */ if (diag_class == DK_UNSPECIFIED - && (m_classify_diagnostic[diagnostic->option_index] - != DK_UNSPECIFIED)) - diagnostic->kind = m_classify_diagnostic[diagnostic->option_index]; + && !option_unspecified_p (diagnostic->option_index)) + diagnostic->kind = m_option_classifier.get_current_override (diagnostic->option_index); /* This allows for future extensions, like temporarily disabling warnings for ranges of source code. */ diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index f9950ec..b83cdeb 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -168,16 +168,6 @@ struct diagnostic_info } m_iinfo; }; -/* 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. */ -struct diagnostic_classification_change_t -{ - location_t location; - int option; - diagnostic_t kind; -}; - /* Forward declarations. */ typedef void (*diagnostic_starter_fn) (diagnostic_context *, diagnostic_info *); @@ -240,6 +230,79 @@ public: void on_diagram (const diagnostic_diagram &diagram) override; }; +/* A stack of sets of classifications: each entry in the stack is + a mapping from option index to diagnostic severity that can be changed + via pragmas. The stack can be pushed and popped. */ + +class diagnostic_option_classifier +{ +public: + void init (int n_opts); + void fini (); + + /* Save all diagnostic classifications in a stack. */ + void push (); + + /* Restore the topmost classification set off the stack. If the stack + is empty, revert to the state based on command line parameters. */ + void pop (location_t where); + + bool option_unspecified_p (int opt) const + { + return get_current_override (opt) == DK_UNSPECIFIED; + } + + diagnostic_t get_current_override (int opt) const + { + gcc_assert (opt < m_n_opts); + return m_classify_diagnostic[opt]; + } + + diagnostic_t + classify_diagnostic (const diagnostic_context *context, + int option_index, + diagnostic_t new_kind, + location_t where); + + diagnostic_t + update_effective_level_from_pragmas (diagnostic_info *diagnostic) const; + +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. */ + struct diagnostic_classification_change_t + { + location_t location; + int option; + diagnostic_t kind; + }; + + int m_n_opts; + + /* For each option index that can be passed to warning() et al + (OPT_* from options.h when using this code with the core GCC + options), this array may contain a new kind that the diagnostic + should be changed to before reporting, or DK_UNSPECIFIED to leave + it as the reported kind, or DK_IGNORED to not report it at + all. */ + diagnostic_t *m_classify_diagnostic; + + /* History of all changes to the classifications above. This list + is stored in location-order, so we can search it, either + 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; + + /* For pragma push/pop. */ + int *m_push_list; + int m_n_push; +}; + /* This data structure bundles altogether any information relevant to the context of a diagnostic message. */ class diagnostic_context @@ -273,8 +336,7 @@ public: bool option_unspecified_p (int opt) const { - gcc_assert (opt < m_n_opts); - return m_classify_diagnostic[opt] == DK_UNSPECIFIED; + return m_option_classifier.option_unspecified_p (opt); } bool report_diagnostic (diagnostic_info *); @@ -287,9 +349,22 @@ public: diagnostic_t classify_diagnostic (int option_index, diagnostic_t new_kind, - location_t where); - void push_diagnostics (location_t where ATTRIBUTE_UNUSED); - void pop_diagnostics (location_t where); + location_t where) + { + return m_option_classifier.classify_diagnostic (this, + option_index, + new_kind, + where); + } + + void push_diagnostics (location_t where ATTRIBUTE_UNUSED) + { + m_option_classifier.push (); + } + void pop_diagnostics (location_t where) + { + m_option_classifier.pop (where); + } void emit_diagram (const diagnostic_diagram &diagram); @@ -376,9 +451,6 @@ private: bool diagnostic_enabled (diagnostic_info *diagnostic); void get_any_inlining_info (diagnostic_info *diagnostic); - diagnostic_t - update_effective_level_from_pragmas (diagnostic_info *diagnostic); - /* Data members. Ideally, all of these would be private and have "m_" prefixes. */ @@ -401,27 +473,8 @@ private: al. */ int m_n_opts; - /* For each option index that can be passed to warning() et al - (OPT_* from options.h when using this code with the core GCC - options), this array may contain a new kind that the diagnostic - should be changed to before reporting, or DK_UNSPECIFIED to leave - it as the reported kind, or DK_IGNORED to not report it at - all. */ - diagnostic_t *m_classify_diagnostic; - - /* History of all changes to the classifications above. This list - is stored in location-order, so we can search it, either - 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; - - /* For pragma push/pop. */ - int *m_push_list; - int m_n_push; + /* The stack of sets of overridden diagnostic option severities. */ + diagnostic_option_classifier m_option_classifier; /* True if we should print any CWE identifiers associated with diagnostics. */ |