|
View:
New views
12 Messages
—
Rating Filter:
Alert me
|
|
|
[PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsThis patch brings several preprocessor warnings under the control of the
-Werror= gcc flag. At present, gcc does not associate preprocessor warnings with gcc command line options, and so such warnings cannot be controlled individually with -Werror=. With the patch in place, preprocessor warnings can now be set separately as errors with -Werror=, disabled as errors with -Wno-error=, and will report their corresponding gcc diagnostic flag with -fdiagnostics-show-option when requested. The patch also adds a new gcc option -W[no-]warning-directive so that the output of #warning operates symmetrically to other gcc warnings, and in particular so that the combination "-Werror -Wno-error=warning-directive" allows all warnings except for #warning directives to be treated as errors. Confirmed C/C++ dejagnu testsuite parity with the unpatched gcc, and verified bootstrap of C/C++ on x86_64. Okay for mainline? gcc/ChangeLog: 2009-10-30 Simon Baldwin <simonb@...> * 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-warning-directive 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-warning-directive. libcpp/ChangeLog: 2009-10-30 Simon Baldwin <simonb@...> * 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. * 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, _cpp_lex_direct): Ditto. * charset.c (_cpp_valid_ucn, convert_hex, convert_escape, narrow_str_to_charconst): Ditto. gcc/testsuite/ChangeLog: 2009-10-30 Simon Baldwin <simonb@...> * 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. Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 153497) +++ gcc/doc/invoke.texi (working copy) @@ -270,7 +270,7 @@ Objective-C and Objective-C++ Dialects}. -Wmissing-parameter-type -Wmissing-prototypes -Wnested-externs @gol -Wold-style-declaration -Wold-style-definition @gol -Wstrict-prototypes -Wtraditional -Wtraditional-conversion @gol --Wdeclaration-after-statement -Wpointer-sign} +-Wdeclaration-after-statement -Wpointer-sign -Wwarning-directive} @item Debugging Options @xref{Debugging Options,,Options for Debugging Your Program or GCC}. @@ -4325,6 +4325,10 @@ a suffix. When used together with @opti warn about such constants in system header files. This can be useful when preparing code to use with the @code{FLOAT_CONST_DECIMAL64} pragma from the decimal floating-point extension to C99. + +@item -Wno-warning-directive @r{(C and Objective-C only)} + +Suppress warning messages emitted by @code{#warning} directives. @end table @node Debugging Options Index: gcc/diagnostic.h =================================================================== --- gcc/diagnostic.h (revision 153497) +++ gcc/diagnostic.h (working copy) @@ -190,6 +190,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: gcc/testsuite/gcc.dg/cpp/warn-undef-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-undef-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-undef-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-comments-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-comments-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-comments-2.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-1.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-1.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-1.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wwarning-directive." } Index: gcc/testsuite/gcc.dg/cpp/warn-long-long.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-long-long.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-long-long.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-traditional.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-traditional.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-traditional.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c (revision 0) @@ -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." } */ Index: gcc/testsuite/gcc.dg/cpp/warn-undef.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-undef.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-undef.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c (revision 0) @@ -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=." } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-2.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=warning-directive" } + +#warning "Printed" // { dg-error "\"Printed\" .-Wwarning-directive." } Index: gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-variadic.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-variadic.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-variadic.c (revision 0) @@ -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." } */ Index: gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c (revision 0) @@ -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=." } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-3.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-3.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-3.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror -Wno-error=warning-directive" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wwarning-directive." } Index: gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -trigraphs -Wtrigraphs" } + +??= // { dg-warning "trigraph \\?\\?= converted to # .-Wtrigraphs." } Index: gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c (revision 0) @@ -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=." } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-4.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-4.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-4.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wno-warning-directive" } + +#warning "Not printed" // { dg-bogus "." } Index: gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wtrigraphs" } + +??= // { dg-warning "trigraph \\?\\?= ignored, use -trigraphs to enable .-Wtrigraphs." } Index: gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-redefined.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-redefined.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-redefined.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -trigraphs -Werror=trigraphs" } + +??= // { dg-error "trigraph \\?\\?= converted to # .-Wtrigraphs." } Index: gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-deprecated.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-deprecated.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-deprecated.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warn-comments.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-comments.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-comments.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warn-multichar.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-multichar.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-multichar.c (revision 0) @@ -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 Index: gcc/c-tree.h =================================================================== --- gcc/c-tree.h (revision 153497) +++ gcc/c-tree.h (working copy) @@ -604,8 +604,8 @@ extern void c_write_global_declarations 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: gcc/opts.c =================================================================== --- gcc/opts.c (revision 153497) +++ gcc/opts.c (working copy) @@ -2360,6 +2360,19 @@ set_option (const struct cl_option *opti } } + +/* 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)) +{ + 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. */ @@ -2379,14 +2392,20 @@ enable_warning_as_error (const char *arg } 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); - - /* -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 (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; + + if (warning_as_error_callback) + warning_as_error_callback (option_index); + } } free (new_option); } Index: gcc/opts.h =================================================================== --- gcc/opts.h (revision 153497) +++ gcc/opts.h (working copy) @@ -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: gcc/c-opts.c =================================================================== --- gcc/c-opts.c (revision 153497) +++ gcc/c-opts.c (working copy) @@ -196,6 +196,90 @@ defer_opt (enum opt_code code, const cha 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_Wwarning_directive: + /* 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 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: gcc/common.opt =================================================================== --- gcc/common.opt (revision 153497) +++ gcc/common.opt (working copy) @@ -228,6 +228,10 @@ Wunused-variable Common Var(warn_unused_variable) Init(-1) Warning Warn when a variable is unused +Wwarning-directive +Common Var(warn_warning_directive) Init(1) Warning +Warn when a #warning directive is encountered + Wcoverage-mismatch Common RejectNegative Var(warn_coverage_mismatch) Warning Warn instead of error in case profiles in -fprofile-use do not match Index: gcc/c-common.c =================================================================== --- gcc/c-common.c (revision 153497) +++ gcc/c-common.c (working copy) @@ -8224,6 +8224,49 @@ c_parse_error (const char *gmsgid, enum #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_Wwarning_directive}, + {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 LOCATION unless this is after lexing and the compiler's location @@ -8233,7 +8276,7 @@ c_parse_error (const char *gmsgid, enum 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) { @@ -8280,6 +8323,8 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE 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: libcpp/directives.c =================================================================== --- libcpp/directives.c (revision 153497) +++ libcpp/directives.c (working copy) @@ -104,7 +104,7 @@ static const char *parse_include (cpp_re 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); @@ -353,8 +353,8 @@ directive_diagnostics (cpp_reader *pfile 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 @@ -366,16 +366,16 @@ directive_diagnostics (cpp_reader *pfile 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); } } @@ -1043,7 +1043,7 @@ _cpp_do_file_change (cpp_reader *pfile, /* 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; @@ -1057,21 +1057,26 @@ do_diagnostic (cpp_reader *pfile, int co 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. */ @@ -1501,7 +1506,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: libcpp/macro.c =================================================================== --- libcpp/macro.c (revision 153497) +++ libcpp/macro.c (working copy) @@ -83,8 +83,8 @@ _cpp_warn_if_unused_macro (cpp_reader *p 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, 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); @@ -1582,13 +1582,14 @@ parse_params (cpp_reader *pfile, cpp_mac 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); @@ -1891,10 +1892,14 @@ _cpp_create_definition (cpp_reader *pfil 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: libcpp/include/cpplib.h =================================================================== --- libcpp/include/cpplib.h (revision 153497) +++ libcpp/include/cpplib.h (working copy) @@ -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". */ @@ -826,25 +826,57 @@ cpp_num cpp_num_sign_extend (cpp_num, si 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. */ @@ -853,8 +885,18 @@ extern bool cpp_errno (cpp_reader *, int /* 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: libcpp/pch.c =================================================================== --- libcpp/pch.c (revision 153497) +++ libcpp/pch.c (working copy) @@ -480,9 +480,9 @@ cpp_valid_state (cpp_reader *r, const ch || 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; } @@ -502,9 +502,9 @@ cpp_valid_state (cpp_reader *r, const ch 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; } @@ -514,7 +514,7 @@ cpp_valid_state (cpp_reader *r, const ch || 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, @@ -555,9 +555,9 @@ cpp_valid_state (cpp_reader *r, const ch 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; } } @@ -575,9 +575,9 @@ cpp_valid_state (cpp_reader *r, const ch 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; } Index: libcpp/errors.c =================================================================== --- libcpp/errors.c (revision 153497) +++ libcpp/errors.c (working copy) @@ -28,16 +28,16 @@ along with this program; see the file CO #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 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, { 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: libcpp/expr.c =================================================================== --- libcpp/expr.c (revision 153497) +++ libcpp/expr.c (working copy) @@ -365,9 +365,9 @@ cpp_classify_number (cpp_reader *pfile, 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 @@ -411,21 +411,27 @@ cpp_classify_number (cpp_reader *pfile, 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) + ? "use of C++0x long long integer constant" + : "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; } @@ -786,8 +792,8 @@ eval_token (cpp_reader *pfile, const cpp 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; @@ -800,8 +806,8 @@ eval_token (cpp_reader *pfile, const cpp 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; @@ -1496,8 +1502,8 @@ num_unary_op (cpp_reader *pfile, cpp_num { 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: libcpp/lex.c =================================================================== --- libcpp/lex.c (revision 153497) +++ libcpp/lex.c (working copy) @@ -301,14 +301,16 @@ _cpp_process_line_notes (cpp_reader *pfi && (!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); } @@ -353,9 +355,10 @@ _cpp_skip_block_comment (cpp_reader *pfi && 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') @@ -458,11 +461,11 @@ warn_about_normalization (cpp_reader *pf 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); } } @@ -563,9 +566,9 @@ lex_identifier (cpp_reader *pfile, const /* 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; @@ -1373,7 +1376,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: libcpp/charset.c =================================================================== --- libcpp/charset.c (revision 153497) +++ libcpp/charset.c (working copy) @@ -993,9 +993,9 @@ _cpp_valid_ucn (cpp_reader *pfile, const 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 uc 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 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; @@ -1522,7 +1522,7 @@ narrow_str_to_charconst (cpp_reader *pfi "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) |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsOn Fri, 30 Oct 2009, Simon Baldwin wrote:
> Confirmed C/C++ dejagnu testsuite parity with the unpatched gcc, and verified > bootstrap of C/C++ on x86_64. C and C++ isn't enough for this patch. Fortran uses libcpp and has an error callback I expect you'll need to update. > +@item -Wno-warning-directive @r{(C and Objective-C only)} Why C and ObjC only? Surely it should apply to C++ and ObjC++ (and Fortran)? And there should be at least one C++ testcase. You're adding a lot of new diagnostic functions. You need to update the xgettext call in libcpp/Makefile.in to know about which arguments of these functions should be extracted for translation (and for any changed argument positions in existing functions), and verify that rebuilding cpplib.pot doesn't lose any messages in it; cpplib doesn't have the automatic identification of *msgid arguments that the gcc/ directory does. > - 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) > + ? "use of C++0x long long integer constant" > + : "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); This would mean an i18n regression; at least the first of the two messages in the call to cpp_error gets extracted now, even if the second doesn't. Wrap both string constants in N_() so they get extracted for translation. -- Joseph S. Myers joseph@... |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsThank you for the review -- inlined responses below.
I've attached a revised and corrected version of the patch to the mail; bootstrap C/C++/Fortran and appropriate suite re-done. Please take a second look. Thanks. 2009/10/30 Joseph S. Myers <joseph@...> > > On Fri, 30 Oct 2009, Simon Baldwin wrote: > > > Confirmed C/C++ dejagnu testsuite parity with the unpatched gcc, and verified > > bootstrap of C/C++ on x86_64. > > C and C++ isn't enough for this patch. Fortran uses libcpp and has an > error callback I expect you'll need to update. Thanks for the note. I've added Fortran support for -Wno-warning-directives. Fortran doesn't have the, er... rich support for -W flags in C and C++ so it doesn't seem to make sense to try to add all the others at this point. > > +@item -Wno-warning-directive @r{(C and Objective-C only)} > > Why C and ObjC only? Surely it should apply to C++ and ObjC++ (and > Fortran)? And there should be at least one C++ testcase. Revised the documentation to include the C++es and Fortran, added smoke-test testcases for C++ and Fortran. > You're adding a lot of new diagnostic functions. You need to update the > xgettext call in libcpp/Makefile.in to know about which arguments of these > functions should be extracted for translation (and for any changed > argument positions in existing functions), and verify that rebuilding > cpplib.pot doesn't lose any messages in it; cpplib doesn't have the > automatic identification of *msgid arguments that the gcc/ directory does. Thanks for the pointer here; I'd missed this. libcpp/Makefile.in revised for the new diagnostic functions, and N_() added in where required. I've rebuilt cpplib.pot and verified both that no messages were dropped, and that "use of C99 long long integer constant", which was missing from translations before this patch, is now picked up by N_(). > > > - 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) > > + ? "use of C++0x long long integer constant" > > + : "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); > > This would mean an i18n regression; at least the first of the two messages > in the call to cpp_error gets extracted now, even if the second doesn't. > Wrap both string constants in N_() so they get extracted for translation. -- Google UK Limited | Registered Office: Belgrave House, 76 Buckingham Palace Road, London SW1W 9TQ | Registered in England Number: 3977902 [cpp_warnings.patch] This patch brings several preprocessor warnings under the control of the -Werror= gcc flag. At present, gcc does not associate preprocessor warnings with gcc command line options, and so such warnings cannot be controlled individually with -Werror=. With the patch in place, preprocessor warnings can now be set separately as errors with -Werror=, disabled as errors with -Wno-error=, and will report their corresponding gcc diagnostic flag with -fdiagnostics-show-option when requested. The patch also adds a new gcc option -W[no-]warning-directive so that the output of #warning operates symmetrically to other gcc warnings, and in particular so that the combination "-Werror -Wno-error=warning-directive" allows all warnings except for #warning directives to be treated as errors. Confirmed C, C++ and Fortran dejagnu testsuite parity with the unpatched gcc, and verified bootstrap of C/C++/Fortran on x86_64. gcc/ChangeLog: 2009-11-02 Simon Baldwin <simonb@...> * 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-warning-directive 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-warning-directive. gcc/fortran/ChangeLog: 2009-11-02 Simon Baldwin <simonb@...> * cpp.c (cb_cpp_error): Add warning reason argument, set a value for diagnostic_override_option_index if CPP_W_WARNING_DIRECTIVE. libcpp/ChangeLog: 2009-11-02 Simon Baldwin <simonb@...> * 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, _cpp_lex_direct): Ditto. * charset.c (_cpp_valid_ucn, convert_hex, convert_escape, narrow_str_to_charconst): Ditto. gcc/testsuite/ChangeLog: 2009-11-02 Simon Baldwin <simonb@...> * 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. Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 153803) +++ gcc/doc/invoke.texi (working copy) @@ -263,7 +263,7 @@ Objective-C and Objective-C++ Dialects}. -Wunsuffixed-float-constants -Wunused -Wunused-function @gol -Wunused-label -Wunused-parameter -Wno-unused-result -Wunused-value -Wunused-variable @gol -Wvariadic-macros -Wvla @gol --Wvolatile-register-var -Wwrite-strings} +-Wvolatile-register-var -Wwarning-directive -Wwrite-strings} @item C and Objective-C-only Warning Options @gccoptlist{-Wbad-function-cast -Wmissing-declarations @gol @@ -4340,6 +4340,11 @@ a suffix. When used together with @opti warn about such constants in system header files. This can be useful when preparing code to use with the @code{FLOAT_CONST_DECIMAL64} pragma from the decimal floating-point extension to C99. + +@item -Wno-warning-directive \ +@r{(C, Objective-C, C++, Objective-C++ and Fortran only)} + +Suppress warning messages emitted by @code{#warning} directives. @end table @node Debugging Options Index: gcc/diagnostic.h =================================================================== --- gcc/diagnostic.h (revision 153803) +++ gcc/diagnostic.h (working copy) @@ -190,6 +190,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: gcc/testsuite/gcc.dg/cpp/warn-undef-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-undef-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-undef-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-comments-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-comments-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-comments-2.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-1.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-1.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-1.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wwarning-directive." } Index: gcc/testsuite/gcc.dg/cpp/warn-long-long.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-long-long.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-long-long.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-traditional.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-traditional.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-traditional.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c (revision 0) @@ -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." } */ Index: gcc/testsuite/gcc.dg/cpp/warn-undef.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-undef.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-undef.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c (revision 0) @@ -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=." } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-2.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=warning-directive" } + +#warning "Printed" // { dg-error "\"Printed\" .-Wwarning-directive." } Index: gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-variadic.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-variadic.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-variadic.c (revision 0) @@ -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." } */ Index: gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c (revision 0) @@ -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=." } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-3.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-3.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-3.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror -Wno-error=warning-directive" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wwarning-directive." } Index: gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -trigraphs -Wtrigraphs" } + +??= // { dg-warning "trigraph \\?\\?= converted to # .-Wtrigraphs." } Index: gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c (revision 0) @@ -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=." } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-4.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-4.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-4.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wno-warning-directive" } + +#warning "Not printed" // { dg-bogus "." } Index: gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wtrigraphs" } + +??= // { dg-warning "trigraph \\?\\?= ignored, use -trigraphs to enable .-Wtrigraphs." } Index: gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-redefined.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-redefined.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-redefined.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -trigraphs -Werror=trigraphs" } + +??= // { dg-error "trigraph \\?\\?= converted to # .-Wtrigraphs." } Index: gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-deprecated.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-deprecated.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-deprecated.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warn-comments.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-comments.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-comments.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warn-multichar.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-multichar.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-multichar.c (revision 0) @@ -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 Index: gcc/testsuite/g++.dg/cpp/warning-directive-1.C =================================================================== --- gcc/testsuite/g++.dg/cpp/warning-directive-1.C (revision 0) +++ gcc/testsuite/g++.dg/cpp/warning-directive-1.C (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-fdiagnostics-show-option" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wwarning-directive." } Index: gcc/testsuite/g++.dg/cpp/warning-directive-2.C =================================================================== --- gcc/testsuite/g++.dg/cpp/warning-directive-2.C (revision 0) +++ gcc/testsuite/g++.dg/cpp/warning-directive-2.C (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-fdiagnostics-show-option -Werror=warning-directive" } + +#warning "Printed" // { dg-error "\"Printed\" .-Wwarning-directive." } Index: gcc/testsuite/g++.dg/cpp/warning-directive-3.C =================================================================== --- gcc/testsuite/g++.dg/cpp/warning-directive-3.C (revision 0) +++ gcc/testsuite/g++.dg/cpp/warning-directive-3.C (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-fdiagnostics-show-option -Werror -Wno-error=warning-directive" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wwarning-directive." } Index: gcc/testsuite/g++.dg/cpp/warning-directive-4.C =================================================================== --- gcc/testsuite/g++.dg/cpp/warning-directive-4.C (revision 0) +++ gcc/testsuite/g++.dg/cpp/warning-directive-4.C (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-fdiagnostics-show-option -Wno-warning-directive" } + +#warning "Not printed" // { dg-bogus "." } Index: gcc/testsuite/gfortran.dg/warning-directive-1.F90 =================================================================== --- gcc/testsuite/gfortran.dg/warning-directive-1.F90 (revision 0) +++ gcc/testsuite/gfortran.dg/warning-directive-1.F90 (revision 0) @@ -0,0 +1,5 @@ +! { dg-do preprocess } +! { dg-options "-std=f95 -fdiagnostics-show-option" } + +#warning "Printed" +! { dg-warning "\"Printed\" .-Wwarning-directive." "" { target *-*-* } 4 } Index: gcc/testsuite/gfortran.dg/warning-directive-3.F90 =================================================================== --- gcc/testsuite/gfortran.dg/warning-directive-3.F90 (revision 0) +++ gcc/testsuite/gfortran.dg/warning-directive-3.F90 (revision 0) @@ -0,0 +1,5 @@ +! { dg-do preprocess } +! { dg-options "-std=f95 -fdiagnostics-show-option -Werror -Wno-error=warning-directive" } + +#warning "Printed" +! { dg-warning "\"Printed\" .-Wwarning-directive." "" { target *-*-* } 4 } Index: gcc/testsuite/gfortran.dg/warning-directive-2.F90 =================================================================== --- gcc/testsuite/gfortran.dg/warning-directive-2.F90 (revision 0) +++ gcc/testsuite/gfortran.dg/warning-directive-2.F90 (revision 0) @@ -0,0 +1,5 @@ +! { dg-do preprocess } +! { dg-options "-std=f95 -fdiagnostics-show-option -Werror=warning-directive" } + +#warning "Printed" +! { dg-error "\"Printed\" .-Wwarning-directive." "" { target *-*-* } 4 } Index: gcc/testsuite/gfortran.dg/warning-directive-4.F90 =================================================================== --- gcc/testsuite/gfortran.dg/warning-directive-4.F90 (revision 0) +++ gcc/testsuite/gfortran.dg/warning-directive-4.F90 (revision 0) @@ -0,0 +1,5 @@ +! { dg-do preprocess } +! { dg-options "-std=f95 -fdiagnostics-show-option -Wno-warning-directive" } + +#warning "Not printed" +! { dg-bogus "." "" { target *-*-* } 4 } Index: gcc/c-tree.h =================================================================== --- gcc/c-tree.h (revision 153803) +++ gcc/c-tree.h (working copy) @@ -608,8 +608,8 @@ extern void c_write_global_declarations 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: gcc/opts.c =================================================================== --- gcc/opts.c (revision 153803) +++ gcc/opts.c (working copy) @@ -2364,6 +2364,19 @@ set_option (const struct cl_option *opti } } + +/* 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)) +{ + 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. */ @@ -2383,14 +2396,20 @@ enable_warning_as_error (const char *arg } 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); - - /* -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 (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; + + if (warning_as_error_callback) + warning_as_error_callback (option_index); + } } free (new_option); } Index: gcc/opts.h =================================================================== --- gcc/opts.h (revision 153803) +++ gcc/opts.h (working copy) @@ -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: gcc/fortran/cpp.c =================================================================== --- gcc/fortran/cpp.c (revision 153803) +++ gcc/fortran/cpp.c (working copy) @@ -137,9 +137,9 @@ static void cb_include (cpp_reader *, so 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, sourc } /* 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 ATTRIBUT location, dlevel); if (column_override) diagnostic_override_column (&diagnostic, column_override); + if (reason == CPP_W_WARNING_DIRECTIVE) + diagnostic_override_option_index (&diagnostic, OPT_Wwarning_directive); ret = report_diagnostic (&diagnostic); if (level == CPP_DL_WARNING_SYSHDR) warn_system_headers = save_warn_system_headers; Index: gcc/c-opts.c =================================================================== --- gcc/c-opts.c (revision 153803) +++ gcc/c-opts.c (working copy) @@ -196,6 +196,90 @@ defer_opt (enum opt_code code, const cha 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_Wwarning_directive: + /* 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 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: gcc/common.opt =================================================================== --- gcc/common.opt (revision 153803) +++ gcc/common.opt (working copy) @@ -228,6 +228,10 @@ Wunused-variable Common Var(warn_unused_variable) Init(-1) Warning Warn when a variable is unused +Wwarning-directive +Common Var(warn_warning_directive) Init(1) Warning +Warn when a #warning directive is encountered + Wcoverage-mismatch Common RejectNegative Var(warn_coverage_mismatch) Warning Warn instead of error in case profiles in -fprofile-use do not match Index: gcc/c-common.c =================================================================== --- gcc/c-common.c (revision 153803) +++ gcc/c-common.c (working copy) @@ -8245,8 +8245,52 @@ c_parse_error (const char *gmsgid, enum #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_Wwarning_directive}, + {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 @@ -8254,7 +8298,7 @@ c_parse_error (const char *gmsgid, enum 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) { @@ -8301,6 +8345,8 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE 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: libcpp/macro.c =================================================================== --- libcpp/macro.c (revision 153803) +++ libcpp/macro.c (working copy) @@ -83,8 +83,8 @@ _cpp_warn_if_unused_macro (cpp_reader *p 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, 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); @@ -1582,13 +1582,14 @@ parse_params (cpp_reader *pfile, cpp_mac 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); @@ -1891,10 +1892,14 @@ _cpp_create_definition (cpp_reader *pfil 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: libcpp/Makefile.in =================================================================== --- libcpp/Makefile.in (revision 153803) +++ libcpp/Makefile.in (working copy) @@ -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: libcpp/directives.c =================================================================== --- libcpp/directives.c (revision 153803) +++ libcpp/directives.c (working copy) @@ -104,7 +104,7 @@ static const char *parse_include (cpp_re 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); @@ -353,8 +353,8 @@ directive_diagnostics (cpp_reader *pfile 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 @@ -366,16 +366,16 @@ directive_diagnostics (cpp_reader *pfile 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); } } @@ -1043,7 +1043,7 @@ _cpp_do_file_change (cpp_reader *pfile, /* 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; @@ -1057,21 +1057,26 @@ do_diagnostic (cpp_reader *pfile, int co 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. */ @@ -1501,7 +1506,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: libcpp/include/cpplib.h =================================================================== --- libcpp/include/cpplib.h (revision 153803) +++ libcpp/include/cpplib.h (working copy) @@ -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". */ @@ -826,25 +826,57 @@ cpp_num cpp_num_sign_extend (cpp_num, si 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. */ @@ -853,8 +885,18 @@ extern bool cpp_errno (cpp_reader *, int /* 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: libcpp/pch.c =================================================================== --- libcpp/pch.c (revision 153803) +++ libcpp/pch.c (working copy) @@ -480,9 +480,9 @@ cpp_valid_state (cpp_reader *r, const ch || 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; } @@ -502,9 +502,9 @@ cpp_valid_state (cpp_reader *r, const ch 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; } @@ -514,7 +514,7 @@ cpp_valid_state (cpp_reader *r, const ch || 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, @@ -555,9 +555,9 @@ cpp_valid_state (cpp_reader *r, const ch 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; } } @@ -575,9 +575,9 @@ cpp_valid_state (cpp_reader *r, const ch 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; } Index: libcpp/errors.c =================================================================== --- libcpp/errors.c (revision 153803) +++ libcpp/errors.c (working copy) @@ -28,16 +28,16 @@ along with this program; see the file CO #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 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, { 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: libcpp/expr.c =================================================================== --- libcpp/expr.c (revision 153803) +++ libcpp/expr.c (working copy) @@ -365,9 +365,9 @@ cpp_classify_number (cpp_reader *pfile, 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 @@ -411,21 +411,27 @@ cpp_classify_number (cpp_reader *pfile, 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; } @@ -786,8 +792,8 @@ eval_token (cpp_reader *pfile, const cpp 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; @@ -800,8 +806,8 @@ eval_token (cpp_reader *pfile, const cpp 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; @@ -1496,8 +1502,8 @@ num_unary_op (cpp_reader *pfile, cpp_num { 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: libcpp/lex.c =================================================================== --- libcpp/lex.c (revision 153803) +++ libcpp/lex.c (working copy) @@ -301,14 +301,16 @@ _cpp_process_line_notes (cpp_reader *pfi && (!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); } @@ -353,9 +355,10 @@ _cpp_skip_block_comment (cpp_reader *pfi && 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') @@ -458,11 +461,11 @@ warn_about_normalization (cpp_reader *pf 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); } } @@ -563,9 +566,9 @@ lex_identifier (cpp_reader *pfile, const /* 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; @@ -1373,7 +1376,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: libcpp/charset.c =================================================================== --- libcpp/charset.c (revision 153803) +++ libcpp/charset.c (working copy) @@ -993,9 +993,9 @@ _cpp_valid_ucn (cpp_reader *pfile, const 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 uc 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 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; @@ -1522,7 +1522,7 @@ narrow_str_to_charconst (cpp_reader *pfi "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) |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsOn Tue, 3 Nov 2009, Simon Baldwin wrote:
> Thank you for the review -- inlined responses below. > > I've attached a revised and corrected version of the patch to the > mail; bootstrap C/C++/Fortran and appropriate suite re-done. Please > take a second look. Thanks. The C and cpplib parts of the revised patch are OK. You still need review of the Fortran, diagnostic.h and opts.[ch] parts. -- Joseph S. Myers joseph@... |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsSimon Baldwin <simonb@...> writes:
> gcc/ChangeLog: > 2009-11-02 Simon Baldwin <simonb@...> > > * 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-warning-directive 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-warning-directive. > > gcc/fortran/ChangeLog: > 2009-11-02 Simon Baldwin <simonb@...> > > * cpp.c (cb_cpp_error): Add warning reason argument, set a value > for diagnostic_override_option_index if CPP_W_WARNING_DIRECTIVE. > > libcpp/ChangeLog: > 2009-11-02 Simon Baldwin <simonb@...> > > * 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, _cpp_lex_direct): Ditto. > * charset.c (_cpp_valid_ucn, convert_hex, convert_escape, > narrow_str_to_charconst): Ditto. > > gcc/testsuite/ChangeLog: > 2009-11-02 Simon Baldwin <simonb@...> > > * 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. > +/* Override the option index to be used for reporting a > + diagnostic. */ > +#define diagnostic_override_option_index(DI, OPTIDX) \ > + (DI)->option_index = (OPTIDX) Please put parentheses around the macro expansion. > +/* 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)) > +{ > + warning_as_error_callback = callback; > +} Since there can only be one callback, please add something along the lines of gcc_assert (warning_as_error_callback == NULL || callback == NULL); This is OK with those changes. Thanks. Ian |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsOn Tue, Nov 3, 2009 at 6:25 AM, Simon Baldwin <simonb@...> wrote:
> Thank you for the review -- inlined responses below. > > I've attached a revised and corrected version of the patch to the > mail; bootstrap C/C++/Fortran and appropriate suite re-done. Please > take a second look. Thanks. My earlier comments were about the name of the command line. It is misleading. We are not warning #warning. Please, change the name to something like -Wcpp or better. Wwarning-directive sounds as if we were warning about #warning themselves. -- Gaby |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warnings2009/11/8 Gabriel Dos Reis <dosreis@...>
> > On Tue, Nov 3, 2009 at 6:25 AM, Simon Baldwin <simonb@...> wrote: > > Thank you for the review -- inlined responses below. > > > > I've attached a revised and corrected version of the patch to the > > mail; bootstrap C/C++/Fortran and appropriate suite re-done. Please > > take a second look. Thanks. > > My earlier comments were about the name of the command line. It is > misleading. We are not warning #warning. Please, change the > name to something like -Wcpp or better. Wwarning-directive > sounds as if we were warning about #warning themselves. Neither -Wcomment nor -Wsystem-headers behave in the way this reading of their names might suggest, yet both are accepted. However, -Wcpp sounds worse to me. The preprocessor can issue several warnings, and -Wcpp sounds like it controls them all. In fact, only the output of #warning is what's affected here. -Wwarning-directive has the advantage of being relatively short and easy to remember, and also contains "warning" and so is likely to be found in a man or text search. Please let me know precisely what you would like this command line flag to be called, and I will change it to that. Thanks, --S -- Google UK Limited | Registered Office: Belgrave House, 76 Buckingham Palace Road, London SW1W 9TQ | Registered in England Number: 3977902 |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsOn Mon, Nov 9, 2009 at 5:16 AM, Simon Baldwin <simonb@...> wrote:
> 2009/11/8 Gabriel Dos Reis <dosreis@...> >> >> On Tue, Nov 3, 2009 at 6:25 AM, Simon Baldwin <simonb@...> wrote: >> > Thank you for the review -- inlined responses below. >> > >> > I've attached a revised and corrected version of the patch to the >> > mail; bootstrap C/C++/Fortran and appropriate suite re-done. Please >> > take a second look. Thanks. >> >> My earlier comments were about the name of the command line. It is >> misleading. We are not warning #warning. Please, change the >> name to something like -Wcpp or better. Wwarning-directive >> sounds as if we were warning about #warning themselves. > > Neither -Wcomment nor -Wsystem-headers behave in the way this reading > of their names might suggest, yet both are accepted. I believe building on 'exceptions' to make the list of exceptions long is wrong headed and a wrong excuse. > > However, -Wcpp sounds worse to me. The preprocessor can issue several > warnings, and -Wcpp sounds like it controls them all. In fact, only > the output of #warning is what's affected here. -Wwarning-directive > has the advantage of being relatively short and easy to remember, well, it is not shorter than 'cpp', and the issue is not 'easy to remember' -- both would be. > and > also contains "warning" and so is likely to be found in a man or text > search. -W already standard for 'warn'. > > Please let me know precisely what you would like this command line > flag to be called, and I will change it to that. I believe I did. -- Gaby |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warnings2009/11/9 Gabriel Dos Reis <gdr@...>:
> ... >> Please let me know precisely what you would like this command line >> flag to be called, and I will change it to that. > > I believe I did. "...to something like -Wcpp or better" didn't seem all that precise to me. Nevertheless I will change the patch to use this in place of -Wwarning-directive and repost the updated version once it's completed testing Please take another look when ready. Thanks, --S -- Google UK Limited | Registered Office: Belgrave House, 76 Buckingham Palace Road, London SW1W 9TQ | Registered in England Number: 3977902 |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsOn Mon, Nov 9, 2009 at 7:47 AM, Simon Baldwin <simonb@...> wrote:
> 2009/11/9 Gabriel Dos Reis <gdr@...>: >> ... >>> Please let me know precisely what you would like this command line >>> flag to be called, and I will change it to that. >> >> I believe I did. > > "...to something like -Wcpp or better" didn't seem all that precise to me. > > Nevertheless I will change the patch to use this in place of > -Wwarning-directive and repost the updated version once it's completed > testing Please take another look when ready. Thanks! -- Gaby |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsAttached below is the updated version of this patch, incorporating
Ian's gcc_assert() and macro expansion parenthesis changes, and Gaby's change of warning flag name from -Wwarning-directive to -Wcpp. Okay for trunk? I think that's everything covered, so I'll submit in a few days if no further comments. Thanks. -- Google UK Limited | Registered Office: Belgrave House, 76 Buckingham Palace Road, London SW1W 9TQ | Registered in England Number: 3977902 [cpp_warnings.patch] This patch brings several preprocessor warnings under the control of the -Werror= gcc flag. At present, gcc does not associate preprocessor warnings with gcc command line options, and so such warnings cannot be controlled individually with -Werror=. With the patch in place, preprocessor warnings can now be set separately as errors with -Werror=, disabled as errors with -Wno-error=, and will report their corresponding gcc diagnostic flag with -fdiagnostics-show-option when requested. The patch also adds a new gcc option -W[no-]cpp so that the output of #warning operates symmetrically to other gcc warnings, and in particular so that the combination "-Werror -Wno-error=cpp" allows all warnings except for #warning directives to be treated as errors. Confirmed C, C++ and Fortran dejagnu testsuite parity with the unpatched gcc, and verified bootstrap of C/C++/Fortran on x86_64. gcc/ChangeLog: 2009-11-09 Simon Baldwin <simonb@...> * 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. gcc/fortran/ChangeLog: 2009-11-09 Simon Baldwin <simonb@...> * cpp.c (cb_cpp_error): Add warning reason argument, set a value for diagnostic_override_option_index if CPP_W_WARNING_DIRECTIVE. libcpp/ChangeLog: 2009-11-09 Simon Baldwin <simonb@...> * 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, _cpp_lex_direct): Ditto. * charset.c (_cpp_valid_ucn, convert_hex, convert_escape, narrow_str_to_charconst): Ditto. gcc/testsuite/ChangeLog: 2009-11-09 Simon Baldwin <simonb@...> * 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. Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 153803) +++ gcc/doc/invoke.texi (working copy) @@ -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 @@ -2936,6 +2936,11 @@ Warn whenever a comment-start sequence @ 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: gcc/diagnostic.h =================================================================== --- gcc/diagnostic.h (revision 153803) +++ gcc/diagnostic.h (working copy) @@ -190,6 +190,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: gcc/testsuite/gcc.dg/cpp/warn-undef-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-undef-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-undef-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-traditional-2.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-comments-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-comments-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-comments-2.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-1.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-1.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-1.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wcpp." } Index: gcc/testsuite/gcc.dg/cpp/warn-long-long.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-long-long.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-long-long.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-traditional.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-traditional.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-traditional.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-variadic-2.c (revision 0) @@ -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." } */ Index: gcc/testsuite/gcc.dg/cpp/warn-undef.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-undef.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-undef.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-normalized-1.c (revision 0) @@ -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=." } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-2.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=cpp" } + +#warning "Printed" // { dg-error "\"Printed\" .-Wcpp." } Index: gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-long-long-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-variadic.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-variadic.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-variadic.c (revision 0) @@ -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." } */ Index: gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-normalized-2.c (revision 0) @@ -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=." } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-3.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-3.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-3.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror -Wno-error=cpp" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wcpp." } Index: gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-deprecated-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-1.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -trigraphs -Wtrigraphs" } + +??= // { dg-warning "trigraph \\?\\?= converted to # .-Wtrigraphs." } Index: gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-multichar-2.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c (revision 0) @@ -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=." } Index: gcc/testsuite/gcc.dg/cpp/warning-directive-4.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warning-directive-4.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warning-directive-4.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wno-cpp" } + +#warning "Not printed" // { dg-bogus "." } Index: gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-unused-macros.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-2.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Wtrigraphs" } + +??= // { dg-warning "trigraph \\?\\?= ignored, use -trigraphs to enable .-Wtrigraphs." } Index: gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-cxx-compat-2.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-cxx-compat.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-redefined.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-redefined.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-redefined.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-3.c (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -trigraphs -Werror=trigraphs" } + +??= // { dg-error "trigraph \\?\\?= converted to # .-Wtrigraphs." } Index: gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-unused-macros-2.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-deprecated.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-deprecated.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-deprecated.c (revision 0) @@ -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 Index: gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-trigraphs-4.c (revision 0) @@ -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." } Index: gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-redefined-2.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warn-comments.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-comments.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-comments.c (revision 0) @@ -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 } Index: gcc/testsuite/gcc.dg/cpp/warn-multichar.c =================================================================== --- gcc/testsuite/gcc.dg/cpp/warn-multichar.c (revision 0) +++ gcc/testsuite/gcc.dg/cpp/warn-multichar.c (revision 0) @@ -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 Index: gcc/testsuite/g++.dg/cpp/warning-directive-1.C =================================================================== --- gcc/testsuite/g++.dg/cpp/warning-directive-1.C (revision 0) +++ gcc/testsuite/g++.dg/cpp/warning-directive-1.C (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-fdiagnostics-show-option" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wcpp." } Index: gcc/testsuite/g++.dg/cpp/warning-directive-2.C =================================================================== --- gcc/testsuite/g++.dg/cpp/warning-directive-2.C (revision 0) +++ gcc/testsuite/g++.dg/cpp/warning-directive-2.C (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-fdiagnostics-show-option -Werror=cpp" } + +#warning "Printed" // { dg-error "\"Printed\" .-Wcpp." } Index: gcc/testsuite/g++.dg/cpp/warning-directive-3.C =================================================================== --- gcc/testsuite/g++.dg/cpp/warning-directive-3.C (revision 0) +++ gcc/testsuite/g++.dg/cpp/warning-directive-3.C (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-fdiagnostics-show-option -Werror -Wno-error=cpp" } + +#warning "Printed" // { dg-warning "\"Printed\" .-Wcpp." } Index: gcc/testsuite/g++.dg/cpp/warning-directive-4.C =================================================================== --- gcc/testsuite/g++.dg/cpp/warning-directive-4.C (revision 0) +++ gcc/testsuite/g++.dg/cpp/warning-directive-4.C (revision 0) @@ -0,0 +1,4 @@ +// { dg-do preprocess } +// { dg-options "-fdiagnostics-show-option -Wno-cpp" } + +#warning "Not printed" // { dg-bogus "." } Index: gcc/testsuite/gfortran.dg/warning-directive-1.F90 =================================================================== --- gcc/testsuite/gfortran.dg/warning-directive-1.F90 (revision 0) +++ gcc/testsuite/gfortran.dg/warning-directive-1.F90 (revision 0) @@ -0,0 +1,5 @@ +! { dg-do preprocess } +! { dg-options "-std=f95 -fdiagnostics-show-option" } + +#warning "Printed" +! { dg-warning "\"Printed\" .-Wcpp." "" { target *-*-* } 4 } Index: gcc/testsuite/gfortran.dg/warning-directive-3.F90 =================================================================== --- gcc/testsuite/gfortran.dg/warning-directive-3.F90 (revision 0) +++ gcc/testsuite/gfortran.dg/warning-directive-3.F90 (revision 0) @@ -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 } Index: gcc/testsuite/gfortran.dg/warning-directive-2.F90 =================================================================== --- gcc/testsuite/gfortran.dg/warning-directive-2.F90 (revision 0) +++ gcc/testsuite/gfortran.dg/warning-directive-2.F90 (revision 0) @@ -0,0 +1,5 @@ +! { dg-do preprocess } +! { dg-options "-std=f95 -fdiagnostics-show-option -Werror=cpp" } + +#warning "Printed" +! { dg-error "\"Printed\" .-Wcpp." "" { target *-*-* } 4 } Index: gcc/testsuite/gfortran.dg/warning-directive-4.F90 =================================================================== --- gcc/testsuite/gfortran.dg/warning-directive-4.F90 (revision 0) +++ gcc/testsuite/gfortran.dg/warning-directive-4.F90 (revision 0) @@ -0,0 +1,5 @@ +! { dg-do preprocess } +! { dg-options "-std=f95 -fdiagnostics-show-option -Wno-cpp" } + +#warning "Not printed" +! { dg-bogus "." "" { target *-*-* } 4 } Index: gcc/c-tree.h =================================================================== --- gcc/c-tree.h (revision 153803) +++ gcc/c-tree.h (working copy) @@ -608,8 +608,8 @@ extern void c_write_global_declarations 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: gcc/opts.c =================================================================== --- gcc/opts.c (revision 153803) +++ gcc/opts.c (working copy) @@ -2364,6 +2364,20 @@ set_option (const struct cl_option *opti } } + +/* 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. */ @@ -2383,14 +2397,20 @@ enable_warning_as_error (const char *arg } 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); - - /* -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 (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; + + if (warning_as_error_callback) + warning_as_error_callback (option_index); + } } free (new_option); } Index: gcc/opts.h =================================================================== --- gcc/opts.h (revision 153803) +++ gcc/opts.h (working copy) @@ -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: gcc/fortran/cpp.c =================================================================== --- gcc/fortran/cpp.c (revision 153803) +++ gcc/fortran/cpp.c (working copy) @@ -137,9 +137,9 @@ static void cb_include (cpp_reader *, so 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, sourc } /* 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 ATTRIBUT 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 AT } cpp_undefine_queue = NULL; } - - Index: gcc/c-opts.c =================================================================== --- gcc/c-opts.c (revision 153803) +++ gcc/c-opts.c (working copy) @@ -196,6 +196,90 @@ defer_opt (enum opt_code code, const cha 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 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: gcc/common.opt =================================================================== --- gcc/common.opt (revision 153803) +++ gcc/common.opt (working copy) @@ -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: gcc/c-common.c =================================================================== --- gcc/c-common.c (revision 153803) +++ gcc/c-common.c (working copy) @@ -8245,8 +8245,52 @@ c_parse_error (const char *gmsgid, enum #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 @@ -8254,7 +8298,7 @@ c_parse_error (const char *gmsgid, enum 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) { @@ -8301,6 +8345,8 @@ c_cpp_error (cpp_reader *pfile ATTRIBUTE 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: libcpp/macro.c =================================================================== --- libcpp/macro.c (revision 153803) +++ libcpp/macro.c (working copy) @@ -83,8 +83,8 @@ _cpp_warn_if_unused_macro (cpp_reader *p 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, 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); @@ -1582,13 +1582,14 @@ parse_params (cpp_reader *pfile, cpp_mac 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); @@ -1891,10 +1892,14 @@ _cpp_create_definition (cpp_reader *pfil 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: libcpp/Makefile.in =================================================================== --- libcpp/Makefile.in (revision 153803) +++ libcpp/Makefile.in (working copy) @@ -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: libcpp/directives.c =================================================================== --- libcpp/directives.c (revision 153803) +++ libcpp/directives.c (working copy) @@ -104,7 +104,7 @@ static const char *parse_include (cpp_re 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); @@ -353,8 +353,8 @@ directive_diagnostics (cpp_reader *pfile 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 @@ -366,16 +366,16 @@ directive_diagnostics (cpp_reader *pfile 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); } } @@ -1043,7 +1043,7 @@ _cpp_do_file_change (cpp_reader *pfile, /* 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; @@ -1057,21 +1057,26 @@ do_diagnostic (cpp_reader *pfile, int co 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. */ @@ -1501,7 +1506,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: libcpp/include/cpplib.h =================================================================== --- libcpp/include/cpplib.h (revision 153803) +++ libcpp/include/cpplib.h (working copy) @@ -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". */ @@ -826,25 +826,57 @@ cpp_num cpp_num_sign_extend (cpp_num, si 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. */ @@ -853,8 +885,18 @@ extern bool cpp_errno (cpp_reader *, int /* 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: libcpp/pch.c =================================================================== --- libcpp/pch.c (revision 153803) +++ libcpp/pch.c (working copy) @@ -480,9 +480,9 @@ cpp_valid_state (cpp_reader *r, const ch || 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; } @@ -502,9 +502,9 @@ cpp_valid_state (cpp_reader *r, const ch 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; } @@ -514,7 +514,7 @@ cpp_valid_state (cpp_reader *r, const ch || 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, @@ -555,9 +555,9 @@ cpp_valid_state (cpp_reader *r, const ch 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; } } @@ -575,9 +575,9 @@ cpp_valid_state (cpp_reader *r, const ch 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; } Index: libcpp/errors.c =================================================================== --- libcpp/errors.c (revision 153803) +++ libcpp/errors.c (working copy) @@ -28,16 +28,16 @@ along with this program; see the file CO #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 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, { 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: libcpp/expr.c =================================================================== --- libcpp/expr.c (revision 153803) +++ libcpp/expr.c (working copy) @@ -365,9 +365,9 @@ cpp_classify_number (cpp_reader *pfile, 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 @@ -411,21 +411,27 @@ cpp_classify_number (cpp_reader *pfile, 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; } @@ -786,8 +792,8 @@ eval_token (cpp_reader *pfile, const cpp 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; @@ -800,8 +806,8 @@ eval_token (cpp_reader *pfile, const cpp 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; @@ -1496,8 +1502,8 @@ num_unary_op (cpp_reader *pfile, cpp_num { 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: libcpp/lex.c =================================================================== --- libcpp/lex.c (revision 153803) +++ libcpp/lex.c (working copy) @@ -301,14 +301,16 @@ _cpp_process_line_notes (cpp_reader *pfi && (!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); } @@ -353,9 +355,10 @@ _cpp_skip_block_comment (cpp_reader *pfi && 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') @@ -458,11 +461,11 @@ warn_about_normalization (cpp_reader *pf 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); } } @@ -563,9 +566,9 @@ lex_identifier (cpp_reader *pfile, const /* 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; @@ -1373,7 +1376,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: libcpp/charset.c =================================================================== --- libcpp/charset.c (revision 153803) +++ libcpp/charset.c (working copy) @@ -993,9 +993,9 @@ _cpp_valid_ucn (cpp_reader *pfile, const 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 uc 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 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; @@ -1522,7 +1522,7 @@ narrow_str_to_charconst (cpp_reader *pfi "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) |
|
|
Re: [PATCH][RFA] Enabling -W[no-]error=... for cpplib warningsOn Tue, Nov 10, 2009 at 4:29 AM, Simon Baldwin <simonb@...> wrote:
> Attached below is the updated version of this patch, incorporating > Ian's gcc_assert() and macro expansion parenthesis changes, and Gaby's > change of warning flag name from -Wwarning-directive to -Wcpp. > > Okay for trunk? I think that's everything covered, so I'll submit in > a few days if no further comments. Thanks. OK. -- Gaby |
| Free embeddable forum powered by Nabble | Forum Help |