[c-family/49654/49655] reject invalid options in pragma diagnostic
authorManuel López-Ibáñez <manu@gcc.gnu.org>
Wed, 23 Sep 2015 13:07:07 +0000 (13:07 +0000)
committerManuel López-Ibáñez <manu@gcc.gnu.org>
Wed, 23 Sep 2015 13:07:07 +0000 (13:07 +0000)
Use find_opt instead of linear search through options in
handle_pragma_diagnostic (PR 49654) and reject non-warning options and
options not valid for the current language (PR 49655).

gcc/testsuite/ChangeLog:

2015-09-23  Manuel López-Ibáñez  <manu@gcc.gnu.org>

PR c/49655
* gcc.dg/pragma-diag-6.c: New test.

gcc/ChangeLog:

2015-09-23  Manuel López-Ibáñez  <manu@gcc.gnu.org>

PR c/49655
* opts.h (write_langs): Declare.
* opts-global.c (write_langs): Make it extern.

gcc/c-family/ChangeLog:

2015-09-23  Manuel López-Ibáñez  <manu@gcc.gnu.org>

PR c/49654
PR c/49655
* c-pragma.c (handle_pragma_diagnostic): Detect non-warning
options and options not valid for the current language.

From-SVN: r228049

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-pragma.c
gcc/opts-global.c
gcc/opts.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pragma-diag-6.c [new file with mode: 0644]

index 2ec3abeb60157f67f601cc191f3536c233203582..eba5f94c573c7032e534fe35fed29356d3431d88 100644 (file)
@@ -1,3 +1,9 @@
+2015-09-23  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR c/49655
+       * opts.h (write_langs): Declare.
+       * opts-global.c (write_langs): Make it extern.
+
 2015-09-23  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/67391
index e887735f58b972824541b7506e271a49958500dc..8d4df7654b77f898b665fc243f829d274b4059ec 100644 (file)
@@ -1,3 +1,10 @@
+2015-09-23  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR c/49654
+       PR c/49655
+       * c-pragma.c (handle_pragma_diagnostic): Detect non-warning
+       options and options not valid for the current language.
+
 2015-09-22  Patrick Palka  <ppalka@gcc.gnu.org>
 
        * c-indentation.c (should_warn_for_misleading_indentation):
index de2304e788eee1fbee58dfdf71f5e23c47f01ac9..3c348009ceada82e4c1c7253b5d6b028f4c14356 100644 (file)
@@ -749,22 +749,40 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
       return;
     }
 
+  const char *option_string = TREE_STRING_POINTER (x);
+  unsigned int lang_mask = c_common_option_lang_mask () | CL_COMMON;
+  /* option_string + 1 to skip the initial '-' */
+  unsigned int option_index = find_opt (option_string + 1, lang_mask);
+  if (option_index == OPT_SPECIAL_unknown)
+    {
+      warning_at (loc, OPT_Wpragmas,
+                 "unknown option after %<#pragma GCC diagnostic%> kind");
+      return;
+    }
+  else if (!(cl_options[option_index].flags & CL_WARNING))
+    {
+      warning_at (loc, OPT_Wpragmas,
+                 "%qs is not an option that controls warnings", option_string);
+      return;
+    }
+  else if (!(cl_options[option_index].flags & lang_mask))
+    {
+      char *ok_langs = write_langs (cl_options[option_index].flags);
+      char *bad_lang = write_langs (c_common_option_lang_mask ());
+      warning_at (loc, OPT_Wpragmas,
+                 "option %qs is valid for %s but not for %s",
+                 option_string, ok_langs, bad_lang);
+      free (ok_langs);
+      free (bad_lang);
+      return;
+    }
+
   struct cl_option_handlers handlers;
   set_default_handlers (&handlers);
-
-  unsigned int option_index;
-  const char *option_string = TREE_STRING_POINTER (x);
-  for (option_index = 0; option_index < cl_options_count; option_index++)
-    if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
-      {
-       control_warning_option (option_index, (int) kind, kind != DK_IGNORED,
-                               input_location, c_family_lang_mask, &handlers,
-                               &global_options, &global_options_set,
-                               global_dc);
-       return;
-      }
-  warning_at (loc, OPT_Wpragmas,
-             "unknown option after %<#pragma GCC diagnostic%> kind");
+  control_warning_option (option_index, (int) kind, kind != DK_IGNORED,
+                         loc, lang_mask, &handlers,
+                         &global_options, &global_options_set,
+                         global_dc);
 }
 
 /*  Parse #pragma GCC target (xxx) to set target specific options.  */
index 9f5050b1cab5439cf0b99de7c20b4cfbe6d858fb..05e2e37aed633c035ec181e02e79b4fb3a8a8330 100644 (file)
@@ -54,7 +54,7 @@ unsigned num_in_fnames;
 
 /* Return a malloced slash-separated list of languages in MASK.  */
 
-static char *
+char *
 write_langs (unsigned int mask)
 {
   unsigned int n = 0, len = 0;
index 3cfd151fb620adfcfaeb1810ec8e47234a53b5ac..38b38370fb53080bfba385f4c56ec3d3a812eb53 100644 (file)
@@ -368,6 +368,7 @@ extern void control_warning_option (unsigned int opt_index, int kind,
                                    struct gcc_options *opts,
                                    struct gcc_options *opts_set,
                                    diagnostic_context *dc);
+extern char *write_langs (unsigned int mask);
 extern void print_ignored_options (void);
 extern void handle_common_deferred_options (void);
 extern bool common_handle_option (struct gcc_options *opts,
index 3e722c2c89c48421f7120b431be9df0636d10ac0..46d4f053130c05eba137a811b4ec9e71f20d0b30 100644 (file)
@@ -1,3 +1,8 @@
+2015-09-23  Manuel López-Ibáñez  <manu@gcc.gnu.org>
+
+       PR c/49655
+       * gcc.dg/pragma-diag-6.c: New test.
+
 2015-09-23  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * gcc.target/aarch64/advsimd-intrinsics/vcvt_high_1.c: New.
diff --git a/gcc/testsuite/gcc.dg/pragma-diag-6.c b/gcc/testsuite/gcc.dg/pragma-diag-6.c
new file mode 100644 (file)
index 0000000..6ce76d9
--- /dev/null
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+#pragma GCC diagnostic error "-Wnoexcept" /* { dg-warning "is valid for C../ObjC.. but not for C" } */
+#pragma GCC diagnostic error "-fstrict-aliasing" /* { dg-warning "not an option that controls warnings" } */
+#pragma GCC diagnostic error "-Werror" /* { dg-warning "not an option that controls warnings" } */
+int i;