[PATCH/PR c/59304] #pragma diagnostic pop after warning fails for options unspecified in the command-line and disabled by default

Manuel López-Ibáñez lopezibanez@gmail.com
Tue Aug 19 18:01:00 GMT 2014


The idea is that when we see a change of classification, and the
option was originally unspecified, we record the command-line status.
This way, when doing pop later, we already check if the option was
reclassified so we get the command-line status. This also works with
-Wall, since all dependent options go through set_option and call
diagnostic_classify_diagnostic. But we have to call it before changing
the option status.

Bootstrapped and regression tested on x86_64-linux-gnu.

OK?

gcc/ChangeLog:

2014-08-19  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR c/59304
    * opts-common.c (set_option): Call diagnostic_classify_diagnostic
    before setting the option.
    * diagnostic.c (diagnostic_classify_diagnostic): Record
    command-line status.

gcc/testsuite/ChangeLog:

2014-08-19  Manuel López-Ibáñez  <manu@gcc.gnu.org>

    PR c/59304
    * gcc.dg/pr59304.c: New test.
-------------- next part --------------
Index: gcc/opts-common.c
===================================================================
--- gcc/opts-common.c	(revision 214136)
+++ gcc/opts-common.c	(working copy)
@@ -1117,10 +1117,13 @@ set_option (struct gcc_options *opts, st
   void *set_flag_var = NULL;
 
   if (!flag_var)
     return;
 
+  if ((diagnostic_t) kind != DK_UNSPECIFIED && dc != NULL)
+    diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc);
+
   if (opts_set != NULL)
     set_flag_var = option_flag_var (opt_index, opts_set);
 
   switch (option->var_type)
     {
@@ -1196,14 +1199,10 @@ set_option (struct gcc_options *opts, st
 	  if (set_flag_var)
 	    *(void **) set_flag_var = v;
 	}
 	break;
     }
-
-  if ((diagnostic_t) kind != DK_UNSPECIFIED
-      && dc != NULL)
-    diagnostic_classify_diagnostic (dc, opt_index, (diagnostic_t) kind, loc);
 }
 
 /* Return the address of the flag variable for option OPT_INDEX in
    options structure OPTS, or NULL if there is no flag variable.  */
 
Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 214136)
+++ gcc/diagnostic.c	(working copy)
@@ -582,10 +582,19 @@ diagnostic_classify_diagnostic (diagnost
      the pragmas were.  */
   if (where != UNKNOWN_LOCATION)
     {
       int i;
 
+      /* Record the command-line status, so we can reset it back on DK_POP. */
+      if (old_kind == DK_UNSPECIFIED)
+	{
+	  old_kind = context->option_enabled (option_index,
+					      context->option_state)
+	    ? DK_WARNING : DK_IGNORED;
+	  context->classify_diagnostic[option_index] = old_kind;
+	}
+
       for (i = context->n_classification_history - 1; i >= 0; i --)
 	if (context->classification_history[i].option == option_index)
 	  {
 	    old_kind = context->classification_history[i].kind;
 	    break;
Index: gcc/testsuite/gcc.dg/pr59304.c
===================================================================
--- gcc/testsuite/gcc.dg/pr59304.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr59304.c	(revision 0)
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+enum EE
+  {
+    ONE, TWO, THREE
+  };
+
+int f (enum EE e)
+{
+  int r = 0;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic error "-Wswitch-enum"
+
+  switch (e)
+    {
+    case ONE:
+      r = 1;
+      break;
+    case TWO:
+      r = 2;
+      break;
+    case THREE:
+      r = 3;
+      break;
+    }
+
+#pragma GCC diagnostic pop
+
+  switch (e)
+    {
+    case ONE:
+      r = 1;
+      break;
+    case TWO:
+      r = 2;
+      break;
+    }
+
+  return r;
+}


More information about the Gcc-patches mailing list