re PR c/48088 (-Werror=frame-larger-than=100 does not work as expected)
authorJakub Jelinek <jakub@redhat.com>
Tue, 8 Dec 2015 13:26:35 +0000 (14:26 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 8 Dec 2015 13:26:35 +0000 (14:26 +0100)
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

15 files changed:
gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/gcc-interface/trans.c
gcc/c-family/ChangeLog
gcc/c-family/c-pragma.c
gcc/c-family/c.opt
gcc/common.opt
gcc/opts-common.c
gcc/opts.c
gcc/opts.h
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr68657-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr68657-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr68657-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/warn-normalized-3.c

index 217c78f7045966790e231820fa449ec78050d12d..093d9a252f4868d29223eaf87ec36875b2e3fff9 100644 (file)
@@ -1,3 +1,19 @@
+2015-12-08  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <matthew.wahab@arm.com>
 
        * config/aarch64/aarch64-options-extensions.def: Remove
index 2a7f18c162fb72970cc2f2447ac4503d98620768..81afef88d8676dfd199b0ea5ec72ca8371372024 100644 (file)
@@ -1,3 +1,10 @@
+2015-12-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/48088
+       PR c/68657
+       * gcc-interface/trans.c (Pragma_to_gnu): Adjust
+       control_warning_option caller.
+
 2015-12-06  Piotr Trojanek  <piotr.trojanek@gmail.com>
 
        PR ada/60164
index 143d2144dcc39ae63e0e9578ca7acef6f743d6a3..d565854a94ddbd7271ff3572bf98c3b0746a2ca8 100644 (file)
@@ -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);
       }
index 03a66eb22126eccc790b951e477e25b6852b5677..18ec7a1c74777667a7fe9ebca0fa732e2155a1f4 100644 (file)
@@ -1,3 +1,11 @@
+2015-12-08  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <dmalcolm@redhat.com>
 
        * c-common.c (c_cpp_error): Update for change to
index 56cf6976fc957f4c6e5309fb48a505e9250528db..56ed677bb22abba28d4fa342e414ab70bb8989d6 100644 (file)
@@ -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);
index aafd80207b1d9e52309455000069dbf70ba3718f..6531d3af84d81b787e2290c06459889953a0e9e0 100644 (file)
@@ -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
index 1de4c24fbc62280786c1be6eb2a5636aa56b9226..b1591d5d49b0658daa5131eb7c55753149064554 100644 (file)
@@ -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=<number>   Warn if a function's stack frame requires more than <number> bytes.
 
 Wfree-nonheap-object
index 24967cc4a252a149f0d9e58e1416079f4f99e866..507358a1d17d5f95772c8d7286145d03f680441e 100644 (file)
@@ -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);
+       }
     }
 }
index 874c84fec5b07b3c09515a9e33b10226aeeb2b48..3d25f98c9e2a9d0541133a60b0c08f5f00d3fb90 100644 (file)
@@ -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);
     }
index 2eb2d9735c6ab8ef98d61c56918dc5e651ebe12c..60222ef53de48feb0d685175d603b612cc186478 100644 (file)
@@ -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,
index e7aa6ea2cdc16779a1eb93f4473b8bbbb655cfbb..c970caf6fc320b2e807caaddcb81a8f4cfd04531 100644 (file)
@@ -1,3 +1,14 @@
+2015-12-08  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <christophe.lyon@linaro.org>
 
        * 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 (file)
index 0000000..3db6f49
--- /dev/null
@@ -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 (file)
index 0000000..9eb68ce
--- /dev/null
@@ -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 (file)
index 0000000..84622fc
--- /dev/null
@@ -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" } */
index 2251e2836b241a11f38b27d7484d43a2bead33f0..225fc4de01d815a1c2147fb4baa6f0f8cdcd499c 100644 (file)
@@ -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=." }