OSDN Git Service

* diagnostic.h (diagnostic_override_option_index): New macro to
authorsimonb <simonb@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Apr 2010 17:18:10 +0000 (17:18 +0000)
committersimonb <simonb@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 7 Apr 2010 17:18:10 +0000 (17:18 +0000)
set a diagnostic's option_index.
* c-tree.h (c_cpp_error): Add warning reason argument.
* opts.c (_warning_as_error_callback): New.
(register_warning_as_error_callback): Store callback for
warnings enabled via enable_warning_as_error.
(enable_warning_as_error): Call callback, minor code tidy.
* opts.h (register_warning_as_error_callback): Declare.
* c-opts.c (warning_as_error_callback): New, set cpp_opts flag in
response to -Werror=.
(c_common_init_options): Register warning_as_error_callback in opts.c.
* common.opt: Add -Wno-cpp option.
* c-common.c (struct reason_option_codes_t): Map cpp warning
reason codes to gcc option indexes.
* (c_option_controlling_cpp_error): New function, lookup the gcc
option index for a cpp warning reason code.
* (c_cpp_error): Add warning reason argument, call
c_option_controlling_cpp_error for diagnostic_override_option_index.
* doc/invoke.texi: Document -Wno-cpp.

* cpp.c (cb_cpp_error): Add warning reason argument, set a value
for diagnostic_override_option_index if CPP_W_WARNING_DIRECTIVE.

* directives.c (do_diagnostic): Add warning reason argument,
call appropriate error reporting function for code.
(directive_diagnostics): Call specific warning functions with
warning reason where appropriate.
(do_error, do_warning, do_pragma_dependency): Add warning reason
argument to do_diagnostic calls.
* macro.c (_cpp_warn_if_unused_macro, enter_macro_context,
_cpp_create_definition): Call specific warning functions with
        warning reason where appropriate.
* Makefile.in: Add new diagnostic functions to gettext translations.
* include/cpplib.h (struct cpp_callbacks): Add warning reason code
to error callback.
(CPP_DL_WARNING, CPP_DL_WARNING_SYSHDR, CPP_DL_PEDWARN, CPP_DL_ERROR,
CPP_DL_ICE, CPP_DL_NOTE, CPP_DL_FATAL): Replace macros with enums.
(CPP_W_NONE, CPP_W_DEPRECATED, CPP_W_COMMENTS,
CPP_W_MISSING_INCLUDE_DIRS, CPP_W_TRIGRAPHS, CPP_W_MULTICHAR,
CPP_W_TRADITIONAL, CPP_W_LONG_LONG, CPP_W_ENDIF_LABELS,
CPP_W_NUM_SIGN_CHANGE, CPP_W_VARIADIC_MACROS,
CPP_W_BUILTIN_MACRO_REDEFINED, CPP_W_DOLLARS, CPP_W_UNDEF,
CPP_W_UNUSED_MACROS, CPP_W_CXX_OPERATOR_NAMES, CPP_W_NORMALIZE,
CPP_W_INVALID_PCH, CPP_W_WARNING_DIRECTIVE): New enums for cpp
warning reason codes.
(cpp_warning, cpp_pedwarning, cpp_warning_syshdr,
cpp_warning_with_line, cpp_pedwarning_with_line,
cpp_warning_with_line_syshdr): New specific error reporting functions.
* pch.c (cpp_valid_state): Call specific warning functions with
        warning reason where appropriate.
* errors.c (cpp_diagnostic, cpp_diagnostic_with_line): New central
diagnostic handlers.
(cpp_warning, cpp_pedwarning, cpp_warning_syshdr,
cpp_warning_with_line, cpp_pedwarning_with_line,
cpp_warning_with_line_syshdr): New specific error reporting functions.
* expr.c (cpp_classify_number, eval_token, num_unary_op): Call
specific warning functions with warning reason where appropriate.
* lex.c (_cpp_process_line_notes, _cpp_skip_block_comment,
warn_about_normalization, lex_identifier_intern, lex_identifier,
_cpp_lex_direct): Ditto.
* charset.c (_cpp_valid_ucn, convert_hex, convert_escape,
narrow_str_to_charconst): Ditto.

* gcc.dg/cpp/warn-undef-2.c: New.
* gcc.dg/cpp/warn-traditional-2.c: New.
* gcc.dg/cpp/warn-comments-2.c: New.
* gcc.dg/cpp/warning-directive-1.c: New.
* gcc.dg/cpp/warn-long-long.c: New.
* gcc.dg/cpp/warn-traditional.c: New.
* gcc.dg/cpp/warn-variadic-2.c: New.
* gcc.dg/cpp/warn-undef.c: New.
* gcc.dg/cpp/warn-normalized-1.c: New.
* gcc.dg/cpp/warning-directive-2.c: New.
* gcc.dg/cpp/warn-long-long-2.c: New.
* gcc.dg/cpp/warn-variadic.c: New.
* gcc.dg/cpp/warn-normalized-2.c: New.
* gcc.dg/cpp/warning-directive-3.c: New.
* gcc.dg/cpp/warn-deprecated-2.c: New.
* gcc.dg/cpp/warn-trigraphs-1.c: New.
* gcc.dg/cpp/warn-multichar-2.c: New.
* gcc.dg/cpp/warn-normalized-3.c: New.
* gcc.dg/cpp/warning-directive-4.c: New.
* gcc.dg/cpp/warn-unused-macros.c: New.
* gcc.dg/cpp/warn-trigraphs-2.c: New.
* gcc.dg/cpp/warn-cxx-compat-2.c: New.
* gcc.dg/cpp/warn-cxx-compat.c: New.
* gcc.dg/cpp/warn-redefined.c: New.
* gcc.dg/cpp/warn-trigraphs-3.c: New.
* gcc.dg/cpp/warn-unused-macros-2.c: New.
* gcc.dg/cpp/warn-deprecated.c: New.
* gcc.dg/cpp/warn-trigraphs-4.c: New.
* gcc.dg/cpp/warn-redefined-2.c: New.
* gcc.dg/cpp/warn-comments.c: New.
* gcc.dg/cpp/warn-multichar.c: New.
* g++.dg/cpp/warning-directive-1.C: New.
* g++.dg/cpp/warning-directive-2.C: New.
* g++.dg/cpp/warning-directive-3.C: New.
* g++.dg/cpp/warning-directive-4.C: New.
* gfortran.dg/warning-directive-1.F90: New.
* gfortran.dg/warning-directive-3.F90: New.
* gfortran.dg/warning-directive-2.F90: New.
* gfortran.dg/warning-directive-4.F90: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158079 138bc75d-0d04-0410-961f-82ee72b054a4

61 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-opts.c
gcc/c-tree.h
gcc/common.opt
gcc/diagnostic.h
gcc/doc/invoke.texi
gcc/fortran/ChangeLog
gcc/fortran/cpp.c
gcc/opts.c
gcc/opts.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp/warning-directive-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp/warning-directive-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp/warning-directive-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp/warning-directive-4.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-comments-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-comments.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-deprecated.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-long-long.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-multichar.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-redefined.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-traditional.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-undef-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-undef.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-variadic.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warning-directive-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warning-directive-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warning-directive-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warning-directive-4.c [new file with mode: 0644]
gcc/testsuite/gfortran.dg/warning-directive-1.F90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/warning-directive-2.F90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/warning-directive-3.F90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/warning-directive-4.F90 [new file with mode: 0644]
libcpp/ChangeLog
libcpp/Makefile.in
libcpp/charset.c
libcpp/directives.c
libcpp/errors.c
libcpp/expr.c
libcpp/include/cpplib.h
libcpp/lex.c
libcpp/macro.c
libcpp/pch.c

index 693d69d..2a6c593 100644 (file)
@@ -1,3 +1,25 @@
+2010-04-07  Simon Baldwin  <simonb@google.com>
+
+       * diagnostic.h (diagnostic_override_option_index): New macro to
+       set a diagnostic's option_index.
+       * c-tree.h (c_cpp_error): Add warning reason argument.
+       * opts.c (_warning_as_error_callback): New.
+       (register_warning_as_error_callback): Store callback for
+       warnings enabled via enable_warning_as_error.
+       (enable_warning_as_error): Call callback, minor code tidy.
+       * opts.h (register_warning_as_error_callback): Declare.
+       * c-opts.c (warning_as_error_callback): New, set cpp_opts flag in
+       response to -Werror=.
+       (c_common_init_options): Register warning_as_error_callback in opts.c.
+       * common.opt: Add -Wno-cpp option.
+       * c-common.c (struct reason_option_codes_t): Map cpp warning
+       reason codes to gcc option indexes.
+       * (c_option_controlling_cpp_error): New function, lookup the gcc
+       option index for a cpp warning reason code.
+       * (c_cpp_error): Add warning reason argument, call
+       c_option_controlling_cpp_error for diagnostic_override_option_index.
+       * doc/invoke.texi: Document -Wno-cpp.
+
 2010-04-07  Richard Guenther  <rguenther@suse.de>
 
        * ipa-reference.c (mark_load): Use get_base_address.
index 66034a9..7daba6b 100644 (file)
@@ -8253,8 +8253,52 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
 #undef catenate_messages
 }
 
+/* Mapping for cpp message reasons to the options that enable them.  */
+
+struct reason_option_codes_t
+{
+  const int reason;            /* cpplib message reason.  */
+  const int option_code;       /* gcc option that controls this message.  */
+};
+
+static const struct reason_option_codes_t option_codes[] = {
+  {CPP_W_DEPRECATED,                   OPT_Wdeprecated},
+  {CPP_W_COMMENTS,                     OPT_Wcomments},
+  {CPP_W_TRIGRAPHS,                    OPT_Wtrigraphs},
+  {CPP_W_MULTICHAR,                    OPT_Wmultichar},
+  {CPP_W_TRADITIONAL,                  OPT_Wtraditional},
+  {CPP_W_LONG_LONG,                    OPT_Wlong_long},
+  {CPP_W_ENDIF_LABELS,                 OPT_Wendif_labels},
+  {CPP_W_VARIADIC_MACROS,              OPT_Wvariadic_macros},
+  {CPP_W_BUILTIN_MACRO_REDEFINED,      OPT_Wbuiltin_macro_redefined},
+  {CPP_W_UNDEF,                                OPT_Wundef},
+  {CPP_W_UNUSED_MACROS,                        OPT_Wunused_macros},
+  {CPP_W_CXX_OPERATOR_NAMES,           OPT_Wc___compat},
+  {CPP_W_NORMALIZE,                    OPT_Wnormalized_},
+  {CPP_W_INVALID_PCH,                  OPT_Winvalid_pch},
+  {CPP_W_WARNING_DIRECTIVE,            OPT_Wcpp},
+  {CPP_W_NONE,                         0}
+};
+
+/* Return the gcc option code associated with the reason for a cpp
+   message, or 0 if none.  */
+
+static int
+c_option_controlling_cpp_error (int reason)
+{
+  const struct reason_option_codes_t *entry;
+
+  for (entry = option_codes; entry->reason != CPP_W_NONE; entry++)
+    {
+      if (entry->reason == reason)
+       return entry->option_code;
+    }
+  return 0;
+}
+
 /* Callback from cpp_error for PFILE to print diagnostics from the
-   preprocessor.  The diagnostic is of type LEVEL, at location
+   preprocessor.  The diagnostic is of type LEVEL, with REASON set
+   to the reason code if LEVEL is represents a warning, at location
    LOCATION unless this is after lexing and the compiler's location
    should be used instead, with column number possibly overridden by
    COLUMN_OVERRIDE if not zero; MSG is the translated message and AP
@@ -8262,7 +8306,7 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
    otherwise.  */
 
 bool
-c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
+c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
             location_t location, unsigned int column_override,
             const char *msg, va_list *ap)
 {
@@ -8309,6 +8353,8 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
                                  location, dlevel);
   if (column_override)
     diagnostic_override_column (&diagnostic, column_override);
+  diagnostic_override_option_index (&diagnostic,
+                                    c_option_controlling_cpp_error (reason));
   ret = report_diagnostic (&diagnostic);
   if (level == CPP_DL_WARNING_SYSHDR)
     warn_system_headers = save_warn_system_headers;
index 9d5fa2e..a680f2d 100644 (file)
@@ -196,6 +196,90 @@ defer_opt (enum opt_code code, const char *arg)
   deferred_count++;
 }
 
+/* -Werror= may set a warning option to enable a warning that is emitted
+   by the preprocessor.  Set any corresponding flag in cpp_opts.  */
+
+static void
+warning_as_error_callback (int option_index)
+{
+  switch (option_index)
+    {
+      default:
+       /* Ignore options not associated with the preprocessor.  */
+       break;
+
+      case OPT_Wdeprecated:
+       cpp_opts->warn_deprecated = 1;
+       break;
+
+      case OPT_Wcomment:
+      case OPT_Wcomments:
+       cpp_opts->warn_comments = 1;
+       break;
+
+      case OPT_Wtrigraphs:
+       cpp_opts->warn_trigraphs = 1;
+       break;
+
+      case OPT_Wmultichar:
+       cpp_opts->warn_multichar = 1;
+       break;
+
+      case OPT_Wtraditional:
+       cpp_opts->warn_traditional = 1;
+       break;
+
+      case OPT_Wlong_long:
+       cpp_opts->warn_long_long = 1;
+       break;
+
+      case OPT_Wendif_labels:
+       cpp_opts->warn_endif_labels = 1;
+       break;
+
+      case OPT_Wvariadic_macros:
+       /* Set the local flag that is used later to update cpp_opts.  */
+       warn_variadic_macros = 1;
+       break;
+
+      case OPT_Wbuiltin_macro_redefined:
+       cpp_opts->warn_builtin_macro_redefined = 1;
+       break;
+
+      case OPT_Wundef:
+       cpp_opts->warn_undef = 1;
+       break;
+
+      case OPT_Wunused_macros:
+       /* Set the local flag that is used later to update cpp_opts.  */
+       warn_unused_macros = 1;
+       break;
+
+      case OPT_Wc___compat:
+       /* Add warnings in the same way as c_common_handle_option below.  */
+       if (warn_enum_compare == -1)
+         warn_enum_compare = 1;
+       if (warn_jump_misses_init == -1)
+         warn_jump_misses_init = 1;
+       cpp_opts->warn_cxx_operator_names = 1;
+       break;
+
+      case OPT_Wnormalized_:
+       inform (input_location, "-Werror=normalized=: Set -Wnormalized=nfc");
+       cpp_opts->warn_normalize = normalized_C;
+       break;
+
+      case OPT_Winvalid_pch:
+       cpp_opts->warn_invalid_pch = 1;
+       break;
+
+      case OPT_Wcpp:
+       /* Handled by standard diagnostics using the option's associated
+          boolean variable.  */
+       break;
+    }
+}
+
 /* Common initialization before parsing options.  */
 unsigned int
 c_common_init_options (unsigned int argc, const char **argv)
@@ -204,6 +288,9 @@ c_common_init_options (unsigned int argc, const char **argv)
   unsigned int i, result;
   struct cpp_callbacks *cb;
 
+  /* Register callback for warnings enabled by -Werror=.  */
+  register_warning_as_error_callback (warning_as_error_callback);
+
   /* This is conditionalized only because that is the way the front
      ends used to do it.  Maybe this should be unconditional?  */
   if (c_dialect_cxx ())
index 2309d51..dab9d39 100644 (file)
@@ -608,8 +608,8 @@ extern void c_write_global_declarations (void);
 extern void pedwarn_c90 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(3,4);
 extern void pedwarn_c99 (location_t, int opt, const char *, ...) ATTRIBUTE_GCC_CDIAG(3,4);
 
-extern bool c_cpp_error (cpp_reader *, int, location_t, unsigned int,
+extern bool c_cpp_error (cpp_reader *, int, int, location_t, unsigned int,
                         const char *, va_list *)
-     ATTRIBUTE_GCC_CDIAG(5,0);
+     ATTRIBUTE_GCC_CDIAG(6,0);
 
 #endif /* ! GCC_C_TREE_H */
index 2b8b6d7..49eb453 100644 (file)
@@ -89,6 +89,10 @@ Wcast-align
 Common Var(warn_cast_align) Warning
 Warn about pointer casts which increase alignment
 
+Wcpp
+Common Var(warn_cpp) Init(1) Warning
+Warn when a #warning directive is encountered
+
 Wdeprecated-declarations
 Common Var(warn_deprecated_decl) Init(1) Warning
 Warn about uses of __attribute__((deprecated)) declarations
index 78c19e9..de76477 100644 (file)
@@ -199,6 +199,11 @@ extern diagnostic_context *global_dc;
    diagnostic.  */
 #define diagnostic_override_column(DI, COL) (DI)->override_column = (COL)
 
+/* Override the option index to be used for reporting a
+   diagnostic.  */
+#define diagnostic_override_option_index(DI, OPTIDX) \
+    ((DI)->option_index = (OPTIDX))
+
 /* Diagnostic related functions.  */
 extern void diagnostic_initialize (diagnostic_context *);
 extern void diagnostic_report_current_module (diagnostic_context *);
index 76c4240..d356daa 100644 (file)
@@ -232,7 +232,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wno-attributes -Wno-builtin-macro-redefined @gol
 -Wc++-compat -Wc++0x-compat -Wcast-align  -Wcast-qual  @gol
 -Wchar-subscripts -Wclobbered  -Wcomment @gol
--Wconversion  -Wcoverage-mismatch  -Wno-deprecated  @gol
+-Wconversion  -Wcoverage-mismatch  -Wcpp  -Wno-deprecated  @gol
 -Wno-deprecated-declarations -Wdisabled-optimization  @gol
 -Wno-div-by-zero -Wempty-body  -Wenum-compare -Wno-endif-labels @gol
 -Werror  -Werror=* @gol
@@ -2973,6 +2973,11 @@ Warn whenever a comment-start sequence @samp{/*} appears in a @samp{/*}
 comment, or whenever a Backslash-Newline appears in a @samp{//} comment.
 This warning is enabled by @option{-Wall}.
 
+@item -Wno-cpp \
+@r{(C, Objective-C, C++, Objective-C++ and Fortran only)}
+
+Suppress warning messages emitted by @code{#warning} directives.
+
 @item -Wformat
 @opindex Wformat
 @opindex Wno-format
index 2b1aa30..6502b89 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-07  Simon Baldwin  <simonb@google.com>
+
+       * cpp.c (cb_cpp_error): Add warning reason argument, set a value
+       for diagnostic_override_option_index if CPP_W_WARNING_DIRECTIVE.
+
 2010-04-07  Richard Guenther  <rguenther@suse.de>
 
        * options.c (gfc_init_options): Do not set.
index ec8bb59..6ff464a 100644 (file)
@@ -137,9 +137,9 @@ static void cb_include (cpp_reader *, source_location, const unsigned char *,
 static void cb_ident (cpp_reader *, source_location, const cpp_string *);
 static void cb_used_define (cpp_reader *, source_location, cpp_hashnode *);
 static void cb_used_undef (cpp_reader *, source_location, cpp_hashnode *);
-static bool cb_cpp_error (cpp_reader *, int, location_t, unsigned int,
+static bool cb_cpp_error (cpp_reader *, int, int, location_t, unsigned int,
                          const char *, va_list *)
-     ATTRIBUTE_GCC_DIAG(5,0);
+     ATTRIBUTE_GCC_DIAG(6,0);
 void pp_dir_change (cpp_reader *, const char *);
 
 static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
@@ -962,13 +962,14 @@ cb_used_define (cpp_reader *pfile, source_location line ATTRIBUTE_UNUSED,
 }
 
 /* Callback from cpp_error for PFILE to print diagnostics from the
-   preprocessor.  The diagnostic is of type LEVEL, at location
+   preprocessor.  The diagnostic is of type LEVEL, with REASON set
+   to the reason code if LEVEL is represents a warning, at location
    LOCATION, with column number possibly overridden by COLUMN_OVERRIDE
    if not zero; MSG is the translated message and AP the arguments.
    Returns true if a diagnostic was emitted, false otherwise.  */
 
 static bool
-cb_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
+cb_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level, int reason,
              location_t location, unsigned int column_override,
              const char *msg, va_list *ap)
 {
@@ -1007,6 +1008,8 @@ cb_cpp_error (cpp_reader *pfile ATTRIBUTE_UNUSED, int level,
                                  location, dlevel);
   if (column_override)
     diagnostic_override_column (&diagnostic, column_override);
+  if (reason == CPP_W_WARNING_DIRECTIVE)
+    diagnostic_override_option_index (&diagnostic, OPT_Wcpp);
   ret = report_diagnostic (&diagnostic);
   if (level == CPP_DL_WARNING_SYSHDR)
     warn_system_headers = save_warn_system_headers;
@@ -1090,5 +1093,3 @@ dump_queued_macros (cpp_reader *pfile ATTRIBUTE_UNUSED)
     }
   cpp_undefine_queue = NULL;
 }
-
-
index 7c928bb..19d5634 100644 (file)
@@ -2396,6 +2396,20 @@ set_option (const struct cl_option *option, int value, const char *arg)
     }
 }
 
+
+/* Callback function, called when -Werror= enables a warning.  */
+
+static void (*warning_as_error_callback) (int) = NULL;
+
+/* Register a callback for enable_warning_as_error calls.  */
+
+void
+register_warning_as_error_callback (void (*callback) (int))
+{
+  gcc_assert (warning_as_error_callback == NULL || callback == NULL);
+  warning_as_error_callback = callback;
+}
+
 /* Enable a warning option as an error.  This is used by -Werror= and
    also by legacy Werror-implicit-function-declaration.  */
 
@@ -2415,14 +2429,20 @@ enable_warning_as_error (const char *arg, int value, unsigned int lang_mask)
     }
   else
     {
-      diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
+      const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
+
       diagnostic_classify_diagnostic (global_dc, option_index, kind);
+      if (kind == DK_ERROR)
+       {
+         const struct cl_option * const option = cl_options + option_index;
+
+         /* -Werror=foo implies -Wfoo.  */
+         if (option->var_type == CLVC_BOOLEAN && option->flag_var)
+           *(int *) option->flag_var = 1;
 
-      /* -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;
+         if (warning_as_error_callback)
+           warning_as_error_callback (option_index);
+       }
     }
   free (new_option);
 }
index a2eef19..54f57d1 100644 (file)
@@ -105,6 +105,7 @@ extern int option_enabled (int opt_idx);
 extern bool get_option_state (int, struct cl_option_state *);
 extern void set_option (const struct cl_option *, int, const char *);
 
+extern void register_warning_as_error_callback (void (*callback) (int));
 extern void enable_warning_as_error (const char *arg, int value,
                                     unsigned int lang_mask);
 extern void print_ignored_options (void);
index a074ef2..8168478 100644 (file)
@@ -1,6 +1,47 @@
-2010-04-07  Iain Sandoe <iains@gcc.gnu.org>
+2010-04-07  Simon Baldwin  <simonb@google.com>
+
+       * gcc.dg/cpp/warn-undef-2.c: New.
+       * gcc.dg/cpp/warn-traditional-2.c: New.
+       * gcc.dg/cpp/warn-comments-2.c: New.
+       * gcc.dg/cpp/warning-directive-1.c: New.
+       * gcc.dg/cpp/warn-long-long.c: New.
+       * gcc.dg/cpp/warn-traditional.c: New.
+       * gcc.dg/cpp/warn-variadic-2.c: New.
+       * gcc.dg/cpp/warn-undef.c: New.
+       * gcc.dg/cpp/warn-normalized-1.c: New.
+       * gcc.dg/cpp/warning-directive-2.c: New.
+       * gcc.dg/cpp/warn-long-long-2.c: New.
+       * gcc.dg/cpp/warn-variadic.c: New.
+       * gcc.dg/cpp/warn-normalized-2.c: New.
+       * gcc.dg/cpp/warning-directive-3.c: New.
+       * gcc.dg/cpp/warn-deprecated-2.c: New.
+       * gcc.dg/cpp/warn-trigraphs-1.c: New.
+       * gcc.dg/cpp/warn-multichar-2.c: New.
+       * gcc.dg/cpp/warn-normalized-3.c: New.
+       * gcc.dg/cpp/warning-directive-4.c: New.
+       * gcc.dg/cpp/warn-unused-macros.c: New.
+       * gcc.dg/cpp/warn-trigraphs-2.c: New.
+       * gcc.dg/cpp/warn-cxx-compat-2.c: New.
+       * gcc.dg/cpp/warn-cxx-compat.c: New.
+       * gcc.dg/cpp/warn-redefined.c: New.
+       * gcc.dg/cpp/warn-trigraphs-3.c: New.
+       * gcc.dg/cpp/warn-unused-macros-2.c: New.
+       * gcc.dg/cpp/warn-deprecated.c: New.
+       * gcc.dg/cpp/warn-trigraphs-4.c: New.
+       * gcc.dg/cpp/warn-redefined-2.c: New.
+       * gcc.dg/cpp/warn-comments.c: New.
+       * gcc.dg/cpp/warn-multichar.c: New.
+       * g++.dg/cpp/warning-directive-1.C: New.
+       * g++.dg/cpp/warning-directive-2.C: New.
+       * g++.dg/cpp/warning-directive-3.C: New.
+       * g++.dg/cpp/warning-directive-4.C: New.
+       * gfortran.dg/warning-directive-1.F90: New.
+       * gfortran.dg/warning-directive-3.F90: New.
+       * gfortran.dg/warning-directive-2.F90: New.
+       * gfortran.dg/warning-directive-4.F90: New.
 
-       PR objc++/23716
+2010-04-07  Iain Sandoe <iains@gcc.gnu.org>
+PR objc++/23716
        * obj-c++.dg/comp-types-10.mm: Remove XFAIL.
 
 2010-04-07  Jason Merrill  <jason@redhat.com>
diff --git a/gcc/testsuite/g++.dg/cpp/warning-directive-1.C b/gcc/testsuite/g++.dg/cpp/warning-directive-1.C
new file mode 100644 (file)
index 0000000..1ce18c6
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-fdiagnostics-show-option" }
+
+#warning "Printed"  // { dg-warning "\"Printed\" .-Wcpp." }
diff --git a/gcc/testsuite/g++.dg/cpp/warning-directive-2.C b/gcc/testsuite/g++.dg/cpp/warning-directive-2.C
new file mode 100644 (file)
index 0000000..abd6427
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-fdiagnostics-show-option -Werror=cpp" }
+
+#warning "Printed"  // { dg-error "\"Printed\" .-Wcpp." }
diff --git a/gcc/testsuite/g++.dg/cpp/warning-directive-3.C b/gcc/testsuite/g++.dg/cpp/warning-directive-3.C
new file mode 100644 (file)
index 0000000..8ed66c6
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-fdiagnostics-show-option -Werror -Wno-error=cpp" }
+
+#warning "Printed"  // { dg-warning "\"Printed\" .-Wcpp." }
diff --git a/gcc/testsuite/g++.dg/cpp/warning-directive-4.C b/gcc/testsuite/g++.dg/cpp/warning-directive-4.C
new file mode 100644 (file)
index 0000000..a5db1b4
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-fdiagnostics-show-option -Wno-cpp" }
+
+#warning "Not printed"  // { dg-bogus "." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-comments-2.c b/gcc/testsuite/gcc.dg/cpp/warn-comments-2.c
new file mode 100644 (file)
index 0000000..5a17f2b
--- /dev/null
@@ -0,0 +1,7 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=comments" }
+
+/* /* */  // { dg-error "\"\.\*\" within comment .-Wcomments." }
+
+// \
+          // { dg-error "multi-line comment .-Wcomments." "multi-line" { target *-*-* } 6 }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-comments.c b/gcc/testsuite/gcc.dg/cpp/warn-comments.c
new file mode 100644 (file)
index 0000000..6f3d5a5
--- /dev/null
@@ -0,0 +1,7 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wcomments" }
+
+/* /* */  // { dg-warning "\"\.\*\" within comment .-Wcomments." }
+
+// \
+          // { dg-warning "multi-line comment .-Wcomments." "multi-line" { target *-*-* } 6 }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c b/gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c
new file mode 100644 (file)
index 0000000..6bf7d55
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=c++-compat" }
+
+#define not !  // { dg-error "identifier \"not\" is a special operator name in C\\+\\+ .-Wc\\+\\+-compat." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c b/gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c
new file mode 100644 (file)
index 0000000..2e7b259
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wc++-compat" }
+
+#define not !  // { dg-warning "identifier \"not\" is a special operator name in C\\+\\+ .-Wc\\+\\+-compat." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c b/gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c
new file mode 100644 (file)
index 0000000..b9cfffb
--- /dev/null
@@ -0,0 +1,7 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=deprecated" }
+
+#assert x(x)  // { dg-error "#assert is a deprecated GCC extension .-Wdeprecated." }
+
+#if #x(x)     // { dg-error "assertions are a deprecated extension .-Wdeprecated." }
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-deprecated.c b/gcc/testsuite/gcc.dg/cpp/warn-deprecated.c
new file mode 100644 (file)
index 0000000..84214b1
--- /dev/null
@@ -0,0 +1,7 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wdeprecated" }
+
+#assert x(x)  // { dg-warning "#assert is a deprecated GCC extension .-Wdeprecated." }
+
+#if #x(x)     // { dg-warning "assertions are a deprecated extension .-Wdeprecated." }
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c b/gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c
new file mode 100644 (file)
index 0000000..11eb5fb
--- /dev/null
@@ -0,0 +1,6 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wtraditional -Werror=long-long" }
+
+#if 0LL  // { dg-error "traditional C rejects the \"LL\" suffix .-Wlong-long." }
+         // { dg-error "use of C99 long long integer constant .-Wlong-long." "use long long" { target *-*-* } 4 }
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-long-long.c b/gcc/testsuite/gcc.dg/cpp/warn-long-long.c
new file mode 100644 (file)
index 0000000..e86f9a6
--- /dev/null
@@ -0,0 +1,6 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wtraditional -Wlong-long" }
+
+#if 0LL  // { dg-warning "traditional C rejects the \"LL\" suffix .-Wlong-long." }
+         // { dg-warning "use of C99 long long integer constant .-Wlong-long." "use long long" { target *-*-* } 4 }
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c b/gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c
new file mode 100644 (file)
index 0000000..31d33bb
--- /dev/null
@@ -0,0 +1,5 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=multichar" }
+
+#if 'abc'  // { dg-error "multi-character character constant .-Wmultichar." }
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-multichar.c b/gcc/testsuite/gcc.dg/cpp/warn-multichar.c
new file mode 100644 (file)
index 0000000..f5b02da
--- /dev/null
@@ -0,0 +1,5 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wmultichar" }
+
+#if 'abc'  // { dg-warning "multi-character character constant .-Wmultichar." }
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c b/gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c
new file mode 100644 (file)
index 0000000..fe1c575
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -fextended-identifiers -Wnormalized=nfc" }
+
+\u0F43  // { dg-warning "`.U00000f43' is not in NFC .-Wnormalized=." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c b/gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c
new file mode 100644 (file)
index 0000000..f1fb968
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -fextended-identifiers -Wnormalized=nfkc" }
+
+\u00AA  // { dg-warning "`.U000000aa' is not in NFKC .-Wnormalized=." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c b/gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c
new file mode 100644 (file)
index 0000000..380c670
--- /dev/null
@@ -0,0 +1,5 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -fextended-identifiers -Werror=normalized=" }
+
+        // { dg-prune-output ".*-Werror=normalized=: Set -Wnormalized=nfc.*" }
+\u0F43  // { dg-error "`.U00000f43' is not in NFC .-Wnormalized=." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c b/gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c
new file mode 100644 (file)
index 0000000..83cc3df
--- /dev/null
@@ -0,0 +1,18 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=builtin-macro-redefined" }
+
+#ifndef __TIME__
+#error "__TIME__ builtin is not defined"
+// { dg-bogus "__TIME__ builtin is not defined" "no-time" { target *-*-* } 5 }
+#endif
+
+#define __TIME__ "X"  // { dg-error "\"__TIME__\" redefined .-Wbuiltin-macro-redefined." }
+
+#define __TIME__ "Y"  // { dg-bogus "-Wbuiltin-macro-redefined" }
+                      // { dg-warning "\"__TIME__\" redefined" "not-builtin-1" { target *-*-* } 11 }
+                      // { dg-message "previous definition" "previous-1" { target *-*-* } 9 }
+
+#define X "X"
+#define X "Y"         // { dg-bogus "-Wbuiltin-macro-redefined" }
+                      // { dg-warning "\"X\" redefined" "not-builtin-2" { target *-*-* } 16 }
+                      // { dg-message "previous definition" "previous-2" { target *-*-* } 15 }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-redefined.c b/gcc/testsuite/gcc.dg/cpp/warn-redefined.c
new file mode 100644 (file)
index 0000000..1d3e7fc
--- /dev/null
@@ -0,0 +1,18 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wbuiltin-macro-redefined" }
+
+#ifndef __TIME__
+#error "__TIME__ builtin is not defined"
+// { dg-bogus "__TIME__ builtin is not defined" "no-time" { target *-*-* } 5 }
+#endif
+
+#define __TIME__ "X"  // { dg-warning "\"__TIME__\" redefined .-Wbuiltin-macro-redefined." }
+
+#define __TIME__ "Y"  // { dg-bogus "-Wbuiltin-macro-redefined" }
+                      // { dg-warning "\"__TIME__\" redefined" "not-builtin-1" { target *-*-* } 11 }
+                      // { dg-message "previous definition" "previous-1" { target *-*-* } 9 }
+
+#define X "X"
+#define X "Y"         // { dg-bogus "-Wbuiltin-macro-redefined" }
+                      // { dg-warning "\"X\" redefined" "not-builtin-2" { target *-*-* } 16 }
+                      // { dg-message "previous definition" "previous-2" { target *-*-* } 15 }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c b/gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c
new file mode 100644 (file)
index 0000000..cb5f690
--- /dev/null
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=traditional -Wno-deprecated -Wno-long-long" }
+
+#assert x(x)         // { dg-error "suggest hiding #assert from traditional C with an indented # .-Wtraditional." }
+
+ #define X X         // { dg-error "traditional C ignores #define with the # indented .-Wtraditional." }
+
+#if 0
+#elif 1              // { dg-error "suggest not using #elif in traditional C .-Wtraditional." }
+#endif
+
+#define f(X) X
+int f;               // { dg-error "function-like macro \"f\" must be used with arguments in traditional C .-Wtraditional." }
+
+#if 0U               // { dg-error "traditional C rejects the \"U\" suffix .-Wtraditional." }
+#endif
+
+#if +1               // { dg-error " traditional C rejects the unary plus operator .-Wtraditional." }
+#endif
+
+char *x = "\x0";     // { dg-error "the meaning of '.x' is different in traditional C .-Wtraditional." }
+char *y = "\a";      // { dg-error "the meaning of '.a' is different in traditional C .-Wtraditional." }
+char *z = "\u0F43";  // { dg-error "the meaning of '.u' is different in traditional C .-Wtraditional." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-traditional.c b/gcc/testsuite/gcc.dg/cpp/warn-traditional.c
new file mode 100644 (file)
index 0000000..f72f6db
--- /dev/null
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wtraditional -Wno-deprecated -Wno-long-long" }
+
+#assert x(x)         // { dg-warning "suggest hiding #assert from traditional C with an indented # .-Wtraditional." }
+
+ #define X X         // { dg-warning "traditional C ignores #define with the # indented .-Wtraditional." }
+
+#if 0
+#elif 1              // { dg-warning "suggest not using #elif in traditional C .-Wtraditional." }
+#endif
+
+#define f(X) X
+int f;               // { dg-warning "function-like macro \"f\" must be used with arguments in traditional C .-Wtraditional." }
+
+#if 0U               // { dg-warning "traditional C rejects the \"U\" suffix .-Wtraditional." }
+#endif
+
+#if +1               // { dg-warning " traditional C rejects the unary plus operator .-Wtraditional." }
+#endif
+
+char *x = "\x0";     // { dg-warning "the meaning of '.x' is different in traditional C .-Wtraditional." }
+char *y = "\a";      // { dg-warning "the meaning of '.a' is different in traditional C .-Wtraditional." }
+char *z = "\u0F43";  // { dg-warning "the meaning of '.u' is different in traditional C .-Wtraditional." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c b/gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c
new file mode 100644 (file)
index 0000000..4f3779d
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -trigraphs -Wtrigraphs" }
+
+??=  // { dg-warning "trigraph \\?\\?= converted to # .-Wtrigraphs." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c b/gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c
new file mode 100644 (file)
index 0000000..ff87ae5
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wtrigraphs" }
+
+??=  // { dg-warning "trigraph \\?\\?= ignored, use -trigraphs to enable .-Wtrigraphs." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c b/gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c
new file mode 100644 (file)
index 0000000..a993e2a
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -trigraphs -Werror=trigraphs" }
+
+??=  // { dg-error "trigraph \\?\\?= converted to # .-Wtrigraphs." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c b/gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c
new file mode 100644 (file)
index 0000000..240ae0f
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=trigraphs" }
+
+??=  // { dg-error "trigraph \\?\\?= ignored, use -trigraphs to enable .-Wtrigraphs." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-undef-2.c b/gcc/testsuite/gcc.dg/cpp/warn-undef-2.c
new file mode 100644 (file)
index 0000000..4eb80e0
--- /dev/null
@@ -0,0 +1,5 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=undef" }
+
+#if x  // { dg-error "\"x\" is not defined .-Wundef." }
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-undef.c b/gcc/testsuite/gcc.dg/cpp/warn-undef.c
new file mode 100644 (file)
index 0000000..dd4524d
--- /dev/null
@@ -0,0 +1,5 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wundef" }
+
+#if x  // { dg-warning "\"x\" is not defined .-Wundef." }
+#endif
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c b/gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c
new file mode 100644 (file)
index 0000000..58eeebf
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=unused-macros" }
+
+#define X X  // { dg-error "macro \"X\" is not used .-Wunused-macros." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c b/gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c
new file mode 100644 (file)
index 0000000..e1ce94e
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wunused-macros" }
+
+#define X X  // { dg-warning "macro \"X\" is not used .-Wunused-macros." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c b/gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c
new file mode 100644 (file)
index 0000000..f43d96a
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do preprocess } */
+/* { dg-options "-ansi -fdiagnostics-show-option -pedantic -Werror=variadic-macros" } */
+
+#define F(...) X   /* { dg-error "anonymous variadic macros were introduced in C99 .-Wvariadic-macros." } */
+
+#define G(X...) X  /* { dg-error "ISO C does not permit named variadic macros .-Wvariadic-macros." } */
diff --git a/gcc/testsuite/gcc.dg/cpp/warn-variadic.c b/gcc/testsuite/gcc.dg/cpp/warn-variadic.c
new file mode 100644 (file)
index 0000000..ba66c90
--- /dev/null
@@ -0,0 +1,6 @@
+/* { dg-do preprocess } */
+/* { dg-options "-ansi -fdiagnostics-show-option -pedantic -Wvariadic-macros" } */
+
+#define F(...) X   /* { dg-warning "anonymous variadic macros were introduced in C99 .-Wvariadic-macros." } */
+
+#define G(X...) X  /* { dg-warning "ISO C does not permit named variadic macros .-Wvariadic-macros." } */
diff --git a/gcc/testsuite/gcc.dg/cpp/warning-directive-1.c b/gcc/testsuite/gcc.dg/cpp/warning-directive-1.c
new file mode 100644 (file)
index 0000000..cb4bd32
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option" }
+
+#warning "Printed"  // { dg-warning "\"Printed\" .-Wcpp." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warning-directive-2.c b/gcc/testsuite/gcc.dg/cpp/warning-directive-2.c
new file mode 100644 (file)
index 0000000..0889803
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=cpp" }
+
+#warning "Printed"  // { dg-error "\"Printed\" .-Wcpp." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warning-directive-3.c b/gcc/testsuite/gcc.dg/cpp/warning-directive-3.c
new file mode 100644 (file)
index 0000000..48c97f3
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror -Wno-error=cpp" }
+
+#warning "Printed"  // { dg-warning "\"Printed\" .-Wcpp." }
diff --git a/gcc/testsuite/gcc.dg/cpp/warning-directive-4.c b/gcc/testsuite/gcc.dg/cpp/warning-directive-4.c
new file mode 100644 (file)
index 0000000..2eb1017
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-do preprocess }
+// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wno-cpp" }
+
+#warning "Not printed"  // { dg-bogus "." }
diff --git a/gcc/testsuite/gfortran.dg/warning-directive-1.F90 b/gcc/testsuite/gfortran.dg/warning-directive-1.F90
new file mode 100644 (file)
index 0000000..5f59315
--- /dev/null
@@ -0,0 +1,5 @@
+! { dg-do preprocess }
+! { dg-options "-std=f95 -fdiagnostics-show-option" }
+
+#warning "Printed"
+! { dg-warning "\"Printed\" .-Wcpp." "" { target *-*-* } 4 }
diff --git a/gcc/testsuite/gfortran.dg/warning-directive-2.F90 b/gcc/testsuite/gfortran.dg/warning-directive-2.F90
new file mode 100644 (file)
index 0000000..75b78bf
--- /dev/null
@@ -0,0 +1,5 @@
+! { dg-do preprocess }
+! { dg-options "-std=f95 -fdiagnostics-show-option -Werror=cpp" }
+
+#warning "Printed"
+! { dg-error "\"Printed\" .-Wcpp." "" { target *-*-* } 4 }
diff --git a/gcc/testsuite/gfortran.dg/warning-directive-3.F90 b/gcc/testsuite/gfortran.dg/warning-directive-3.F90
new file mode 100644 (file)
index 0000000..aa20c19
--- /dev/null
@@ -0,0 +1,5 @@
+! { dg-do preprocess }
+! { dg-options "-std=f95 -fdiagnostics-show-option -Werror -Wno-error=cpp" }
+
+#warning "Printed"
+! { dg-warning "\"Printed\" .-Wcpp." "" { target *-*-* } 4 }
diff --git a/gcc/testsuite/gfortran.dg/warning-directive-4.F90 b/gcc/testsuite/gfortran.dg/warning-directive-4.F90
new file mode 100644 (file)
index 0000000..a5c3811
--- /dev/null
@@ -0,0 +1,5 @@
+! { dg-do preprocess }
+! { dg-options "-std=f95 -fdiagnostics-show-option -Wno-cpp" }
+
+#warning "Not printed"
+! { dg-bogus "." "" { target *-*-* } 4 }
index b55d255..7762099 100644 (file)
@@ -1,3 +1,45 @@
+2010-04-07  Simon Baldwin  <simonb@google.com>
+
+       * directives.c (do_diagnostic): Add warning reason argument,
+       call appropriate error reporting function for code.
+       (directive_diagnostics): Call specific warning functions with
+       warning reason where appropriate.
+       (do_error, do_warning, do_pragma_dependency): Add warning reason
+       argument to do_diagnostic calls.
+       * macro.c (_cpp_warn_if_unused_macro, enter_macro_context,
+       _cpp_create_definition): Call specific warning functions with
+       warning reason where appropriate.
+       * Makefile.in: Add new diagnostic functions to gettext translations.
+       * include/cpplib.h (struct cpp_callbacks): Add warning reason code
+       to error callback.
+       (CPP_DL_WARNING, CPP_DL_WARNING_SYSHDR, CPP_DL_PEDWARN, CPP_DL_ERROR,
+       CPP_DL_ICE, CPP_DL_NOTE, CPP_DL_FATAL): Replace macros with enums.
+       (CPP_W_NONE, CPP_W_DEPRECATED, CPP_W_COMMENTS,
+       CPP_W_MISSING_INCLUDE_DIRS, CPP_W_TRIGRAPHS, CPP_W_MULTICHAR,
+       CPP_W_TRADITIONAL, CPP_W_LONG_LONG, CPP_W_ENDIF_LABELS,
+       CPP_W_NUM_SIGN_CHANGE, CPP_W_VARIADIC_MACROS,
+       CPP_W_BUILTIN_MACRO_REDEFINED, CPP_W_DOLLARS, CPP_W_UNDEF,
+       CPP_W_UNUSED_MACROS, CPP_W_CXX_OPERATOR_NAMES, CPP_W_NORMALIZE,
+       CPP_W_INVALID_PCH, CPP_W_WARNING_DIRECTIVE): New enums for cpp
+       warning reason codes.
+       (cpp_warning, cpp_pedwarning, cpp_warning_syshdr,
+       cpp_warning_with_line, cpp_pedwarning_with_line,
+       cpp_warning_with_line_syshdr): New specific error reporting functions.
+       * pch.c (cpp_valid_state): Call specific warning functions with
+       warning reason where appropriate.
+       * errors.c (cpp_diagnostic, cpp_diagnostic_with_line): New central
+       diagnostic handlers.
+       (cpp_warning, cpp_pedwarning, cpp_warning_syshdr,
+       cpp_warning_with_line, cpp_pedwarning_with_line,
+       cpp_warning_with_line_syshdr): New specific error reporting functions.
+       * expr.c (cpp_classify_number, eval_token, num_unary_op): Call
+       specific warning functions with warning reason where appropriate.
+       * lex.c (_cpp_process_line_notes, _cpp_skip_block_comment,
+       warn_about_normalization, lex_identifier_intern, lex_identifier,
+       _cpp_lex_direct): Ditto.
+       * charset.c (_cpp_valid_ucn, convert_hex, convert_escape,
+       narrow_str_to_charconst): Ditto.
+
 2010-04-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR preprocessor/43642
index 268d1ba..8d19d8d 100644 (file)
@@ -249,8 +249,15 @@ po/$(PACKAGE).pot: $(libcpp_a_SOURCES)
        $(mkinstalldirs) $(srcdir)/po
        $(XGETTEXT) --default-domain=$(PACKAGE) \
          --keyword=_ --keyword=N_ \
-         --keyword=cpp_error:3 --keyword=cpp_errno:3 \
+         --keyword=cpp_error:3 \
+         --keyword=cpp_warning:3 \
+         --keyword=cpp_pedwarning:3 \
+         --keyword=cpp_warning_syshdr:3 \
          --keyword=cpp_error_with_line:5 \
+         --keyword=cpp_warning_with_line:5 \
+         --keyword=cpp_pedwarning_with_line:5 \
+         --keyword=cpp_warning_with_line_syshdr:5 \
+         --keyword=cpp_errno:3 \
          --keyword=SYNTAX_ERROR --keyword=SYNTAX_ERROR2 \
          --copyright-holder="Free Software Foundation, Inc." \
          --msgid-bugs-address="http://gcc.gnu.org/bugs.html" \
index 304efc8..7bc3db3 100644 (file)
@@ -993,9 +993,9 @@ _cpp_valid_ucn (cpp_reader *pfile, const uchar **pstr,
     cpp_error (pfile, CPP_DL_WARNING,
               "universal character names are only valid in C++ and C99");
   else if (CPP_WTRADITIONAL (pfile) && identifier_pos == 0)
-    cpp_error (pfile, CPP_DL_WARNING,
-              "the meaning of '\\%c' is different in traditional C",
-              (int) str[-1]);
+    cpp_warning (pfile, CPP_W_TRADITIONAL,
+                "the meaning of '\\%c' is different in traditional C",
+                (int) str[-1]);
 
   if (str[-1] == 'u')
     length = 4;
@@ -1174,8 +1174,8 @@ convert_hex (cpp_reader *pfile, const uchar *from, const uchar *limit,
   size_t mask = width_to_mask (width);
 
   if (CPP_WTRADITIONAL (pfile))
-    cpp_error (pfile, CPP_DL_WARNING,
-              "the meaning of '\\x' is different in traditional C");
+    cpp_warning (pfile, CPP_W_TRADITIONAL,
+                "the meaning of '\\x' is different in traditional C");
 
   from++;  /* Skip 'x'.  */
   while (from < limit)
@@ -1302,8 +1302,8 @@ convert_escape (cpp_reader *pfile, const uchar *from, const uchar *limit,
 
     case 'a':
       if (CPP_WTRADITIONAL (pfile))
-       cpp_error (pfile, CPP_DL_WARNING,
-                  "the meaning of '\\a' is different in traditional C");
+       cpp_warning (pfile, CPP_W_TRADITIONAL,
+                    "the meaning of '\\a' is different in traditional C");
       c = charconsts[0];
       break;
 
@@ -1509,7 +1509,7 @@ narrow_str_to_charconst (cpp_reader *pfile, cpp_string str,
                 "character constant too long for its type");
     }
   else if (i > 1 && CPP_OPTION (pfile, warn_multichar))
-    cpp_error (pfile, CPP_DL_WARNING, "multi-character character constant");
+    cpp_warning (pfile, CPP_W_MULTICHAR, "multi-character character constant");
 
   /* Multichar constants are of type int and therefore signed.  */
   if (i > 1)
index 409d908..77da485 100644 (file)
@@ -104,7 +104,7 @@ static const char *parse_include (cpp_reader *, int *, const cpp_token ***,
 static void push_conditional (cpp_reader *, int, int, const cpp_hashnode *);
 static unsigned int read_flag (cpp_reader *, unsigned int);
 static bool strtolinenum (const uchar *, size_t, linenum_type *, bool *);
-static void do_diagnostic (cpp_reader *, int, int);
+static void do_diagnostic (cpp_reader *, int, int, int);
 static cpp_hashnode *lex_macro_node (cpp_reader *, bool);
 static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
 static void do_include_common (cpp_reader *, enum include_type);
@@ -355,8 +355,8 @@ directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented)
       else if (((dir->flags & DEPRECATED) != 0
                || (dir == &dtable[T_IMPORT] && !CPP_OPTION (pfile, objc)))
               && CPP_OPTION (pfile, warn_deprecated))
-       cpp_error (pfile, CPP_DL_WARNING, "#%s is a deprecated GCC extension",
-                  dir->name);
+       cpp_warning (pfile, CPP_W_DEPRECATED,
+                     "#%s is a deprecated GCC extension", dir->name);
     }
 
   /* Traditionally, a directive is ignored unless its # is in
@@ -368,16 +368,16 @@ directive_diagnostics (cpp_reader *pfile, const directive *dir, int indented)
   if (CPP_WTRADITIONAL (pfile))
     {
       if (dir == &dtable[T_ELIF])
-       cpp_error (pfile, CPP_DL_WARNING,
-                  "suggest not using #elif in traditional C");
+       cpp_warning (pfile, CPP_W_TRADITIONAL,
+                    "suggest not using #elif in traditional C");
       else if (indented && dir->origin == KANDR)
-       cpp_error (pfile, CPP_DL_WARNING,
-                  "traditional C ignores #%s with the # indented",
-                  dir->name);
+       cpp_warning (pfile, CPP_W_TRADITIONAL,
+                    "traditional C ignores #%s with the # indented",
+                    dir->name);
       else if (!indented && dir->origin != KANDR)
-       cpp_error (pfile, CPP_DL_WARNING,
-                  "suggest hiding #%s from traditional C with an indented #",
-                  dir->name);
+       cpp_warning (pfile, CPP_W_TRADITIONAL,
+                    "suggest hiding #%s from traditional C with an indented #",
+                    dir->name);
     }
 }
 
@@ -1045,7 +1045,7 @@ _cpp_do_file_change (cpp_reader *pfile, enum lc_reason reason,
 /* Report a warning or error detected by the program we are
    processing.  Use the directive's tokens in the error message.  */
 static void
-do_diagnostic (cpp_reader *pfile, int code, int print_dir)
+do_diagnostic (cpp_reader *pfile, int code, int reason, int print_dir)
 {
   const unsigned char *dir_name;
   unsigned char *line;
@@ -1059,21 +1059,26 @@ do_diagnostic (cpp_reader *pfile, int code, int print_dir)
   line = cpp_output_line_to_string (pfile, dir_name);
   pfile->state.prevent_expansion--;
 
-  cpp_error_with_line (pfile, code, src_loc, 0, "%s", line);
+  if (code == CPP_DL_WARNING_SYSHDR && reason)
+    cpp_warning_with_line_syshdr (pfile, reason, src_loc, 0, "%s", line);
+  else if (code == CPP_DL_WARNING && reason)
+    cpp_warning_with_line (pfile, reason, src_loc, 0, "%s", line);
+  else
+    cpp_error_with_line (pfile, code, src_loc, 0, "%s", line);
   free (line);
 }
 
 static void
 do_error (cpp_reader *pfile)
 {
-  do_diagnostic (pfile, CPP_DL_ERROR, 1);
+  do_diagnostic (pfile, CPP_DL_ERROR, 0, 1);
 }
 
 static void
 do_warning (cpp_reader *pfile)
 {
   /* We want #warning diagnostics to be emitted in system headers too.  */
-  do_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, 1);
+  do_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, CPP_W_WARNING_DIRECTIVE, 1);
 }
 
 /* Report program identification.  */
@@ -1595,7 +1600,7 @@ do_pragma_dependency (cpp_reader *pfile)
       if (cpp_get_token (pfile)->type != CPP_EOF)
        {
          _cpp_backup_tokens (pfile, 1);
-         do_diagnostic (pfile, CPP_DL_WARNING, 0);
+         do_diagnostic (pfile, CPP_DL_WARNING, 0, 0);
        }
     }
 
index bc85289..b7783f5 100644 (file)
@@ -28,16 +28,16 @@ along with this program; see the file COPYING3.  If not see
 #include "cpplib.h"
 #include "internal.h"
 
-/* Print an error at the location of the previously lexed token.  */
-bool
-cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
+/* Print a diagnostic at the location of the previously lexed token.  */
+
+ATTRIBUTE_FPTR_PRINTF(4,0)
+static bool
+cpp_diagnostic (cpp_reader * pfile, int level, int reason,
+                const char *msgid, va_list *ap)
 {
   source_location src_loc;
-  va_list ap;
   bool ret;
 
-  va_start (ap, msgid);
-
   if (CPP_OPTION (pfile, traditional))
     {
       if (pfile->state.in_directive)
@@ -61,13 +61,95 @@ cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
 
   if (!pfile->cb.error)
     abort ();
-  ret = pfile->cb.error (pfile, level, src_loc, 0, _(msgid), &ap);
+  ret = pfile->cb.error (pfile, level, reason, src_loc, 0, _(msgid), ap);
+
+  return ret;
+}
+
+/* Print a warning or error, depending on the value of LEVEL.  */
+
+bool
+cpp_error (cpp_reader * pfile, int level, const char *msgid, ...)
+{
+  va_list ap;
+  bool ret;
+
+  va_start (ap, msgid);
+
+  ret = cpp_diagnostic (pfile, level, CPP_W_NONE, msgid, &ap);
 
   va_end (ap);
   return ret;
 }
 
-/* Print an error at a specific location.  */
+/* Print a warning.  The warning reason may be given in REASON.  */
+
+bool
+cpp_warning (cpp_reader * pfile, int reason, const char *msgid, ...)
+{
+  va_list ap;
+  bool ret;
+
+  va_start (ap, msgid);
+
+  ret = cpp_diagnostic (pfile, CPP_DL_WARNING, reason, msgid, &ap);
+
+  va_end (ap);
+  return ret;
+}
+
+/* Print a pedantic warning.  The warning reason may be given in REASON.  */
+
+bool
+cpp_pedwarning (cpp_reader * pfile, int reason, const char *msgid, ...)
+{
+  va_list ap;
+  bool ret;
+
+  va_start (ap, msgid);
+
+  ret = cpp_diagnostic (pfile, CPP_DL_PEDWARN, reason, msgid, &ap);
+
+  va_end (ap);
+  return ret;
+}
+
+/* Print a warning, including system headers.  The warning reason may be
+   given in REASON.  */
+
+bool
+cpp_warning_syshdr (cpp_reader * pfile, int reason, const char *msgid, ...)
+{
+  va_list ap;
+  bool ret;
+
+  va_start (ap, msgid);
+
+  ret = cpp_diagnostic (pfile, CPP_DL_WARNING_SYSHDR, reason, msgid, &ap);
+
+  va_end (ap);
+  return ret;
+}
+
+/* Print a diagnostic at a specific location.  */
+
+ATTRIBUTE_FPTR_PRINTF(6,0)
+static bool
+cpp_diagnostic_with_line (cpp_reader * pfile, int level, int reason,
+                         source_location src_loc, unsigned int column,
+                         const char *msgid, va_list *ap)
+{
+  bool ret;
+  
+  if (!pfile->cb.error)
+    abort ();
+  ret = pfile->cb.error (pfile, level, reason, src_loc, column, _(msgid), ap);
+
+  return ret;
+}
+
+/* Print a warning or error, depending on the value of LEVEL.  */
+
 bool
 cpp_error_with_line (cpp_reader *pfile, int level,
                     source_location src_loc, unsigned int column,
@@ -75,17 +157,77 @@ cpp_error_with_line (cpp_reader *pfile, int level,
 {
   va_list ap;
   bool ret;
-  
+
   va_start (ap, msgid);
 
-  if (!pfile->cb.error)
-    abort ();
-  ret = pfile->cb.error (pfile, level, src_loc, column, _(msgid), &ap);
+  ret = cpp_diagnostic_with_line (pfile, level, CPP_W_NONE, src_loc,
+                                  column, msgid, &ap);
+
+  va_end (ap);
+  return ret;
+}
+
+/* Print a warning.  The warning reason may be given in REASON.  */
+
+bool
+cpp_warning_with_line (cpp_reader *pfile, int reason,
+                      source_location src_loc, unsigned int column,
+                      const char *msgid, ...)
+{
+  va_list ap;
+  bool ret;
+
+  va_start (ap, msgid);
+
+  ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING, reason, src_loc,
+                                  column, msgid, &ap);
+
+  va_end (ap);
+  return ret;
+}
+
+/* Print a pedantic warning.  The warning reason may be given in REASON.  */
+
+bool
+cpp_pedwarning_with_line (cpp_reader *pfile, int reason,
+                         source_location src_loc, unsigned int column,
+                         const char *msgid, ...)
+{
+  va_list ap;
+  bool ret;
+
+  va_start (ap, msgid);
+
+  ret = cpp_diagnostic_with_line (pfile, CPP_DL_PEDWARN, reason, src_loc,
+                                  column, msgid, &ap);
 
   va_end (ap);
   return ret;
 }
 
+/* Print a warning, including system headers.  The warning reason may be
+   given in REASON.  */
+
+bool
+cpp_warning_with_line_syshdr (cpp_reader *pfile, int reason,
+                             source_location src_loc, unsigned int column,
+                             const char *msgid, ...)
+{
+  va_list ap;
+  bool ret;
+
+  va_start (ap, msgid);
+
+  ret = cpp_diagnostic_with_line (pfile, CPP_DL_WARNING_SYSHDR, reason, src_loc,
+                                  column, msgid, &ap);
+
+  va_end (ap);
+  return ret;
+}
+
+/* Print a warning or error, depending on the value of LEVEL.  Include
+   information from errno.  */
+
 bool
 cpp_errno (cpp_reader *pfile, int level, const char *msgid)
 {
index 60cb281..4dbc989 100644 (file)
@@ -371,9 +371,9 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
       if (limit != str
          && CPP_WTRADITIONAL (pfile)
          && ! cpp_sys_macro_p (pfile))
-       cpp_error (pfile, CPP_DL_WARNING,
-                  "traditional C rejects the \"%.*s\" suffix",
-                  (int) (limit - str), str);
+       cpp_warning (pfile, CPP_W_TRADITIONAL,
+                    "traditional C rejects the \"%.*s\" suffix",
+                    (int) (limit - str), str);
 
       /* A suffix for double is a GCC extension via decimal float support.
         If the suffix also specifies an imaginary value we'll catch that
@@ -417,21 +417,27 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token)
       if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile))
        {
          int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY));
-         int large = (result & CPP_N_WIDTH) == CPP_N_LARGE;
+         int large = (result & CPP_N_WIDTH) == CPP_N_LARGE
+                      && CPP_OPTION (pfile, warn_long_long);
 
-         if (u_or_i || (large && CPP_OPTION (pfile, warn_long_long)))
-           cpp_error (pfile, CPP_DL_WARNING,
-                      "traditional C rejects the \"%.*s\" suffix",
-                      (int) (limit - str), str);
+         if (u_or_i || large)
+           cpp_warning (pfile, large ? CPP_W_LONG_LONG : CPP_W_TRADITIONAL,
+                        "traditional C rejects the \"%.*s\" suffix",
+                        (int) (limit - str), str);
        }
 
       if ((result & CPP_N_WIDTH) == CPP_N_LARGE
          && CPP_OPTION (pfile, warn_long_long))
-       cpp_error (pfile, 
-                  CPP_OPTION (pfile, c99) ? CPP_DL_WARNING : CPP_DL_PEDWARN,
-                  CPP_OPTION (pfile, cplusplus) 
-                  ? "use of C++0x long long integer constant"
-                  : "use of C99 long long integer constant");
+        {
+          const char *message = CPP_OPTION (pfile, cplusplus) 
+                               ? N_("use of C++0x long long integer constant")
+                               : N_("use of C99 long long integer constant");
+
+         if (CPP_OPTION (pfile, c99))
+            cpp_warning (pfile, CPP_W_LONG_LONG, message);
+          else
+            cpp_pedwarning (pfile, CPP_W_LONG_LONG, message);
+        }
 
       result |= CPP_N_INTEGER;
     }
@@ -792,8 +798,8 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
          result.high = 0;
          result.low = 0;
          if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval)
-           cpp_error (pfile, CPP_DL_WARNING, "\"%s\" is not defined",
-                      NODE_NAME (token->val.node.node));
+           cpp_warning (pfile, CPP_W_UNDEF, "\"%s\" is not defined",
+                        NODE_NAME (token->val.node.node));
        }
       break;
 
@@ -806,8 +812,8 @@ eval_token (cpp_reader *pfile, const cpp_token *token)
            cpp_error (pfile, CPP_DL_PEDWARN,
                       "assertions are a GCC extension");
          else if (CPP_OPTION (pfile, warn_deprecated))
-           cpp_error (pfile, CPP_DL_WARNING,
-                      "assertions are a deprecated extension");
+           cpp_warning (pfile, CPP_W_DEPRECATED,
+                        "assertions are a deprecated extension");
        }
       _cpp_test_assertion (pfile, &temp);
       result.high = 0;
@@ -1502,8 +1508,8 @@ num_unary_op (cpp_reader *pfile, cpp_num num, enum cpp_ttype op)
     {
     case CPP_UPLUS:
       if (CPP_WTRADITIONAL (pfile) && !pfile->state.skip_eval)
-       cpp_error (pfile, CPP_DL_WARNING,
-                  "traditional C rejects the unary plus operator");
+       cpp_warning (pfile, CPP_W_TRADITIONAL,
+                    "traditional C rejects the unary plus operator");
       num.overflow = false;
       break;
 
index 6175bbc..9f29e6e 100644 (file)
@@ -497,9 +497,9 @@ struct cpp_callbacks
 
   /* Called to emit a diagnostic.  This callback receives the
      translated message.  */
-  bool (*error) (cpp_reader *, int, source_location, unsigned int,
+  bool (*error) (cpp_reader *, int, int, source_location, unsigned int,
                 const char *, va_list *)
-       ATTRIBUTE_FPTR_PRINTF(5,0);
+       ATTRIBUTE_FPTR_PRINTF(6,0);
 
   /* Callbacks for when a macro is expanded, or tested (whether
      defined or not at the time) in #ifdef, #ifndef or "defined".  */
@@ -829,25 +829,57 @@ cpp_num cpp_num_sign_extend (cpp_num, size_t);
    position in the translation unit with it, use cpp_error_with_line
    with a line number of zero.  */
 
-/* Warning, an error with -Werror.  */
-#define CPP_DL_WARNING         0x00
-/* Same as CPP_DL_WARNING, except it is not suppressed in system headers.  */
-#define CPP_DL_WARNING_SYSHDR  0x01
-/* Warning, an error with -pedantic-errors or -Werror.  */
-#define CPP_DL_PEDWARN         0x02
-/* An error.  */
-#define CPP_DL_ERROR           0x03
-/* An internal consistency check failed.  Prints "internal error: ",
-   otherwise the same as CPP_DL_ERROR.  */
-#define CPP_DL_ICE             0x04
-/* An informative note following a warning.  */
-#define CPP_DL_NOTE            0x05
-/* A fatal error.  */
-#define CPP_DL_FATAL           0x06
+enum {
+  /* Warning, an error with -Werror.  */
+  CPP_DL_WARNING = 0,
+  /* Same as CPP_DL_WARNING, except it is not suppressed in system headers.  */
+  CPP_DL_WARNING_SYSHDR,
+  /* Warning, an error with -pedantic-errors or -Werror.  */
+  CPP_DL_PEDWARN,
+  /* An error.  */
+  CPP_DL_ERROR,
+  /* An internal consistency check failed.  Prints "internal error: ",
+     otherwise the same as CPP_DL_ERROR.  */
+  CPP_DL_ICE,
+  /* An informative note following a warning.  */
+  CPP_DL_NOTE,
+  /* A fatal error.  */
+  CPP_DL_FATAL
+};
+
+/* Warning reason codes. Use a reason code of zero for unclassified warnings
+   and errors that are not warnings.  */
+enum {
+  CPP_W_NONE = 0,
+  CPP_W_DEPRECATED,
+  CPP_W_COMMENTS,
+  CPP_W_MISSING_INCLUDE_DIRS,
+  CPP_W_TRIGRAPHS,
+  CPP_W_MULTICHAR,
+  CPP_W_TRADITIONAL,
+  CPP_W_LONG_LONG,
+  CPP_W_ENDIF_LABELS,
+  CPP_W_NUM_SIGN_CHANGE,
+  CPP_W_VARIADIC_MACROS,
+  CPP_W_BUILTIN_MACRO_REDEFINED,
+  CPP_W_DOLLARS,
+  CPP_W_UNDEF,
+  CPP_W_UNUSED_MACROS,
+  CPP_W_CXX_OPERATOR_NAMES,
+  CPP_W_NORMALIZE,
+  CPP_W_INVALID_PCH,
+  CPP_W_WARNING_DIRECTIVE
+};
 
 /* Output a diagnostic of some kind.  */
 extern bool cpp_error (cpp_reader *, int, const char *msgid, ...)
   ATTRIBUTE_PRINTF_3;
+extern bool cpp_warning (cpp_reader *, int, const char *msgid, ...)
+  ATTRIBUTE_PRINTF_3;
+extern bool cpp_pedwarning (cpp_reader *, int, const char *msgid, ...)
+  ATTRIBUTE_PRINTF_3;
+extern bool cpp_warning_syshdr (cpp_reader *, int, const char *msgid, ...)
+  ATTRIBUTE_PRINTF_3;
 
 /* Output a diagnostic with "MSGID: " preceding the
    error string of errno.  No location is printed.  */
@@ -856,8 +888,18 @@ extern bool cpp_errno (cpp_reader *, int, const char *msgid);
 /* Same as cpp_error, except additionally specifies a position as a
    (translation unit) physical line and physical column.  If the line is
    zero, then no location is printed.  */
-extern bool cpp_error_with_line (cpp_reader *, int, source_location, unsigned,
-                                const char *msgid, ...) ATTRIBUTE_PRINTF_5;
+extern bool cpp_error_with_line (cpp_reader *, int, source_location,
+                                 unsigned, const char *msgid, ...)
+  ATTRIBUTE_PRINTF_5;
+extern bool cpp_warning_with_line (cpp_reader *, int, source_location,
+                                   unsigned, const char *msgid, ...)
+  ATTRIBUTE_PRINTF_5;
+extern bool cpp_pedwarning_with_line (cpp_reader *, int, source_location,
+                                      unsigned, const char *msgid, ...)
+  ATTRIBUTE_PRINTF_5;
+extern bool cpp_warning_with_line_syshdr (cpp_reader *, int, source_location,
+                                          unsigned, const char *msgid, ...)
+  ATTRIBUTE_PRINTF_5;
 
 /* In lex.c */
 extern int cpp_ideq (const cpp_token *, const char *);
index f299982..f628272 100644 (file)
@@ -301,14 +301,16 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
              && (!in_comment || warn_in_comment (pfile, note)))
            {
              if (CPP_OPTION (pfile, trigraphs))
-               cpp_error_with_line (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
-                                    "trigraph ??%c converted to %c",
-                                    note->type,
-                                    (int) _cpp_trigraph_map[note->type]);
+               cpp_warning_with_line (pfile, CPP_W_TRIGRAPHS,
+                                       pfile->line_table->highest_line, col,
+                                      "trigraph ??%c converted to %c",
+                                      note->type,
+                                      (int) _cpp_trigraph_map[note->type]);
              else
                {
-                 cpp_error_with_line 
-                   (pfile, CPP_DL_WARNING, pfile->line_table->highest_line, col,
+                 cpp_warning_with_line 
+                   (pfile, CPP_W_TRIGRAPHS,
+                     pfile->line_table->highest_line, col,
                     "trigraph ??%c ignored, use -trigraphs to enable",
                     note->type);
                }
@@ -355,9 +357,10 @@ _cpp_skip_block_comment (cpp_reader *pfile)
              && cur[0] == '*' && cur[1] != '/')
            {
              buffer->cur = cur;
-             cpp_error_with_line (pfile, CPP_DL_WARNING,
-                                  pfile->line_table->highest_line, CPP_BUF_COL (buffer),
-                                  "\"/*\" within comment");
+             cpp_warning_with_line (pfile, CPP_W_COMMENTS,
+                                    pfile->line_table->highest_line,
+                                    CPP_BUF_COL (buffer),
+                                    "\"/*\" within comment");
            }
        }
       else if (c == '\n')
@@ -460,11 +463,11 @@ warn_about_normalization (cpp_reader *pfile,
 
       sz = cpp_spell_token (pfile, token, buf, false) - buf;
       if (NORMALIZE_STATE_RESULT (s) == normalized_C)
-       cpp_error_with_line (pfile, CPP_DL_WARNING, token->src_loc, 0,
-                            "`%.*s' is not in NFKC", (int) sz, buf);
+       cpp_warning_with_line (pfile, CPP_W_NORMALIZE, token->src_loc, 0,
+                              "`%.*s' is not in NFKC", (int) sz, buf);
       else
-       cpp_error_with_line (pfile, CPP_DL_WARNING, token->src_loc, 0,
-                            "`%.*s' is not in NFC", (int) sz, buf);
+       cpp_warning_with_line (pfile, CPP_W_NORMALIZE, token->src_loc, 0,
+                              "`%.*s' is not in NFC", (int) sz, buf);
     }
 }
 
@@ -545,9 +548,9 @@ lex_identifier_intern (cpp_reader *pfile, const uchar *base)
 
       /* For -Wc++-compat, warn about use of C++ named operators.  */
       if (result->flags & NODE_WARN_OPERATOR)
-       cpp_error (pfile, CPP_DL_WARNING,
-                  "identifier \"%s\" is a special operator name in C++",
-                  NODE_NAME (result));
+       cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES,
+                    "identifier \"%s\" is a special operator name in C++",
+                    NODE_NAME (result));
     }
 
   return result;
@@ -622,9 +625,9 @@ lex_identifier (cpp_reader *pfile, const uchar *base, bool starts_ucn,
 
       /* For -Wc++-compat, warn about use of C++ named operators.  */
       if (result->flags & NODE_WARN_OPERATOR)
-       cpp_error (pfile, CPP_DL_WARNING,
-                  "identifier \"%s\" is a special operator name in C++",
-                  NODE_NAME (result));
+       cpp_warning (pfile, CPP_W_CXX_OPERATOR_NAMES,
+                    "identifier \"%s\" is a special operator name in C++",
+                    NODE_NAME (result));
     }
 
   return result;
@@ -1531,7 +1534,7 @@ _cpp_lex_direct (cpp_reader *pfile)
            }
 
          if (skip_line_comment (pfile) && CPP_OPTION (pfile, warn_comments))
-           cpp_error (pfile, CPP_DL_WARNING, "multi-line comment");
+           cpp_warning (pfile, CPP_W_COMMENTS, "multi-line comment");
        }
       else if (c == '=')
        {
index 6647db5..cbb0b0e 100644 (file)
@@ -83,8 +83,8 @@ _cpp_warn_if_unused_macro (cpp_reader *pfile, cpp_hashnode *node,
 
       if (!macro->used
          && MAIN_FILE_P (linemap_lookup (pfile->line_table, macro->line)))
-       cpp_error_with_line (pfile, CPP_DL_WARNING, macro->line, 0,
-                            "macro \"%s\" is not used", NODE_NAME (node));
+       cpp_warning_with_line (pfile, CPP_W_UNUSED_MACROS, macro->line, 0,
+                              "macro \"%s\" is not used", NODE_NAME (node));
     }
 
   return 1;
@@ -860,9 +860,9 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node,
          if (buff == NULL)
            {
              if (CPP_WTRADITIONAL (pfile) && ! node->value.macro->syshdr)
-               cpp_error (pfile, CPP_DL_WARNING,
+               cpp_warning (pfile, CPP_W_TRADITIONAL,
  "function-like macro \"%s\" must be used with arguments in traditional C",
-                          NODE_NAME (node));
+                            NODE_NAME (node));
 
              if (pragma_buff)
                _cpp_release_buff (pfile, pragma_buff);
@@ -1585,13 +1585,14 @@ parse_params (cpp_reader *pfile, cpp_macro *macro)
              if (! CPP_OPTION (pfile, c99)
                  && CPP_OPTION (pfile, pedantic)
                  && CPP_OPTION (pfile, warn_variadic_macros))
-               cpp_error (pfile, CPP_DL_PEDWARN,
-                          "anonymous variadic macros were introduced in C99");
+               cpp_pedwarning
+                  (pfile, CPP_W_VARIADIC_MACROS,
+                  "anonymous variadic macros were introduced in C99");
            }
          else if (CPP_OPTION (pfile, pedantic)
                   && CPP_OPTION (pfile, warn_variadic_macros))
-           cpp_error (pfile, CPP_DL_PEDWARN,
-                      "ISO C does not permit named variadic macros");
+           cpp_pedwarning (pfile, CPP_W_VARIADIC_MACROS,
+                           "ISO C does not permit named variadic macros");
 
          /* We're at the end, and just expect a closing parenthesis.  */
          token = _cpp_lex_token (pfile);
@@ -1894,10 +1895,14 @@ _cpp_create_definition (cpp_reader *pfile, cpp_hashnode *node)
 
       if (warn_of_redefinition (pfile, node, macro))
        {
+          const int reason = (node->flags & NODE_BUILTIN)
+                             ? CPP_W_BUILTIN_MACRO_REDEFINED : CPP_W_NONE;
          bool warned;
-         warned = cpp_error_with_line (pfile, CPP_DL_PEDWARN,
-                                       pfile->directive_line, 0,
-                                       "\"%s\" redefined", NODE_NAME (node));
+
+         warned = cpp_pedwarning_with_line (pfile, reason,
+                                            pfile->directive_line, 0,
+                                            "\"%s\" redefined",
+                                             NODE_NAME (node));
 
          if (warned && node->type == NT_MACRO && !(node->flags & NODE_BUILTIN))
            cpp_error_with_line (pfile, CPP_DL_NOTE,
index c70759a..2fb7ba5 100644 (file)
@@ -613,9 +613,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
          || h->flags & NODE_POISONED)
        {
          if (CPP_OPTION (r, warn_invalid_pch))
-           cpp_error (r, CPP_DL_WARNING_SYSHDR,
-                      "%s: not used because `%.*s' is poisoned",
-                      name, m.name_length, namebuf);
+           cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+                               "%s: not used because `%.*s' is poisoned",
+                               name, m.name_length, namebuf);
          goto fail;
        }
 
@@ -635,9 +635,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
            continue;
 
          if (CPP_OPTION (r, warn_invalid_pch))
-           cpp_error (r, CPP_DL_WARNING_SYSHDR,
-                      "%s: not used because `%.*s' not defined",
-                      name, m.name_length, namebuf);
+           cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+                               "%s: not used because `%.*s' not defined",
+                               name, m.name_length, namebuf);
          goto fail;
        }
 
@@ -647,7 +647,7 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
          || memcmp (namebuf, newdefn, m.definition_length) != 0)
        {
          if (CPP_OPTION (r, warn_invalid_pch))
-           cpp_error (r, CPP_DL_WARNING_SYSHDR,
+           cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
               "%s: not used because `%.*s' defined as `%s' not `%.*s'",
                       name, m.name_length, namebuf, newdefn + m.name_length,
                       m.definition_length - m.name_length,
@@ -688,9 +688,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
       else
        {
          if (CPP_OPTION (r, warn_invalid_pch))
-           cpp_error (r, CPP_DL_WARNING_SYSHDR,
-                      "%s: not used because `%s' is defined",
-                      name, first);
+           cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+                               "%s: not used because `%s' is defined",
+                               name, first);
          goto fail;
        }
     }
@@ -708,9 +708,9 @@ cpp_valid_state (cpp_reader *r, const char *name, int fd)
   if (counter && r->counter)
     {
       if (CPP_OPTION (r, warn_invalid_pch))
-       cpp_error (r, CPP_DL_WARNING_SYSHDR,
-                  "%s: not used because `__COUNTER__' is invalid",
-                  name);
+       cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+                           "%s: not used because `__COUNTER__' is invalid",
+                           name);
        goto fail;
     }