From 63bbf46d5f44f34a54f4e9cff62377516633fb7f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 8 Dec 2015 14:26:35 +0100 Subject: [PATCH] re PR c/48088 (-Werror=frame-larger-than=100 does not work as expected) PR c/48088 PR c/68657 * common.opt (Wframe-larger-than=): Add Warning. * opts.h (control_warning_option): Add ARG argument. * opts-common.c (cmdline_handle_error): New function. (read_cmdline_option): Use it. (control_warning_option): Likewise. Add ARG argument. If non-NULL, decode it if needed and pass through to handle_generated_option. Handle CLVC_ENUM like CLVC_BOOLEAN. * opts.c (common_handle_option): Adjust control_warning_option caller. (enable_warning_as_error): Likewise. c-family/ * c.opt (Wfloat-conversion, Wsign-conversion): Add Warning. * c-pragma.c (handle_pragma_diagnostic): Adjust control_warning_option caller. ada/ * gcc-interface/trans.c (Pragma_to_gnu): Adjust control_warning_option caller. testsuite/ * c-c++-common/pr68657-1.c: New test. * c-c++-common/pr68657-2.c: New test. * c-c++-common/pr68657-3.c: New test. * gcc.dg/cpp/warn-normalized-3.c: Use -Werror=normalized=nfc instead of -Werror=normalized= in dg-options. From-SVN: r231406 --- gcc/ChangeLog | 16 ++ gcc/ada/ChangeLog | 7 + gcc/ada/gcc-interface/trans.c | 5 +- gcc/c-family/ChangeLog | 8 + gcc/c-family/c-pragma.c | 6 +- gcc/c-family/c.opt | 4 +- gcc/common.opt | 2 +- gcc/opts-common.c | 162 +++++++++++++------ gcc/opts.c | 7 +- gcc/opts.h | 2 +- gcc/testsuite/ChangeLog | 11 ++ gcc/testsuite/c-c++-common/pr68657-1.c | 26 +++ gcc/testsuite/c-c++-common/pr68657-2.c | 8 + gcc/testsuite/c-c++-common/pr68657-3.c | 13 ++ gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c | 2 +- 15 files changed, 224 insertions(+), 55 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr68657-1.c create mode 100644 gcc/testsuite/c-c++-common/pr68657-2.c create mode 100644 gcc/testsuite/c-c++-common/pr68657-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 217c78f7045..093d9a252f4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2015-12-08 Jakub Jelinek + + PR c/48088 + PR c/68657 + * common.opt (Wframe-larger-than=): Add Warning. + * opts.h (control_warning_option): Add ARG argument. + * opts-common.c (cmdline_handle_error): New function. + (read_cmdline_option): Use it. + (control_warning_option): Likewise. Add ARG argument. + If non-NULL, decode it if needed and pass through + to handle_generated_option. Handle CLVC_ENUM like + CLVC_BOOLEAN. + * opts.c (common_handle_option): Adjust control_warning_option + caller. + (enable_warning_as_error): Likewise. + 2015-12-08 Matthew Wahab * config/aarch64/aarch64-options-extensions.def: Remove diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 2a7f18c162f..81afef88d86 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,10 @@ +2015-12-08 Jakub Jelinek + + PR c/48088 + PR c/68657 + * gcc-interface/trans.c (Pragma_to_gnu): Adjust + control_warning_option caller. + 2015-12-06 Piotr Trojanek PR ada/60164 diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 143d2144dcc..d565854a94d 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -1441,6 +1441,7 @@ Pragma_to_gnu (Node_Id gnat_node) /* This is the same implementation as in the C family of compilers. */ const unsigned int lang_mask = CL_Ada | CL_COMMON; + const char *arg = NULL; if (Present (gnat_expr)) { tree gnu_expr = gnat_to_gnu (gnat_expr); @@ -1464,12 +1465,14 @@ Pragma_to_gnu (Node_Id gnat_node) post_error ("?-W switch not valid for Ada", gnat_node); break; } + if (cl_options[option_index].flags & CL_JOINED) + arg = option_string + 1 + cl_options[option_index].opt_len; } else option_index = 0; set_default_handlers (&handlers); - control_warning_option (option_index, (int) kind, imply, location, + control_warning_option (option_index, (int) kind, arg, imply, location, lang_mask, &handlers, &global_options, &global_options_set, global_dc); } diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 03a66eb2212..18ec7a1c747 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2015-12-08 Jakub Jelinek + + PR c/48088 + PR c/68657 + * c.opt (Wfloat-conversion, Wsign-conversion): Add Warning. + * c-pragma.c (handle_pragma_diagnostic): Adjust + control_warning_option caller. + 2015-12-07 David Malcolm * c-common.c (c_cpp_error): Update for change to diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index 56cf6976fc9..56ed677bb22 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -814,7 +814,11 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) struct cl_option_handlers handlers; set_default_handlers (&handlers); - control_warning_option (option_index, (int) kind, kind != DK_IGNORED, + const char *arg = NULL; + if (cl_options[option_index].flags & CL_JOINED) + arg = option_string + 1 + cl_options[option_index].opt_len; + control_warning_option (option_index, (int) kind, + arg, kind != DK_IGNORED, loc, lang_mask, &handlers, &global_options, &global_options_set, global_dc); diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index aafd80207b1..6531d3af84d 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -435,7 +435,7 @@ C ObjC RejectNegative Warning Alias(Werror=, implicit-function-declaration) This switch is deprecated; use -Werror=implicit-function-declaration instead. Wfloat-conversion -C ObjC C++ ObjC++ Var(warn_float_conversion) LangEnabledBy(C ObjC C++ ObjC++,Wconversion) +C ObjC C++ ObjC++ Var(warn_float_conversion) Warning LangEnabledBy(C ObjC C++ ObjC++,Wconversion) Warn for implicit type conversions that cause loss of floating point precision. Wfloat-equal @@ -837,7 +837,7 @@ C ObjC C++ ObjC++ EnabledBy(Wextra) ; Wsign-conversion -C ObjC C++ ObjC++ Var(warn_sign_conversion) LangEnabledBy(C ObjC,Wconversion) +C ObjC C++ ObjC++ Var(warn_sign_conversion) Warning LangEnabledBy(C ObjC,Wconversion) Warn for implicit type conversions between signed and unsigned integers. Wsign-promo diff --git a/gcc/common.opt b/gcc/common.opt index 1de4c24fbc6..b1591d5d49b 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -581,7 +581,7 @@ Common Var(flag_fatal_errors) Exit on the first error occurred. Wframe-larger-than= -Common RejectNegative Joined UInteger +Common RejectNegative Joined UInteger Warning -Wframe-larger-than= Warn if a function's stack frame requires more than bytes. Wfree-nonheap-object diff --git a/gcc/opts-common.c b/gcc/opts-common.c index 24967cc4a25..507358a1d17 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -1021,62 +1021,42 @@ generate_option_input_file (const char *file, decoded->errors = 0; } -/* Handle the switch DECODED (location LOC) for the language indicated - by LANG_MASK, using the handlers in *HANDLERS and setting fields in - OPTS and OPTS_SET and using diagnostic context DC (if not NULL) for - diagnostic options. */ +/* Perform diagnostics for read_cmdline_option and control_warning_option + functions. Returns true if an error has been diagnosed. + LOC and LANG_MASK arguments like in read_cmdline_option. + OPTION is the option to report diagnostics for, OPT the name + of the option as text, ARG the argument of the option (for joined + options), ERRORS is bitmask of CL_ERR_* values. */ -void -read_cmdline_option (struct gcc_options *opts, - struct gcc_options *opts_set, - struct cl_decoded_option *decoded, - location_t loc, - unsigned int lang_mask, - const struct cl_option_handlers *handlers, - diagnostic_context *dc) +static bool +cmdline_handle_error (location_t loc, const struct cl_option *option, + const char *opt, const char *arg, int errors, + unsigned int lang_mask) { - const struct cl_option *option; - const char *opt = decoded->orig_option_with_args_text; - - if (decoded->warn_message) - warning_at (loc, 0, decoded->warn_message, opt); - - if (decoded->opt_index == OPT_SPECIAL_unknown) - { - if (handlers->unknown_option_callback (decoded)) - error_at (loc, "unrecognized command line option %qs", decoded->arg); - return; - } - - if (decoded->opt_index == OPT_SPECIAL_ignore) - return; - - option = &cl_options[decoded->opt_index]; - - if (decoded->errors & CL_ERR_DISABLED) + if (errors & CL_ERR_DISABLED) { error_at (loc, "command line option %qs" - " is not supported by this configuration", opt); - return; + " is not supported by this configuration", opt); + return true; } - if (decoded->errors & CL_ERR_MISSING_ARG) + if (errors & CL_ERR_MISSING_ARG) { if (option->missing_argument_error) error_at (loc, option->missing_argument_error, opt); else error_at (loc, "missing argument to %qs", opt); - return; + return true; } - if (decoded->errors & CL_ERR_UINT_ARG) + if (errors & CL_ERR_UINT_ARG) { error_at (loc, "argument to %qs should be a non-negative integer", option->opt_text); - return; + return true; } - if (decoded->errors & CL_ERR_ENUM_ARG) + if (errors & CL_ERR_ENUM_ARG) { const struct cl_enum *e = &cl_enums[option->var_enum]; unsigned int i; @@ -1084,7 +1064,7 @@ read_cmdline_option (struct gcc_options *opts, char *s, *p; if (e->unknown_error) - error_at (loc, e->unknown_error, decoded->arg); + error_at (loc, e->unknown_error, arg); else error_at (loc, "unrecognized argument in option %qs", opt); @@ -1105,9 +1085,49 @@ read_cmdline_option (struct gcc_options *opts, } p[-1] = 0; inform (loc, "valid arguments to %qs are: %s", option->opt_text, s); + return true; + } + + return false; +} + +/* Handle the switch DECODED (location LOC) for the language indicated + by LANG_MASK, using the handlers in *HANDLERS and setting fields in + OPTS and OPTS_SET and using diagnostic context DC (if not NULL) for + diagnostic options. */ + +void +read_cmdline_option (struct gcc_options *opts, + struct gcc_options *opts_set, + struct cl_decoded_option *decoded, + location_t loc, + unsigned int lang_mask, + const struct cl_option_handlers *handlers, + diagnostic_context *dc) +{ + const struct cl_option *option; + const char *opt = decoded->orig_option_with_args_text; + + if (decoded->warn_message) + warning_at (loc, 0, decoded->warn_message, opt); + + if (decoded->opt_index == OPT_SPECIAL_unknown) + { + if (handlers->unknown_option_callback (decoded)) + error_at (loc, "unrecognized command line option %qs", decoded->arg); return; } + if (decoded->opt_index == OPT_SPECIAL_ignore) + return; + + option = &cl_options[decoded->opt_index]; + + if (decoded->errors + && cmdline_handle_error (loc, option, opt, decoded->arg, + decoded->errors, lang_mask)) + return; + if (decoded->errors & CL_ERR_WRONG_LANG) { handlers->wrong_lang_callback (decoded, lang_mask); @@ -1327,13 +1347,14 @@ get_option_state (struct gcc_options *opts, int option, /* Set a warning option OPT_INDEX (language mask LANG_MASK, option handlers HANDLERS) to have diagnostic kind KIND for option structures OPTS and OPTS_SET and diagnostic context DC (possibly - NULL), at location LOC (UNKNOWN_LOCATION for -Werror=). If IMPLY, + NULL), at location LOC (UNKNOWN_LOCATION for -Werror=). ARG is the + argument of the option for joined options, or NULL otherwise. If IMPLY, the warning option in question is implied at this point. This is used by -Werror= and #pragma GCC diagnostic. */ void -control_warning_option (unsigned int opt_index, int kind, bool imply, - location_t loc, unsigned int lang_mask, +control_warning_option (unsigned int opt_index, int kind, const char *arg, + bool imply, location_t loc, unsigned int lang_mask, const struct cl_option_handlers *handlers, struct gcc_options *opts, struct gcc_options *opts_set, @@ -1347,10 +1368,59 @@ control_warning_option (unsigned int opt_index, int kind, bool imply, diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc); if (imply) { + const struct cl_option *option = &cl_options[opt_index]; + /* -Werror=foo implies -Wfoo. */ - if (cl_options[opt_index].var_type == CLVC_BOOLEAN) - handle_generated_option (opts, opts_set, - opt_index, NULL, 1, lang_mask, - kind, loc, handlers, dc); + if (option->var_type == CLVC_BOOLEAN || option->var_type == CLVC_ENUM) + { + int value = 1; + + if (arg && *arg == '\0' && !option->cl_missing_ok) + arg = NULL; + + if ((option->flags & CL_JOINED) && arg == NULL) + { + cmdline_handle_error (loc, option, option->opt_text, arg, + CL_ERR_MISSING_ARG, lang_mask); + return; + } + + /* If the switch takes an integer, convert it. */ + if (arg && option->cl_uinteger) + { + value = integral_argument (arg); + if (value == -1) + { + cmdline_handle_error (loc, option, option->opt_text, arg, + CL_ERR_UINT_ARG, lang_mask); + return; + } + } + + /* If the switch takes an enumerated argument, convert it. */ + if (arg && option->var_type == CLVC_ENUM) + { + const struct cl_enum *e = &cl_enums[option->var_enum]; + + if (enum_arg_to_value (e->values, arg, &value, lang_mask)) + { + const char *carg = NULL; + + if (enum_value_to_arg (e->values, &carg, value, lang_mask)) + arg = carg; + gcc_assert (carg != NULL); + } + else + { + cmdline_handle_error (loc, option, option->opt_text, arg, + CL_ERR_ENUM_ARG, lang_mask); + return; + } + } + + handle_generated_option (opts, opts_set, + opt_index, arg, value, lang_mask, + kind, loc, handlers, dc); + } } } diff --git a/gcc/opts.c b/gcc/opts.c index 874c84fec5b..3d25f98c9e2 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -2114,7 +2114,7 @@ common_handle_option (struct gcc_options *opts, case OPT_pedantic_errors: dc->pedantic_errors = 1; - control_warning_option (OPT_Wpedantic, DK_ERROR, value, + control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value, loc, lang_mask, handlers, opts, opts_set, dc); @@ -2437,8 +2437,11 @@ enable_warning_as_error (const char *arg, int value, unsigned int lang_mask, else { const diagnostic_t kind = value ? DK_ERROR : DK_WARNING; + const char *arg = NULL; - control_warning_option (option_index, (int) kind, value, + if (cl_options[option_index].flags & CL_JOINED) + arg = new_option + cl_options[option_index].opt_len; + control_warning_option (option_index, (int) kind, arg, value, loc, lang_mask, handlers, opts, opts_set, dc); } diff --git a/gcc/opts.h b/gcc/opts.h index 2eb2d9735c6..60222ef53de 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -363,7 +363,7 @@ extern void read_cmdline_option (struct gcc_options *opts, const struct cl_option_handlers *handlers, diagnostic_context *dc); extern void control_warning_option (unsigned int opt_index, int kind, - bool imply, location_t loc, + const char *arg, bool imply, location_t loc, unsigned int lang_mask, const struct cl_option_handlers *handlers, struct gcc_options *opts, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e7aa6ea2cdc..c970caf6fc3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2015-12-08 Jakub Jelinek + + PR c/48088 + PR c/68657 + * c-c++-common/pr68657-1.c: New test. + * c-c++-common/pr68657-2.c: New test. + * c-c++-common/pr68657-3.c: New test. + * gcc.dg/cpp/warn-normalized-3.c: Use + -Werror=normalized=nfc instead of -Werror=normalized= + in dg-options. + 2015-12-08 Christophe Lyon * lib/target-supports.exp diff --git a/gcc/testsuite/c-c++-common/pr68657-1.c b/gcc/testsuite/c-c++-common/pr68657-1.c new file mode 100644 index 00000000000..3db6f49d00d --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr68657-1.c @@ -0,0 +1,26 @@ +/* PR c/68657 */ +/* { dg-options "-Werror=sign-conversion -Werror=float-conversion -Werror=frame-larger-than=65536" } */ + +void +f1 (void) +{ + unsigned int a = -5; /* { dg-error "negative integer implicitly converted to unsigned type" } */ + (void) a; +} + +int +f2 (void) +{ + return 3.1f; /* { dg-error "conversion to 'int' alters 'float' constant value" } */ +} + +int f3 (char *); + +int +f4 (void) +{ + char buf[131072]; + return f3 (buf); +} /* { dg-error "the frame size of 1\[0-9]* bytes is larger than 65536 bytes" } */ + +/* { dg-prune-output "treated as errors" } */ diff --git a/gcc/testsuite/c-c++-common/pr68657-2.c b/gcc/testsuite/c-c++-common/pr68657-2.c new file mode 100644 index 00000000000..9eb68ce38e7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr68657-2.c @@ -0,0 +1,8 @@ +/* PR c/68657 */ +/* { dg-do compile } */ +/* { dg-options "-Werror=larger-than=65536" } */ + +int a[131072]; /* { dg-error "size of 'a' is \[1-9]\[0-9]* bytes" } */ +int b[1024]; /* { dg-bogus "size of 'b' is \[1-9]\[0-9]* bytes" } */ + +/* { dg-prune-output "treated as errors" } */ diff --git a/gcc/testsuite/c-c++-common/pr68657-3.c b/gcc/testsuite/c-c++-common/pr68657-3.c new file mode 100644 index 00000000000..84622fc2e60 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr68657-3.c @@ -0,0 +1,13 @@ +/* PR c/68657 */ +/* { dg-do compile } */ + +#pragma GCC diagnostic error "-Wlarger-than=65536" +int a[131072]; /* { dg-error "size of 'a' is \[1-9]\[0-9]* bytes" } */ +int b[1024]; /* { dg-bogus "size of 'b' is \[1-9]\[0-9]* bytes" } */ +#pragma GCC diagnostic ignored "-Wlarger-than=65536" +int c[131072]; /* { dg-bogus "size of 'c' is \[1-9]\[0-9]* bytes" } */ +int d[1024]; /* { dg-bogus "size of 'd' is \[1-9]\[0-9]* bytes" } */ +#pragma GCC diagnostic warning "-Wlarger-than=65536" +int e[131072]; /* { dg-warning "size of 'e' is \[1-9]\[0-9]* bytes" } */ +int f[1024]; /* { dg-bogus "size of 'f' is \[1-9]\[0-9]* bytes" } */ +/* { dg-prune-output "treated as errors" } */ diff --git a/gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c b/gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c index 2251e2836b2..225fc4de01d 100644 --- a/gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c +++ b/gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c @@ -1,4 +1,4 @@ // { dg-do preprocess } -// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=normalized=" } +// { dg-options "-std=gnu99 -fdiagnostics-show-option -Werror=normalized=nfc" } /* { dg-message "some warnings being treated as errors" "" {target "*-*-*"} 0 } */ \u0F43 // { dg-error "`.U00000f43' is not in NFC .-Werror=normalized=." } -- 2.30.2