public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: DJ Delorie <dj@redhat.com>
To: joseph@codesourcery.com
Cc: gdr@cs.tamu.edu, mark@codesourcery.com, lopezibanez@gmail.com,
	        ghazi@caip.rutgers.edu, gcc-patches@gcc.gnu.org
Subject: Re: Add a __nowarn__ keyword
Date: Tue, 21 Aug 2007 03:24:00 -0000	[thread overview]
Message-ID: <200708210221.l7L2LRFW022114@greed.delorie.com> (raw)
In-Reply-To: <Pine.LNX.4.64.0708111911250.12511@digraph.polyomino.org.uk> 	(joseph@codesourcery.com)


Patch so far.  I added some code to fill in the origin array in the
global_dc to what the switch "means" before we go and change it, so
that using the table results in the same effect as if we had never
changed the switch.

I haven't tried to do anything with the mapped-location in the source.
Recording the location is easy (I think), but to take advantage of it
we'd probably have to restructure the classification tree some so that
we can search it.  Plus, there may be minor changes to the diagnostic
API to pass the current location to the diagnostics module.  Unless we
already think the location information we have access to is reliable?
The diagnostics do print the file and line with each message...



Index: diagnostic.c
===================================================================
--- diagnostic.c	(revision 127658)
+++ diagnostic.c	(working copy)
@@ -53,12 +53,13 @@ static void default_diagnostic_finalizer
 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
 static bool diagnostic_count_diagnostic (diagnostic_context *,
 					 diagnostic_info *);
 static void diagnostic_action_after_output (diagnostic_context *,
 					    diagnostic_info *);
 static void real_abort (void) ATTRIBUTE_NORETURN;
+static int lookup_classification (diagnostic_context *, int);
 
 /* A diagnostic_context surrogate for stderr.  */
 static diagnostic_context global_diagnostic_context;
 diagnostic_context *global_dc = &global_diagnostic_context;
 
 \f
@@ -325,17 +326,75 @@ diagnostic_classify_diagnostic (diagnost
 
   if (option_index <= 0
       || option_index >= N_OPTS
       || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
     return DK_UNSPECIFIED;
 
+  if (context->classification_state)
+    {
+      diagnostic_classification_state_t *state;
+
+      old_kind = lookup_classification (context, option_index);
+      state = (diagnostic_classification_state_t *)
+	xmalloc (sizeof (diagnostic_classification_state_t));
+
+      state->previous = context->classification_state;
+      state->option_index = option_index;
+      state->kind = new_kind;
+      context->classification_state = state;
+
+      return old_kind;
+    }
+
   old_kind = context->classify_diagnostic[option_index];
   context->classify_diagnostic[option_index] = new_kind;
   return old_kind;
 }
 
+static int
+lookup_classification (diagnostic_context * context, int option_index)
+{
+  if (option_index <= 0
+      || option_index >= N_OPTS)
+    return DK_UNSPECIFIED;
+
+  if (context->classification_state)
+    {
+      diagnostic_classification_state_t *s;
+      for (s = context->classification_state;
+	   s; s = s->previous)
+	{
+	  if (s->option_index == option_index)
+	    return s->kind;
+	}
+    }
+  return context->classify_diagnostic[option_index];
+}
+
+diagnostic_classification_state_t *
+diagnostic_save_classifications (diagnostic_context *context)
+{
+  if (context->classification_state == NULL)
+    {
+      /* Create the head of the chain.  */
+      context->classification_state = (diagnostic_classification_state_t *)
+	xmalloc (sizeof (diagnostic_classification_state_t));
+      context->classification_state->previous = NULL;
+      context->classification_state->option_index = 0;
+      context->classification_state->kind = context->classify_diagnostic[0];
+    }
+  return context->classification_state;
+}
+
+void
+diagnostic_restore_classifications (diagnostic_context *context,
+				    diagnostic_classification_state_t *state)
+{
+  context->classification_state = state;
+}
+
 /* Report a diagnostic message (an error or a warning) as specified by
    DC.  This function is *the* subroutine in terms of which front-ends
    should implement their specific diagnostic handling modules.  The
    front-end independent format specifiers are exactly those described
    in the documentation of output_format.  */
 
@@ -372,21 +431,23 @@ diagnostic_report_diagnostic (diagnostic
       diagnostic->kind = DK_ERROR;
       maybe_print_warnings_as_errors_message = true;
     }
   
   if (diagnostic->option_index)
     {
+      int kind;
       /* This tests if the user provided the appropriate -Wfoo or
 	 -Wno-foo option.  */
       if (! option_enabled (diagnostic->option_index))
 	return;
       /* This tests if the user provided the appropriate -Werror=foo
 	 option.  */
-      if (context->classify_diagnostic[diagnostic->option_index] != DK_UNSPECIFIED)
+      kind = lookup_classification (context, diagnostic->option_index);
+      if (kind != DK_UNSPECIFIED)
 	{
-	  diagnostic->kind = context->classify_diagnostic[diagnostic->option_index];
+	  diagnostic->kind = kind;
 	  maybe_print_warnings_as_errors_message = false;
 	}
       /* This allows for future extensions, like temporarily disabling
 	 warnings for ranges of source code.  */
       if (diagnostic->kind == DK_IGNORED)
 	return;
Index: diagnostic.h
===================================================================
--- diagnostic.h	(revision 127658)
+++ diagnostic.h	(working copy)
@@ -53,12 +53,19 @@ typedef struct
 /*  Forward declarations.  */
 typedef struct diagnostic_context diagnostic_context;
 typedef void (*diagnostic_starter_fn) (diagnostic_context *,
 				       diagnostic_info *);
 typedef diagnostic_starter_fn diagnostic_finalizer_fn;
 
+/* The diagnostic state is an opaque pointer.  */
+typedef struct diagnostic_classification_state_t {
+  struct diagnostic_classification_state_t *previous;
+  int option_index;
+  int kind;
+} diagnostic_classification_state_t;
+
 /* This data structure bundles altogether any information relevant to
    the context of a diagnostic message.  */
 struct diagnostic_context
 {
   /* Where most of the diagnostic formatting work is done.  */
   pretty_printer *printer;
@@ -77,12 +84,15 @@ struct diagnostic_context
      (OPT_* from options.h), this array may contain a new kind that
      the diagnostic should be changed to before reporting, or
      DK_UNSPECIFIED to leave it as the reported kind, or DK_IGNORED to
      not report it at all.  N_OPTS is from <options.h>.  */
   char classify_diagnostic[N_OPTS];
 
+  /* If non-NULL, this is the current state of changes to the above.  */
+  diagnostic_classification_state_t *classification_state;
+
   /* True if we should print the command line option which controls
      each diagnostic, if known.  */
   bool show_option_requested;
 
   /* True if we should raise a SIGABRT on errors.  */
   bool abort_on_error;
@@ -188,12 +198,24 @@ extern void diagnostic_report_current_mo
 extern void diagnostic_report_current_function (diagnostic_context *);
 
 /* Force diagnostics controlled by OPTIDX to be kind KIND.  */
 extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
 						    int /* optidx */,
 						    diagnostic_t /* kind */);
+
+/* This returns a token which represents the current state of the
+   diagnostic classifications.  */
+extern diagnostic_classification_state_t *
+  diagnostic_save_classifications (diagnostic_context *context);
+
+/* This returns the classifications to some previous point.  Further
+   changes to the classifications will be relative to this previous
+   point.  */
+extern void diagnostic_restore_classifications (diagnostic_context *context,
+						diagnostic_classification_state_t *);
+
 extern void diagnostic_report_diagnostic (diagnostic_context *,
 					  diagnostic_info *);
 #ifdef ATTRIBUTE_GCC_DIAG
 extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
 				 location_t, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);
 extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
Index: c-pragma.c
===================================================================
--- c-pragma.c	(revision 127658)
+++ c-pragma.c	(working copy)
@@ -814,39 +814,91 @@ handle_pragma_visibility (cpp_reader *du
   if (pragma_lex (&x) != CPP_EOF)
     warning (OPT_Wpragmas, "junk at end of %<#pragma GCC visibility%>");
 }
 
 #endif
 
+typedef struct diagnostic_stack_entry_t {
+  struct diagnostic_stack_entry_t *previous;
+  struct diagnostic_classification_state_t *state;
+} diagnostic_stack_entry_t;
+
+static diagnostic_stack_entry_t *diagnostic_stack = 0;
+
 static void
 handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
 {
   const char *kind_string, *option_string;
   unsigned int option_index;
   enum cpp_ttype token;
   diagnostic_t kind;
   tree x;
+  diagnostic_stack_entry_t *stack;
 
   if (cfun)
     {
       error ("#pragma GCC diagnostic not allowed inside functions");
       return;
     }
 
   token = pragma_lex (&x);
   if (token != CPP_NAME)
-    GCC_BAD ("missing [error|warning|ignored] after %<#pragma GCC diagnostic%>");
+    GCC_BAD ("missing [push|pop|error|warning|ignored] after %<#pragma GCC diagnostic%>");
   kind_string = IDENTIFIER_POINTER (x);
+
+  if (strcmp (kind_string, "push") == 0)
+    {
+      stack = (diagnostic_stack_entry_t *) xmalloc (sizeof (diagnostic_stack_entry_t));
+      stack->previous = diagnostic_stack;
+      stack->state = diagnostic_save_classifications (global_dc);
+      diagnostic_stack = stack;
+ 
+      token = pragma_lex (&x);
+      if (token != CPP_NAME)
+	return;
+      kind_string = IDENTIFIER_POINTER (x);
+    }
+  else if (strcmp (kind_string, "pop") == 0)
+    {
+      stack = diagnostic_stack;
+      if (!stack)
+	{
+	  error ("$pragma GCC diagnostic pop with no matching push");
+	  return;
+	}
+      diagnostic_stack = stack->previous;
+      diagnostic_restore_classifications (global_dc, stack->state);
+      free (stack);
+      return;
+    }
+#if 0
+  /* This is an example of how to do this, in case we decide to need
+     this functionality in the future.  "undo" moves one state up the
+     tree, effectively undoing the previous pragma.  It relies on
+     every pragma being in the state tree (which may be expensive), so
+     we must force the tree to exist somehow.  */
+  else if (strcmp (kind_string, "undo") == 0)
+    {
+      diagnostic_classification_state_t *state;
+      state = diagnostic_save_classifications (global_dc);
+      state = state->previous;
+      diagnostic_restore_classifications (global_dc, state);
+      return;
+    }
+  /* Here we force the state tree to exist for any change-type pragma.  */
+  diagnostic_save_classifications (global_dc);
+#endif
+
   if (strcmp (kind_string, "error") == 0)
     kind = DK_ERROR;
   else if (strcmp (kind_string, "warning") == 0)
     kind = DK_WARNING;
   else if (strcmp (kind_string, "ignored") == 0)
     kind = DK_IGNORED;
   else
-    GCC_BAD ("expected [error|warning|ignored] after %<#pragma GCC diagnostic%>");
+    GCC_BAD ("expected [push|pop|error|warning|ignored] after %<#pragma GCC diagnostic%>");
 
   token = pragma_lex (&x);
   if (token != CPP_STRING)
     GCC_BAD ("missing option after %<#pragma GCC diagnostic%> kind");
   option_string = TREE_STRING_POINTER (x);
   for (option_index = 0; option_index < cl_options_count; option_index++)
@@ -855,13 +907,29 @@ handle_pragma_diagnostic(cpp_reader *ARG
 	/* This overrides -Werror, for example.  */
 	diagnostic_classify_diagnostic (global_dc, option_index, kind);
 	/* This makes sure the option is enabled, like -Wfoo would do.  */
 	if (cl_options[option_index].var_type == CLVC_BOOLEAN
 	    && cl_options[option_index].flag_var
 	    && kind != DK_IGNORED)
+	  {
+	    /* Make the default setting explicit, in case we pop.  */
+	    if (global_dc->classify_diagnostic[option_index] == DK_UNSPECIFIED)
+	      {
+		if (*(int *) cl_options[option_index].flag_var)
+		  {
+		    if (global_dc->warning_as_error_requested)
+		      global_dc->classify_diagnostic[option_index] = DK_ERROR;
+		    else
+		      global_dc->classify_diagnostic[option_index] = DK_WARNING;
+		  }
+		else
+		  global_dc->classify_diagnostic[option_index] = DK_IGNORED;
+	      }
+	    /* And turn the option on.  */
 	    *(int *) cl_options[option_index].flag_var = 1;
+	  }
 	return;
       }
   GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
 }
 
 /* A vector of registered pragma callbacks.  */

  parent reply	other threads:[~2007-08-21  2:23 UTC|newest]

Thread overview: 86+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-27  8:15 [PATCH]: Fix problematic -Wcast-qual cases using new CONST_CAST macro Kaveh R. GHAZI
2007-07-27  9:53 ` Richard Guenther
2007-07-27 17:24   ` Kaveh R. GHAZI
2007-07-27 19:32     ` Richard Guenther
2007-07-27 19:37       ` Kaveh R. GHAZI
2007-07-27 20:28         ` Gabriel Dos Reis
2007-08-03 14:19         ` Kaveh R. GHAZI
2007-08-03 18:07           ` Gabriel Dos Reis
2007-08-06  0:19             ` Mark Mitchell
2007-08-06  0:32               ` Gabriel Dos Reis
2007-08-06  4:42                 ` Kaveh R. GHAZI
2007-08-06  5:23                   ` Mark Mitchell
2007-08-06 14:09                     ` Kaveh R. GHAZI
2007-08-06 15:33                       ` Gabriel Dos Reis
2007-08-06 17:59                         ` Kaveh R. GHAZI
2007-08-06 18:11                           ` DJ Delorie
2007-08-06 18:23                             ` Gabriel Dos Reis
2007-08-06 18:18                           ` Gabriel Dos Reis
2007-08-06 15:44                       ` Mark Mitchell
2007-08-08  5:04                         ` Add a __nowarn__ keyword Kaveh R. GHAZI
2007-08-08  8:52                           ` Manuel López-Ibáñez
2007-08-08  9:04                             ` Gabriel Dos Reis
2007-08-08 13:06                               ` Kaveh R. GHAZI
2007-08-08 13:16                                 ` Gabriel Dos Reis
2007-08-08 13:48                                   ` Kaveh R. GHAZI
2007-08-08 13:58                                     ` Paolo Bonzini
2007-08-10  1:42                                       ` Gabriel Dos Reis
2007-08-08 14:29                                     ` Manuel López-Ibáñez
2007-08-08 15:25                                       ` Daniel Jacobowitz
2007-08-08 16:35                                       ` Paolo Bonzini
2007-08-08 19:31                                         ` Kaveh R. GHAZI
2007-08-08 19:42                                           ` Gabriel Dos Reis
2007-08-08 20:22                                             ` Paolo Bonzini
2007-08-08 19:51                                           ` DJ Delorie
2007-08-08 22:41                                             ` Kaveh R. GHAZI
2007-08-08 22:54                                               ` DJ Delorie
2007-08-09  2:36                                                 ` Kaveh R. GHAZI
2007-08-09 13:40                                                   ` Daniel Jacobowitz
2007-08-09 14:19                                                     ` Kaveh R. GHAZI
2007-08-09 14:30                                                       ` Daniel Jacobowitz
2007-08-09 15:05                                                         ` Manuel López-Ibáñez
2007-08-09 15:15                                                           ` Daniel Jacobowitz
2007-08-09 15:31                                                           ` DJ Delorie
2007-08-09 22:23                                                             ` Mark Mitchell
2007-08-09 22:43                                                               ` Kaveh R. GHAZI
2007-08-10  1:52                                                                 ` Gabriel Dos Reis
2007-08-10 16:42                                                                 ` Mark Mitchell
2007-08-10  1:50                                                               ` Gabriel Dos Reis
2007-08-10  2:02                                                                 ` DJ Delorie
2007-08-10  3:09                                                                   ` Gabriel Dos Reis
2007-08-10  3:28                                                                     ` DJ Delorie
2007-08-10  3:44                                                                       ` Gabriel Dos Reis
2007-08-10  4:00                                                                         ` DJ Delorie
2007-08-10  4:12                                                                           ` Gabriel Dos Reis
2007-08-10  4:23                                                                             ` DJ Delorie
2007-08-10 13:24                                                                               ` Gabriel Dos Reis
2007-08-10 18:40                                                                             ` DJ Delorie
2007-08-11 19:19                                                                               ` Joseph S. Myers
2007-08-13 18:36                                                                                 ` DJ Delorie
2007-08-21  3:24                                                                                 ` DJ Delorie [this message]
2009-11-21 12:24                                                                                   ` Magnus Fromreide
2009-11-23 16:40                                                                                     ` Manuel López-Ibáñez
2009-11-23 23:28                                                                                     ` DJ Delorie
2007-08-10 19:05                                                                             ` DJ Delorie
2007-08-10 10:04                                                                       ` Manuel López-Ibáñez
2007-08-10 18:46                                                                         ` DJ Delorie
2007-08-09 15:21                                                         ` Kaveh R. GHAZI
2007-08-09 16:48                                                           ` Paolo Bonzini
2007-08-09 20:04                                                   ` Ian Lance Taylor
2007-08-09 20:40                                                     ` DJ Delorie
2007-08-10  1:47                                                   ` Gabriel Dos Reis
2007-08-09 14:41                                           ` Manuel López-Ibáñez
2007-08-09 16:36                                             ` Gabriel Dos Reis
2007-08-09 23:14                                               ` Kaveh R. GHAZI
2007-08-09 22:55                                             ` Kaveh R. GHAZI
2007-08-10  3:18                                               ` Kaveh R. GHAZI
2007-08-10  3:25                                                 ` Gabriel Dos Reis
2007-08-08 12:56                             ` Kaveh R. GHAZI
2007-08-08 14:05                               ` Manuel López-Ibáñez
2007-08-10  9:48 Paolo Bonzini
2007-08-10 16:53 ` Gabriel Dos Reis
2007-08-10 18:20   ` DJ Delorie
2007-08-10 18:40     ` Kaveh R. GHAZI
2007-08-10 18:52       ` DJ Delorie
2007-08-10 21:52 FX Coudert
2007-08-10 22:13 ` Kaveh R. GHAZI

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200708210221.l7L2LRFW022114@greed.delorie.com \
    --to=dj@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=gdr@cs.tamu.edu \
    --cc=ghazi@caip.rutgers.edu \
    --cc=joseph@codesourcery.com \
    --cc=lopezibanez@gmail.com \
    --cc=mark@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).