===================================================================
@@ -14807,6 +14807,10 @@ track of the location of each pragma, an
to the state as of that point in the source file. Thus, pragmas occurring
after a line do not affect diagnostics caused by that line.
+@item #pragma GCC diagnostic off
+Causes GCC to ignore all the diagnostics. This is equivalent to specifying
+@samp{ignored} for all the diagnostics with the previous form of the pragma.
+
@item #pragma GCC diagnostic push
@itemx #pragma GCC diagnostic pop
===================================================================
@@ -684,19 +684,22 @@ handle_pragma_visibility (cpp_reader *du
warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>");
}
+#define ALL_KINDS_STRING "[error|warning|ignored|off|push|pop]"
+
static void
handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
{
- const char *kind_string, *option_string;
+ const char *kind_string;
unsigned int option_index;
enum cpp_ttype token;
diagnostic_t kind;
tree x;
struct cl_option_handlers handlers;
+ bool no_option = false;
token = pragma_lex (&x);
if (token != CPP_NAME)
- GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>");
+ GCC_BAD ("missing "ALL_KINDS_STRING" after %<#pragma GCC diagnostic%>");
kind_string = IDENTIFIER_POINTER (x);
if (strcmp (kind_string, "error") == 0)
kind = DK_ERROR;
@@ -704,6 +707,11 @@ handle_pragma_diagnostic(cpp_reader *ARG
kind = DK_WARNING;
else if (strcmp (kind_string, "ignored") == 0)
kind = DK_IGNORED;
+ else if (strcmp (kind_string, "off") == 0)
+ {
+ kind = DK_IGNORED;
+ no_option = true;
+ }
else if (strcmp (kind_string, "push") == 0)
{
diagnostic_push_diagnostics (global_dc, input_location);
@@ -715,23 +723,27 @@ handle_pragma_diagnostic(cpp_reader *ARG
return;
}
else
- GCC_BAD ("expected [error|warning|ignored|push|pop] after %<#pragma GCC diagnostic%>");
+ GCC_BAD ("expected "ALL_KINDS_STRING" after %<#pragma GCC diagnostic%>");
+
+ if (no_option)
+ option_index = 0;
+ else
+ {
+ token = pragma_lex (&x);
+ if (token != CPP_STRING)
+ GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
+ const char *option_string = TREE_STRING_POINTER (x);
+ for (option_index = 0; option_index < cl_options_count; option_index++)
+ if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
+ break;
+ if (option_index == cl_options_count)
+ GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
+ }
- token = pragma_lex (&x);
- if (token != CPP_STRING)
- GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
- option_string = TREE_STRING_POINTER (x);
set_default_handlers (&handlers);
- for (option_index = 0; option_index < cl_options_count; option_index++)
- if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
- {
- control_warning_option (option_index, (int) kind, kind != DK_IGNORED,
- input_location, c_family_lang_mask, &handlers,
- &global_options, &global_options_set,
- global_dc);
- return;
- }
- GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
+ control_warning_option (option_index, (int) kind, kind != DK_IGNORED,
+ input_location, c_family_lang_mask, &handlers,
+ &global_options, &global_options_set, global_dc);
}
/* Parse #pragma GCC target (xxx) to set target specific options. */
===================================================================
@@ -551,7 +551,8 @@ default_diagnostic_finalizer (diagnostic
/* Interface to specify diagnostic kind overrides. Returns the
previous setting, or DK_UNSPECIFIED if the parameters are out of
- range. */
+ range. If OPTION_INDEX is zero, the new setting is for all the
+ diagnostics. */
diagnostic_t
diagnostic_classify_diagnostic (diagnostic_context *context,
int option_index,
@@ -560,7 +561,7 @@ diagnostic_classify_diagnostic (diagnost
{
diagnostic_t old_kind;
- if (option_index <= 0
+ if (option_index < 0
|| option_index >= context->n_opts
|| new_kind >= DK_LAST_DIAGNOSTIC_KIND)
return DK_UNSPECIFIED;
@@ -692,9 +693,8 @@ diagnostic_report_diagnostic (diagnostic
/* This tests for #pragma diagnostic changes. */
if (context->n_classification_history > 0)
{
- int i;
/* FIXME: Stupid search. Optimize later. */
- for (i = context->n_classification_history - 1; i >= 0; i --)
+ for (int i = context->n_classification_history - 1; i >= 0; i --)
{
if (linemap_location_before_p
(line_table,
@@ -706,7 +706,9 @@ diagnostic_report_diagnostic (diagnostic
i = context->classification_history[i].option;
continue;
}
- if (context->classification_history[i].option == diagnostic->option_index)
+ int option = context->classification_history[i].option;
+ /* The option 0 is for all the diagnostics. */
+ if (option == 0 || option == diagnostic->option_index)
{
diag_class = context->classification_history[i].kind;
if (diag_class != DK_UNSPECIFIED)
===================================================================
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-Wuninitialized" } */
+
+#pragma GCC diagnostic push
+
+int foo1 (void)
+{
+ int i;
+#pragma GCC diagnostic off
+ return i; /* { dg-bogus "is used uninitialized" } */
+}
+
+#pragma GCC diagnostic pop
+
+int foo2 (void)
+{
+ int i;
+ return i; /* { dg-warning "is used uninitialized" } */
+}
===================================================================
@@ -36,6 +36,8 @@
#include "gimple.h"
#include "bitmap.h"
#include "cgraph.h"
+#include "diagnostic.h"
+#include "opts.h"
#include "target.h"
#include "common/common-target.h"
@@ -1184,8 +1186,8 @@ Identifier_to_gnu (Node_Id gnat_node, tr
static tree
Pragma_to_gnu (Node_Id gnat_node)
{
- Node_Id gnat_temp;
tree gnu_result = alloc_stmt_list ();
+ Node_Id gnat_temp;
/* Check for (and ignore) unrecognized pragma and do nothing if we are just
annotating types. */
@@ -1278,6 +1280,89 @@ Pragma_to_gnu (Node_Id gnat_node)
if (write_symbols == NO_DEBUG)
post_error ("must specify -g?", gnat_node);
break;
+
+ case Pragma_Warnings:
+ {
+ Node_Id gnat_expr;
+ /* Preserve the location of the pragma. */
+ const location_t location = input_location;
+ struct cl_option_handlers handlers;
+ unsigned int option_index;
+ diagnostic_t kind;
+ bool imply;
+
+ gnat_temp = First (Pragma_Argument_Associations (gnat_node));
+
+ /* This is the String form: pragma Warnings (String). */
+ if (Nkind (Expression (gnat_temp)) == N_String_Literal)
+ {
+ kind = DK_WARNING;
+ gnat_expr = Expression (gnat_temp);
+ imply = true;
+ }
+
+ /* This is the On/Off form: pragma Warnings (On | Off [,String]). */
+ else if (Nkind (Expression (gnat_temp)) == N_Identifier)
+ {
+ switch (Chars (Expression (gnat_temp)))
+ {
+ case Name_Off:
+ kind = DK_IGNORED;
+ break;
+
+ case Name_On:
+ kind = DK_WARNING;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ if (Present (Next (gnat_temp)))
+ {
+ /* pragma Warnings (On | Off, Name) is handled differently. */
+ if (Nkind (Expression (Next (gnat_temp))) != N_String_Literal)
+ break;
+
+ gnat_expr = Expression (Next (gnat_temp));
+ }
+ else
+ gnat_expr = Empty;
+
+ imply = false;
+ }
+
+ else
+ gcc_unreachable ();
+
+ /* This is the same implementation as in the C family of compilers. */
+ if (Present (gnat_expr))
+ {
+ tree gnu_expr = gnat_to_gnu (gnat_expr);
+ const char *opt_string = TREE_STRING_POINTER (gnu_expr);
+ const int len = TREE_STRING_LENGTH (gnu_expr);
+ if (len < 3 || opt_string[0] != '-' || opt_string[1] != 'W')
+ break;
+ for (option_index = 0;
+ option_index < cl_options_count;
+ option_index++)
+ if (strcmp (cl_options[option_index].opt_text, opt_string) == 0)
+ break;
+ if (option_index == cl_options_count)
+ {
+ post_error ("unknown -W switch", gnat_node);
+ break;
+ }
+ }
+ else
+ option_index = 0;
+
+ set_default_handlers (&handlers);
+ control_warning_option (option_index, (int) kind, imply, location,
+ CL_Ada, &handlers, &global_options,
+ &global_options_set, global_dc);
+ }
+ break;
}
return gnu_result;