aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2023-11-06 14:28:41 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2023-11-06 14:28:41 -0500
commit38763e2c188fa91dfba1a77206f12db41950935c (patch)
treecc6231694440857fc2d232dad8a28e8fe7074009 /gcc
parenta526cc6ff32e22e1a948c1c5f30d977d440c8da5 (diff)
downloadgcc-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.cc124
-rw-r--r--gcc/diagnostic.h131
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. */