aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel López-Ibáñez <manu@gcc.gnu.org>2015-09-23 13:07:07 +0000
committerManuel López-Ibáñez <manu@gcc.gnu.org>2015-09-23 13:07:07 +0000
commitc1822f9c9b169c9588a110522dd60d579edaf6d1 (patch)
tree36263b59f5fe1b8892bd6bafafc963cd33e5923f
parent9ea4e88f177aec6d897055efc954b4de05766017 (diff)
downloadgcc-c1822f9c9b169c9588a110522dd60d579edaf6d1.zip
gcc-c1822f9c9b169c9588a110522dd60d579edaf6d1.tar.gz
gcc-c1822f9c9b169c9588a110522dd60d579edaf6d1.tar.bz2
[c-family/49654/49655] reject invalid options in pragma diagnostic
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-family/ChangeLog7
-rw-r--r--gcc/c-family/c-pragma.c46
-rw-r--r--gcc/opts-global.c2
-rw-r--r--gcc/opts.h1
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pragma-diag-6.c5
7 files changed, 57 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2ec3abe..eba5f94 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index e887735..8d4df76 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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):
diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c
index de2304e..3c34800 100644
--- a/gcc/c-family/c-pragma.c
+++ b/gcc/c-family/c-pragma.c
@@ -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. */
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 9f5050b..05e2e37 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -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;
diff --git a/gcc/opts.h b/gcc/opts.h
index 3cfd151..38b3837 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -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,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3e722c2..46d4f05 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..6ce76d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pragma-diag-6.c
@@ -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;