]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-pragma.c (handle_pragma_diagnostic): New.
authorDJ Delorie <dj@gcc.gnu.org>
Wed, 18 Jan 2006 20:02:42 +0000 (15:02 -0500)
committerDJ Delorie <dj@gcc.gnu.org>
Wed, 18 Jan 2006 20:02:42 +0000 (15:02 -0500)
* c-pragma.c (handle_pragma_diagnostic): New.
(init_pragma): Register it.
* doc/extend.texi: Document it.

* diagnostic.def: Add DK_UNSPECIFIED and DK_IGNORED.
* diagnostic.h (diagnostic_classify_diagnostic): Declare.
(diagnostic_context): Add classify_diagnostic[].
* diagnostic.c (diagnostic_count_diagnostic): Don't count warnings
as errors if they're overridden to DK_WARNING.
(diagnostic_initialize): Initialize classify_diagnostic[].
(diagnostic_set_kind_override): New.
(diagnostic_report_diagnostic): Check for kind changes.
* opts.c (common_handle_option): Take lang_mask.  Update callers.
Handle OPT_Werror_.
* common.opt (Werror=): New.
* doc/invoke.texi: Document -Werror=*

From-SVN: r109907

gcc/ChangeLog
gcc/c-pragma.c
gcc/common.opt
gcc/diagnostic.c
gcc/diagnostic.def
gcc/diagnostic.h
gcc/doc/extend.texi
gcc/doc/invoke.texi
gcc/opts.c

index d6c62f61536968d7d49d03b716234b25c4eb5f36..cd3a907bda6253dedc867d9265519e6c45bb9e47 100644 (file)
@@ -1,3 +1,22 @@
+2006-01-18  DJ Delorie  <dj@redhat.com>
+
+       * c-pragma.c (handle_pragma_diagnostic): New.
+       (init_pragma): Register it.
+       * doc/extend.texi: Document it.
+
+       * diagnostic.def: Add DK_UNSPECIFIED and DK_IGNORED.
+       * diagnostic.h (diagnostic_classify_diagnostic): Declare.
+       (diagnostic_context): Add classify_diagnostic[].
+       * diagnostic.c (diagnostic_count_diagnostic): Don't count warnings
+       as errors if they're overridden to DK_WARNING.
+       (diagnostic_initialize): Initialize classify_diagnostic[].
+       (diagnostic_set_kind_override): New.
+       (diagnostic_report_diagnostic): Check for kind changes.
+       * opts.c (common_handle_option): Take lang_mask.  Update callers.
+       Handle OPT_Werror_.
+       * common.opt (Werror=): New.
+       * doc/invoke.texi: Document -Werror=*
+
 2006-01-18  Jeff Law  <law@redhat.com>
 
        * tree-vrp.c (test_for_singularity): Correct test for new
        * basic-block.h: Remove the prototype for
        partition_hot_cold_basic_blocks.
 
-2006-01-16  Rafael \81Ã\81vila de Esp\81Ã\81­ndola <rafael.espindola@gmail.com>
+2006-01-16  Rafael \81\81Ã\81vila de Esp\81\81Ã\81\81­ndola <rafael.espindola@gmail.com>
 
        * cppspec.c (lang_specific_spec_functions): remove
        * gcc.c (lookup_spec_function): use static_spec_functions directelly
index 554e57f932b8de921b223bf5725c203dc866d353..5256758d94b72c37eb244e4e0d27a14a90d9e782 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
-   Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+   2006 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -36,7 +36,8 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "tm_p.h"
 #include "vec.h"
 #include "target.h"
-
+#include "diagnostic.h"
+#include "opts.h"
 
 #define GCC_BAD(gmsgid) \
   do { warning (OPT_Wpragmas, gmsgid); return; } while (0)
@@ -668,6 +669,53 @@ handle_pragma_visibility (cpp_reader *dummy ATTRIBUTE_UNUSED)
 
 #endif
 
+static void
+handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
+{
+  const char *kind_string, *option_string;
+  unsigned int option_index;
+  enum cpp_ttype token;
+  diagnostic_t kind;
+  tree x;
+
+  if (cfun)
+    {
+      error ("#pragma GCC diagnostic not allowed inside functions");
+      return;
+    }
+
+  token = pragma_lex (&x);
+  if (token != CPP_NAME)
+    GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>");
+  kind_string = IDENTIFIER_POINTER (x);
+  if (strcmp (kind_string, "error") == 0)
+    kind = DK_ERROR;
+  else if (strcmp (kind_string, "warning") == 0)
+    kind = DK_WARNING;
+  else if (strcmp (kind_string, "ignored") == 0)
+    kind = DK_IGNORED;
+  else
+    GCC_BAD ("expected [error|warning|ignored] after %<#pragma GCC diagnostic%>");
+
+  token = pragma_lex (&x);
+  if (token != CPP_STRING)
+    GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
+  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)
+      {
+       /* This overrides -Werror, for example.  */
+       diagnostic_classify_diagnostic (global_dc, option_index, kind);
+       /* This makes sure the option is enabled, like -Wfoo would do.  */
+       if (cl_options[option_index].var_type == CLVC_BOOLEAN
+           && cl_options[option_index].flag_var
+           && kind != DK_IGNORED)
+           *(int *) cl_options[option_index].flag_var = 1;
+       return;
+      }
+  GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
+}
+
 /* A vector of registered pragma callbacks.  */
 
 DEF_VEC_O (pragma_handler);
@@ -767,6 +815,8 @@ init_pragma (void)
   c_register_pragma ("GCC", "visibility", handle_pragma_visibility);
 #endif
 
+  c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
+
   c_register_pragma (0, "redefine_extname", handle_pragma_redefine_extname);
   c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
 
index 8fe9bee7e9a5151a7ae3fd3511f7234eec95aca4..d16b9977c93a91a966bd9c66e4ccf0c55f5c352a 100644 (file)
@@ -1,6 +1,6 @@
 ; Options for the language- and target-independent parts of the compiler.
 
-; Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+; Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 ;
 ; This file is part of GCC.
 ;
@@ -81,6 +81,10 @@ Werror
 Common Var(warnings_are_errors)
 Treat all warnings as errors
 
+Werror=
+Common Joined
+Treat specified warning as error
+
 Wextra
 Common
 Print extra (possibly unwanted) warnings
index 7f4d8147340f8f31670314929d61930c29409328..48ba2968f3b83a42d1d1746bd65961fb5d35ead6 100644 (file)
@@ -1,5 +1,5 @@
 /* Language-independent diagnostic subroutines for the GNU Compiler Collection
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
 
@@ -61,6 +61,7 @@ static void real_abort (void) ATTRIBUTE_NORETURN;
 /* A diagnostic_context surrogate for stderr.  */
 static diagnostic_context global_diagnostic_context;
 diagnostic_context *global_dc = &global_diagnostic_context;
+
 \f
 /* Return a malloc'd string containing MSG formatted a la printf.  The
    caller is responsible for freeing the memory.  */
@@ -102,6 +103,8 @@ diagnostic_initialize (diagnostic_context *context)
   memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
   context->issue_warnings_are_errors_message = true;
   context->warning_as_error_requested = false;
+  memset (context->classify_diagnostic, DK_UNSPECIFIED,
+         sizeof context->classify_diagnostic);
   context->show_option_requested = false;
   context->abort_on_error = false;
   context->internal_error = NULL;
@@ -202,7 +205,12 @@ diagnostic_count_diagnostic (diagnostic_context *context,
       if (!diagnostic_report_warnings_p ())
         return false;
 
-      if (!context->warning_as_error_requested)
+      /* -Werror can reclassify warnings as errors, but
+        classify_diagnostic can reclassify it back to a warning.  The
+        second part of this test detects that case.  */
+      if (!context->warning_as_error_requested
+         || (context->classify_diagnostic[diagnostic->option_index]
+             == DK_WARNING))
         {
           ++diagnostic_kind_count (context, DK_WARNING);
           break;
@@ -324,6 +332,26 @@ default_diagnostic_finalizer (diagnostic_context *context,
   pp_destroy_prefix (context->printer);
 }
 
+/* Interface to specify diagnostic kind overrides.  Returns the
+   previous setting, or DK_UNSPECIFIED if the parameters are out of
+   range.  */
+diagnostic_t
+diagnostic_classify_diagnostic (diagnostic_context *context,
+                               int option_index,
+                               diagnostic_t new_kind)
+{
+  diagnostic_t old_kind;
+
+  if (option_index <= 0
+      || option_index >= N_OPTS
+      || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
+    return DK_UNSPECIFIED;
+
+  old_kind = context->classify_diagnostic[option_index];
+  context->classify_diagnostic[option_index] = new_kind;
+  return old_kind;
+}
+
 /* Report a diagnostic message (an error or a warning) as specified by
    DC.  This function is *the* subroutine in terms of which front-ends
    should implement their specific diagnostic handling modules.  The
@@ -345,9 +373,21 @@ diagnostic_report_diagnostic (diagnostic_context *context,
        error_recursion (context);
     }
 
-  if (diagnostic->option_index
-      && ! option_enabled (diagnostic->option_index))
-    return;
+  if (diagnostic->option_index)
+    {
+      /* This tests if the user provided the appropriate -Wfoo or
+        -Wno-foo option.  */
+      if (! option_enabled (diagnostic->option_index))
+       return;
+      /* This tests if the user provided the appropriate -Werror=foo
+        option.  */
+      if (context->classify_diagnostic[diagnostic->option_index] != DK_UNSPECIFIED)
+       diagnostic->kind = context->classify_diagnostic[diagnostic->option_index];
+      /* This allows for future extenions, like temporarily disabling
+        warnings for ranges of source code.  */
+      if (diagnostic->kind == DK_IGNORED)
+       return;
+    }
 
   context->lock++;
 
index 6820bb72e9fe05856385e2d5bec350dabfb84f57..bbdba2f1aa266518bdd1558793741e7bcebf994b 100644 (file)
@@ -1,3 +1,17 @@
+/* DK_UNSPECIFIED must be first so it has a value of zero.  We never
+   assign this kind to an actual diagnostic, we only use this in
+   variables that can hold a kind, to mean they have yet to have a
+   kind specified.  I.e. they're uninitialized.  Within the diagnostic
+   machinery, this kind also means "don't change the existing kind",
+   meaning "no change is specified".  */
+DEFINE_DIAGNOSTIC_KIND (DK_UNSPECIFIED, "")
+
+/* If a diagnostic is set to DK_IGNORED, it won't get reported at all.
+   This is used by the diagnostic machinery when it wants to disable a
+   diagnostic without disabling the option which causes it.  */
+DEFINE_DIAGNOSTIC_KIND (DK_IGNORED, "")
+
+/* The remainder are real diagnostic types.  */
 DEFINE_DIAGNOSTIC_KIND (DK_FATAL, "fatal error: ")
 DEFINE_DIAGNOSTIC_KIND (DK_ICE, "internal compiler error: ")
 DEFINE_DIAGNOSTIC_KIND (DK_ERROR, "error: ")
index 242cf47b42f49c8339bb0c29362e04fb54aa999d..51493ea8bab5bcd2df739446edba81a70a966817 100644 (file)
@@ -1,5 +1,5 @@
 /* Various declarations for language-independent diagnostics subroutines.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
 
@@ -73,6 +73,13 @@ struct diagnostic_context
   /* True if it has been requested that warnings be treated as errors.  */
   bool warning_as_error_requested;
 
+  /* For each option index that can be passed to warning() et all
+     (OPT_* from options.h), 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.  N_OPTS is from <options.h>.  */
+  char classify_diagnostic[N_OPTS];
+
   /* True if we should print the command line option which controls
      each diagnostic, if known.  */
   bool show_option_requested;
@@ -179,6 +186,11 @@ extern diagnostic_context *global_dc;
 extern void diagnostic_initialize (diagnostic_context *);
 extern void diagnostic_report_current_module (diagnostic_context *);
 extern void diagnostic_report_current_function (diagnostic_context *);
+
+/* Force diagnostics controlled by OPTIDX to be kind KIND.  */
+extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
+                                                   int /* optidx */,
+                                                   diagnostic_t /* kind */);
 extern void diagnostic_report_diagnostic (diagnostic_context *,
                                          diagnostic_info *);
 #ifdef ATTRIBUTE_GCC_DIAG
index 0c2f39c1e10c02216251d110c006e177b23da339..9d5a8f6076fc1db74c59ae77859a6d4dc0efbea3 100644 (file)
@@ -1,5 +1,5 @@
 @c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000,
-@c 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+@c 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
 @c This is part of the GCC manual.
 @c For copying conditions, see the file gcc.texi.
@@ -9290,6 +9290,7 @@ for further explanation.
 * Symbol-Renaming Pragmas::
 * Structure-Packing Pragmas::
 * Weak Pragmas::
+* Diagnostic Pragmas::
 @end menu
 
 @node ARM Pragmas
@@ -9530,6 +9531,51 @@ It is an error if @var{symbol2} is not defined in the current
 translation unit.
 @end table
 
+@node Diagnostic Pragmas
+@subsection Diagnostic Pragmas
+
+GCC allows the user to selectively enable or disable certain types of
+diagnostics, and change the kind of the diagnostic.  For example, a
+project's policy might require that all sources compile with
+@option{-Werror} but certain files might have exceptions allowing
+specific types of warnings.  Or, a project might selectively enable
+diagnostics and treat them as errors depending on which preprocessor
+macros are defined.
+
+@table @code
+@item #pragma GCC diagnostic @var{kind} @var{option}
+@cindex pragma, diagnostic
+
+Modifies the disposition of a diagnostic.  Note that not all
+diagnostics are modifyiable; at the moment only warnings (normally
+controlled by @samp{-W...}) can be controlled, and not all of them.
+Use @option{-fdiagnostics-show-option} to determine which diagnostics
+are controllable and which option controls them.
+
+@var{kind} is @samp{error} to treat this diagnostic as an error,
+@samp{warning} to treat it like a warning (even if @option{-Werror} is
+in effect), or @samp{ignored} if the diagnostic is to be ignored.
+@var{option} is a double quoted string which matches the command line
+option.
+
+@example
+#pragma GCC diagnostic warning "-Wformat"
+#pragma GCC diagnostic error "-Walways-true"
+#pragma GCC diagnostic ignored "-Walways-true"
+@end example
+
+Note that these pragmas override any command line options.  Also,
+while it is syntactically valid to put these pragmas anywhere in your
+sources, the only supported location for them is before any data or
+functions are defined.  Doing otherwise may result in unpredictable
+results depending on how the optimizer manages your sources.  If the
+same option is listed multiple times, the last one specified is the
+one that is in effect.  This pragma is not intended to be a general
+purpose replacement for command line options, but for implementing
+strict control over project policies.
+
+@end table
+
 @node Unnamed Fields
 @section Unnamed struct/union fields within structs/unions
 @cindex struct
index 629e4a9f4aa1d8ffab9ec803d0f1e512bea7f448..924c121502e2d483ef708b393425a0af92fdd66e 100644 (file)
@@ -1,5 +1,5 @@
 @c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-@c 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+@c 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 @c This is part of the GCC manual.
 @c For copying conditions, see the file gcc.texi.
 
@@ -226,7 +226,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wc++-compat -Wcast-align  -Wcast-qual  -Wchar-subscripts  -Wcomment @gol
 -Wconversion  -Wno-deprecated-declarations @gol
 -Wdisabled-optimization  -Wno-div-by-zero  -Wno-endif-labels @gol
--Werror  -Werror-implicit-function-declaration @gol
+-Werror  -Werror-* -Werror-implicit-function-declaration @gol
 -Wfatal-errors  -Wfloat-equal  -Wformat  -Wformat=2 @gol
 -Wno-format-extra-args -Wformat-nonliteral @gol
 -Wformat-security  -Wformat-y2k @gol
@@ -3411,6 +3411,22 @@ This option is only supported for C and Objective-C@.
 @opindex Werror
 Make all warnings into errors.
 
+@item -Werror=
+@opindex Werror=
+Make the specified warning into an errors.  The specifier for a
+warning is appended, for example @option{-Werror=switch} turns the
+warnings controlled by @option{-Wswitch} into errors.  This switch
+takes a negative form, to be used to negate @option{-Werror} for
+specific warnings, for example @option{-Wno-error=switch} makes
+@option{-Wswitch} warnings not be errors, even when @option{-Werror}
+is in effect.  You can use the @option{-fdiagnostics-show-option}
+option to have each controllable warning amended with the option which
+controls it, to determine what to use with this option.
+
+Note that specifying @option{-Werror=}@var{foo} automatically implies
+@option{-W}@var{foo}.  However, @option{-Wno-error=}@var{foo} does not
+imply anything.
+
 @item -Wstack-protector
 @opindex Wstack-protector
 This option is only active when @option{-fstack-protector} is active.  It
index e264b4abcc3324fcbd6ce96883ec5c0ad3b27fd9..36880862f67efcab9db4032156b2bfd59af2af69 100644 (file)
@@ -1,5 +1,5 @@
 /* Command line option handling.
-   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
 This file is part of GCC.
@@ -102,7 +102,8 @@ const char **in_fnames;
 unsigned num_in_fnames;
 
 static size_t find_opt (const char *, int);
-static int common_handle_option (size_t scode, const char *arg, int value);
+static int common_handle_option (size_t scode, const char *arg, int value,
+                                unsigned int lang_mask);
 static void handle_param (const char *);
 static void set_Wextra (int);
 static unsigned int handle_option (const char **argv, unsigned int lang_mask);
@@ -405,7 +406,7 @@ handle_option (const char **argv, unsigned int lang_mask)
       result = 0;
 
   if (result && (option->flags & CL_COMMON))
-    if (common_handle_option (opt_index, arg, value) == 0)
+    if (common_handle_option (opt_index, arg, value, lang_mask) == 0)
       result = 0;
 
   if (result && (option->flags & CL_TARGET))
@@ -719,7 +720,8 @@ decode_options (unsigned int argc, const char **argv)
    VALUE assigned to a variable, it happens automatically.  */
 
 static int
-common_handle_option (size_t scode, const char *arg, int value)
+common_handle_option (size_t scode, const char *arg, int value,
+                     unsigned int lang_mask)
 {
   enum opt_code code = (enum opt_code) scode;
 
@@ -759,6 +761,32 @@ common_handle_option (size_t scode, const char *arg, int value)
       set_Wextra (value);
       break;
 
+    case OPT_Werror_:
+      {
+       char *new_option;
+       int option_index;
+       new_option = (char *) xmalloc (strlen (arg) + 2);
+       new_option[0] = 'W';
+       strcpy (new_option+1, arg);
+       option_index = find_opt (new_option, lang_mask);
+       if (option_index == N_OPTS)
+         {
+           error("-Werror-%s: No option -%s", arg, new_option);
+         }
+       else
+         {
+           int kind = value ? DK_ERROR : DK_WARNING;
+           diagnostic_classify_diagnostic (global_dc, option_index, kind);
+
+           /* -Werror=foo implies -Wfoo.  */
+           if (cl_options[option_index].var_type == CLVC_BOOLEAN
+               && cl_options[option_index].flag_var
+               && kind == DK_ERROR)
+             *(int *) cl_options[option_index].flag_var = 1;
+         }
+      }
+      break;
+
     case OPT_Wextra:
       set_Wextra (value);
       break;