This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Make diagnostic pragmas use option handlers, clean up -Werror=


Following up on my patch
<http://gcc.gnu.org/ml/gcc-patches/2010-11/msg01174.html>, and
relative to a tree with
<http://gcc.gnu.org/ml/gcc-patches/2010-11/msg01317.html> (pending
review) applied, this patch further cleans up -Werror= and #pragma GCC
diagnostic handling.

enable_warning_as_error is made to take gcc_options parameters rather
than hardcoding use of global_options.  The core of that function is
made into the new control_warning_option, which is used by #pragma GCC
diagnostic as well as -Werror=.

As well as eliminating a hardcoding of global_options in option
handling, this sharing of code fixes various bugs by causing #pragma
GCC diagnostic to use option handlers; one such case is illustrated by
the testcase added.

Note that I left the linear search through options in #pragma GCC
diagnostic handling (which should use find_opt) as is.  I also did not
do anything about how this pragma can be used with *any* CLVC_BOOLEAN
option, not just warning options - I'm sure it must be possible to
produce ICEs that way by changing options at this point and bypassing
all the consistency checks and post-option processing done on the
command line.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
commit (the non-front-end parts)?

2010-11-12  Joseph Myers  <joseph@codesourcery.com>

	* opts-common.c (control_warning_option): New.
	* opts.c (set_default_handlers): New.
	(decode_options): Use set_default_handlers and
	control_warning_option.
	(common_handle_option): Update call to enable_warning_as_error.
	(enable_warning_as_error): Take gcc_options parameters.  Use
	control_warning_option.
	* opts.h (set_default_handlers, control_warning_option): Declare.

c-family:
2010-11-12  Joseph Myers  <joseph@codesourcery.com>

	* c-common.h (c_family_lang_mask): Declare.
	* c-opts.c (c_family_lang_mask): Make extern.
	* c-pragma.c (handle_pragma_diagnostic): Use
	control_warning_option.

testsuite:
2010-11-12  Joseph Myers  <joseph@codesourcery.com>

	* gcc.dg/pragma-diag-2.c: New test.

diff -rupN --exclude=.svn gcc-mainline-0/gcc/c-family/c-common.h gcc-mainline/gcc/c-family/c-common.h
--- gcc-mainline-0/gcc/c-family/c-common.h	2010-11-12 07:44:53.000000000 -0800
+++ gcc-mainline/gcc/c-family/c-common.h	2010-11-12 12:51:45.000000000 -0800
@@ -762,6 +762,7 @@ extern void set_compound_literal_name (t
 
 extern tree build_va_arg (location_t, tree, tree);
 
+extern const unsigned int c_family_lang_mask;
 extern unsigned int c_common_option_lang_mask (void);
 extern void c_common_initialize_diagnostics (diagnostic_context *);
 extern bool c_common_complain_wrong_lang_p (const struct cl_option *);
diff -rupN --exclude=.svn gcc-mainline-0/gcc/c-family/c-opts.c gcc-mainline/gcc/c-family/c-opts.c
--- gcc-mainline-0/gcc/c-family/c-opts.c	2010-11-12 07:45:36.000000000 -0800
+++ gcc-mainline/gcc/c-family/c-opts.c	2010-11-12 12:51:45.000000000 -0800
@@ -132,7 +132,7 @@ static struct deferred_opt
 } *deferred_opts;
 
 
-static const unsigned int 
+extern const unsigned int 
 c_family_lang_mask = (CL_C | CL_CXX | CL_ObjC | CL_ObjCXX);
 
 /* Defer option CODE with argument ARG.  */
@@ -467,6 +467,10 @@ c_common_handle_option (size_t scode, co
       cpp_opts->warn_invalid_pch = value;
       break;
 
+    case OPT_Wlong_long:
+      cpp_opts->cpp_warn_long_long = value;
+      break;
+
     case OPT_Wmissing_include_dirs:
       cpp_opts->warn_missing_include_dirs = value;
       break;
diff -rupN --exclude=.svn gcc-mainline-0/gcc/c-family/c-pragma.c gcc-mainline/gcc/c-family/c-pragma.c
--- gcc-mainline-0/gcc/c-family/c-pragma.c	2010-11-12 07:14:15.000000000 -0800
+++ gcc-mainline/gcc/c-family/c-pragma.c	2010-11-12 12:51:45.000000000 -0800
@@ -720,6 +720,7 @@ handle_pragma_diagnostic(cpp_reader *ARG
   enum cpp_ttype token;
   diagnostic_t kind;
   tree x;
+  struct cl_option_handlers handlers;
 
   token = pragma_lex (&x);
   if (token != CPP_NAME)
@@ -748,18 +749,14 @@ handle_pragma_diagnostic(cpp_reader *ARG
   if (token != CPP_STRING)
     GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
   option_string = TREE_STRING_POINTER (x);
+  set_default_handlers (&handlers);
   for (option_index = 0; option_index < cl_options_count; option_index++)
     if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
       {
-	void *flag_var = option_flag_var (option_index, &global_options);
-
-	/* This overrides -Werror, for example.  */
-	diagnostic_classify_diagnostic (global_dc, option_index, kind, input_location);
-	/* This makes sure the option is enabled, like -Wfoo would do.  */
-	if (cl_options[option_index].var_type == CLVC_BOOLEAN
-	    && flag_var
-	    && kind != DK_IGNORED)
-	    *(int *) flag_var = 1;
+	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;
       }
   GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
diff -rupN --exclude=.svn gcc-mainline-0/gcc/opts-common.c gcc-mainline/gcc/opts-common.c
--- gcc-mainline-0/gcc/opts-common.c	2010-11-12 08:03:34.000000000 -0800
+++ gcc-mainline/gcc/opts-common.c	2010-11-12 12:56:36.000000000 -0800
@@ -977,3 +977,34 @@ option_flag_var (int opt_index, struct g
     return NULL;
   return (void *)(((char *) opts) + option->flag_var_offset);
 }
+
+/* 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,
+   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,
+			const struct cl_option_handlers *handlers,
+			struct gcc_options *opts,
+			struct gcc_options *opts_set,
+			diagnostic_context *dc)
+{
+  if (cl_options[opt_index].alias_target != N_OPTS)
+    opt_index = cl_options[opt_index].alias_target;
+  if (opt_index == OPT_SPECIAL_ignore)
+    return;
+  if (dc)
+    diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc);
+  if (imply)
+    {
+      /* -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);
+    }
+}
diff -rupN --exclude=.svn gcc-mainline-0/gcc/opts.c gcc-mainline/gcc/opts.c
--- gcc-mainline-0/gcc/opts.c	2010-11-12 07:49:56.000000000 -0800
+++ gcc-mainline/gcc/opts.c	2010-11-12 12:55:33.000000000 -0800
@@ -363,6 +363,8 @@ static void set_unsafe_math_optimization
 static void enable_warning_as_error (const char *arg, int value,
 				     unsigned int lang_mask,
 				     const struct cl_option_handlers *handlers,
+				     struct gcc_options *opts,
+				     struct gcc_options *opts_set,
 				     location_t loc,
 				     diagnostic_context *dc);
 
@@ -1014,6 +1016,23 @@ default_options_optimization (struct gcc
 
 static void finish_options (struct gcc_options *, struct gcc_options *);
 
+/* Set *HANDLERS to the default set of option handlers for use in the
+   compilers proper (not the driver).  */
+void
+set_default_handlers (struct cl_option_handlers *handlers)
+{
+  handlers->unknown_option_callback = unknown_option_callback;
+  handlers->wrong_lang_callback = complain_wrong_lang;
+  handlers->post_handling_callback = post_handling_callback;
+  handlers->num_handlers = 3;
+  handlers->handlers[0].handler = lang_handle_option;
+  handlers->handlers[0].mask = initial_lang_mask;
+  handlers->handlers[1].handler = common_handle_option;
+  handlers->handlers[1].mask = CL_COMMON;
+  handlers->handlers[2].handler = target_handle_option;
+  handlers->handlers[2].mask = CL_TARGET;
+}
+
 /* Parse command line options and set default flag values.  Do minimal
    options processing.  The decoded options are in *DECODED_OPTIONS
    and *DECODED_OPTIONS_COUNT; settings go in OPTS, OPTS_SET and DC;
@@ -1030,20 +1049,12 @@ decode_options (struct gcc_options *opts
 
   lang_mask = initial_lang_mask;
 
-  handlers.unknown_option_callback = unknown_option_callback;
-  handlers.wrong_lang_callback = complain_wrong_lang;
-  handlers.post_handling_callback = post_handling_callback;
-  handlers.num_handlers = 3;
-  handlers.handlers[0].handler = lang_handle_option;
-  handlers.handlers[0].mask = lang_mask;
-  handlers.handlers[1].handler = common_handle_option;
-  handlers.handlers[1].mask = CL_COMMON;
-  handlers.handlers[2].handler = target_handle_option;
-  handlers.handlers[2].mask = CL_TARGET;
-
-  /* Enable -Werror=coverage-mismatch by default */
-  enable_warning_as_error ("coverage-mismatch", 1, lang_mask, &handlers,
-			   loc, dc);
+  set_default_handlers (&handlers);
+
+  /* Enable -Werror=coverage-mismatch by default.  */
+  control_warning_option (OPT_Wcoverage_mismatch, (int) DK_ERROR, true,
+			  loc, lang_mask,
+			  &handlers, opts, opts_set, dc);
 
   default_options_optimization (opts, opts_set,
 				decoded_options, decoded_options_count,
@@ -1783,7 +1794,8 @@ common_handle_option (struct gcc_options
       break;
 
     case OPT_Werror_:
-      enable_warning_as_error (arg, value, lang_mask, handlers, loc, dc);
+      enable_warning_as_error (arg, value, lang_mask, handlers,
+			       opts, opts_set, loc, dc);
       break;
 
     case OPT_Wlarger_than_:
@@ -2412,13 +2424,15 @@ get_option_state (struct gcc_options *op
 }
 
 /* Enable (or disable if VALUE is 0) a warning option ARG (language
-   mask LANG_MASK, option handlers HANDLERS) as an error for
-   diagnostic context DC (possibly NULL), location LOC.  This is used
-   by -Werror=.  */
+   mask LANG_MASK, option handlers HANDLERS) as an error for option
+   structures OPTS and OPTS_SET, diagnostic context DC (possibly
+   NULL), location LOC.  This is used by -Werror=.  */
 
 static void
 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
 			 const struct cl_option_handlers *handlers,
+			 struct gcc_options *opts,
+			 struct gcc_options *opts_set,
 			 location_t loc, diagnostic_context *dc)
 {
   char *new_option;
@@ -2430,29 +2444,15 @@ enable_warning_as_error (const char *arg
   option_index = find_opt (new_option, lang_mask);
   if (option_index == OPT_SPECIAL_unknown)
     {
-      error ("-Werror=%s: No option -%s", arg, new_option);
+      error ("-Werror=%s: no option -%s", arg, new_option);
     }
   else
     {
-      const struct cl_option *option = &cl_options[option_index];
       const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
 
-      if (option->alias_target != N_OPTS)
-	option_index = option->alias_target;
-      if (option_index == OPT_SPECIAL_ignore)
-	return;
-      if (dc)
-	diagnostic_classify_diagnostic (dc, option_index, kind, loc);
-      if (kind == DK_ERROR)
-	{
-	  const struct cl_option * const option = cl_options + option_index;
-
-	  /* -Werror=foo implies -Wfoo.  */
-	  if (option->var_type == CLVC_BOOLEAN)
-	    handle_generated_option (&global_options, &global_options_set,
-				     option_index, NULL, value, lang_mask,
-				     (int)kind, loc, handlers, dc);
-	}
+      control_warning_option (option_index, (int) kind, value,
+			      loc, lang_mask,
+			      handlers, opts, opts_set, dc);
     }
   free (new_option);
 }
diff -rupN --exclude=.svn gcc-mainline-0/gcc/opts.h gcc-mainline/gcc/opts.h
--- gcc-mainline-0/gcc/opts.h	2010-11-12 07:35:11.000000000 -0800
+++ gcc-mainline/gcc/opts.h	2010-11-12 12:52:31.000000000 -0800
@@ -223,6 +223,7 @@ extern void decode_cmdline_options_to_ar
 							  const char **argv, 
 							  struct cl_decoded_option **decoded_options,
 							  unsigned int *decoded_options_count);
+extern void set_default_handlers (struct cl_option_handlers *handlers);
 extern void decode_options (struct gcc_options *opts,
 			    struct gcc_options *opts_set,
 			    struct cl_decoded_option *decoded_options,
@@ -255,5 +256,12 @@ extern void read_cmdline_option (struct 
 				 unsigned int lang_mask,
 				 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,
+				    unsigned int lang_mask,
+				    const struct cl_option_handlers *handlers,
+				    struct gcc_options *opts,
+				    struct gcc_options *opts_set,
+				    diagnostic_context *dc);
 extern void print_ignored_options (void);
 #endif
diff -rupN --exclude=.svn gcc-mainline-0/gcc/testsuite/gcc.dg/pragma-diag-2.c gcc-mainline/gcc/testsuite/gcc.dg/pragma-diag-2.c
--- gcc-mainline-0/gcc/testsuite/gcc.dg/pragma-diag-2.c	1969-12-31 16:00:00.000000000 -0800
+++ gcc-mainline/gcc/testsuite/gcc.dg/pragma-diag-2.c	2010-11-12 12:51:45.000000000 -0800
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c89 -pedantic -Wno-long-long" } */
+/* { dg-message "warnings being treated as errors" "" { target *-*-* } 0 } */
+
+int i = 0LL;
+
+#pragma GCC diagnostic error "-Wlong-long"
+
+int j = 1LL; /* { dg-error "long long" } */

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]