PR c/c++/diagnostics/66098 Take -Werror into account when deciding what was the command-line status
diff mbox

Message ID CAESRpQAhJJ6PncAzO6Tv4O6h4nQg1zvssKM9xTX98=AR7SMj2w@mail.gmail.com
State New
Headers show

Commit Message

Manuel López-Ibáñez July 30, 2015, 3:35 p.m. UTC
When I fixed PR59304, I forgot that a command-line warning can be also
an error if -Werror was enabled. This introduced a regression since
anything enabled in the command-line together with -Werror would get
initially classified as a warning when reaching the first #pragma GCC
diagnostic, and this will be the setting after a #pragma pop.

Options that appear as arguments of -W[no-]error= are not affected by
this since those are initially classified as errors/warnings even
before reaching the first #pragma, thus the pop sets them correctly
(before and after this patch). Nonetheless, the tests also check that
they work correctly.

Boot&regtested on x86_64-linux-gnu.

OK?


gcc/ChangeLog:

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

    PR c/66098
    PR c/66711
    * diagnostic.c (diagnostic_classify_diagnostic): Take -Werror into
    account when deciding what was the command-line status.

gcc/testsuite/ChangeLog:

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

    PR c/66098
    PR c/66711
    * gcc.dg/pragma-diag-3.c: New test.
    * gcc.dg/pragma-diag-4.c: New test.

Comments

Manuel López-Ibáñez Aug. 3, 2015, 6:47 p.m. UTC | #1
PING: https://gcc.gnu.org/ml/gcc-patches/2015-07/msg02581.html

Thanks,

Manuel.

On 30 July 2015 at 17:35, Manuel López-Ibáñez <lopezibanez@gmail.com> wrote:
> When I fixed PR59304, I forgot that a command-line warning can be also
> an error if -Werror was enabled. This introduced a regression since
> anything enabled in the command-line together with -Werror would get
> initially classified as a warning when reaching the first #pragma GCC
> diagnostic, and this will be the setting after a #pragma pop.
>
> Options that appear as arguments of -W[no-]error= are not affected by
> this since those are initially classified as errors/warnings even
> before reaching the first #pragma, thus the pop sets them correctly
> (before and after this patch). Nonetheless, the tests also check that
> they work correctly.
>
> Boot&regtested on x86_64-linux-gnu.
>
> OK?
>
>
> gcc/ChangeLog:
>
> 2015-07-29  Manuel López-Ibáñez  <manu@gcc.gnu.org>
>
>     PR c/66098
>     PR c/66711
>     * diagnostic.c (diagnostic_classify_diagnostic): Take -Werror into
>     account when deciding what was the command-line status.
>
> gcc/testsuite/ChangeLog:
>
> 2015-07-29  Manuel López-Ibáñez  <manu@gcc.gnu.org>
>
>     PR c/66098
>     PR c/66711
>     * gcc.dg/pragma-diag-3.c: New test.
>     * gcc.dg/pragma-diag-4.c: New test.
Marek Polacek Aug. 11, 2015, 1:01 p.m. UTC | #2
On Thu, Jul 30, 2015 at 05:35:39PM +0200, Manuel López-Ibáñez wrote:
> When I fixed PR59304, I forgot that a command-line warning can be also
> an error if -Werror was enabled. This introduced a regression since
> anything enabled in the command-line together with -Werror would get
> initially classified as a warning when reaching the first #pragma GCC
> diagnostic, and this will be the setting after a #pragma pop.
> 
> Options that appear as arguments of -W[no-]error= are not affected by
> this since those are initially classified as errors/warnings even
> before reaching the first #pragma, thus the pop sets them correctly
> (before and after this patch). Nonetheless, the tests also check that
> they work correctly.

Sorry for the delay (vacation/Cauldron).

> Index: gcc/diagnostic.c
> ===================================================================
> --- gcc/diagnostic.c	(revision 226312)
> +++ gcc/diagnostic.c	(working copy)
> @@ -694,13 +694,14 @@ diagnostic_classify_diagnostic (diagnost
>        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;
> +	  old_kind = !context->option_enabled (option_index,
> +					       context->option_state)
> +	    ? DK_IGNORED : (context->warning_as_error_requested
> +			    ? DK_ERROR: DK_WARNING);

Missing space before the colon.

> Index: gcc/testsuite/gcc.dg/pragma-diag-3.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/pragma-diag-3.c	(revision 0)
> +++ gcc/testsuite/gcc.dg/pragma-diag-3.c	(revision 0)
> @@ -0,0 +1,72 @@
> +/* { dg-do compile } */
> +/* { dg-options "-Wswitch-enum -Wsign-compare -fstrict-overflow -Wstrict-overflow -Werror -Wno-error=switch-enum" } */
> +/* PR c/66098 - #pragma diagnostic 'ignored' not fully undone by pop for strict-overflow 
> +   PR c/66711 - GCC does not correctly restore diagnostic state after pragma GCC diagnostic pop with -Werror 
> +*/
> +/* { dg-message "warnings being treated as errors" "" {target "*-*-*"} 0 } */
> +
> +void testing2() {
> +#pragma GCC diagnostic push
> +#pragma GCC diagnostic ignored "-Wstrict-overflow"
> +  int j = 4;
> +  j + 4 < j;
> +#pragma GCC diagnostic pop
> +}
> +
> +void testing3() {
> +  int k = 4;
> +  k + 4 < k; /* { dg-error "overflow" } */
> +}
> +
> +int foo() {
> +  testing2();
> +  testing3();
> +
> +  return 0;
> +}
> +
> +

I think you can drop the foo function.

Otherwise LGTM.

	Marek

Patch
diff mbox

Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 226312)
+++ gcc/diagnostic.c	(working copy)
@@ -694,13 +694,14 @@  diagnostic_classify_diagnostic (diagnost
       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;
+	  old_kind = !context->option_enabled (option_index,
+					       context->option_state)
+	    ? DK_IGNORED : (context->warning_as_error_requested
+			    ? DK_ERROR: DK_WARNING);
 	  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)
Index: gcc/testsuite/gcc.dg/pragma-diag-3.c
===================================================================
--- gcc/testsuite/gcc.dg/pragma-diag-3.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pragma-diag-3.c	(revision 0)
@@ -0,0 +1,72 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Wswitch-enum -Wsign-compare -fstrict-overflow -Wstrict-overflow -Werror -Wno-error=switch-enum" } */
+/* PR c/66098 - #pragma diagnostic 'ignored' not fully undone by pop for strict-overflow 
+   PR c/66711 - GCC does not correctly restore diagnostic state after pragma GCC diagnostic pop with -Werror 
+*/
+/* { dg-message "warnings being treated as errors" "" {target "*-*-*"} 0 } */
+
+void testing2() {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-overflow"
+  int j = 4;
+  j + 4 < j;
+#pragma GCC diagnostic pop
+}
+
+void testing3() {
+  int k = 4;
+  k + 4 < k; /* { dg-error "overflow" } */
+}
+
+int foo() {
+  testing2();
+  testing3();
+
+  return 0;
+}
+
+
+int bar()
+{
+  unsigned x = 0;
+  int y = 1;
+
+  /* generates an error - ok */
+  x += x < y ? 1 : 0; /* { dg-error "comparison" } */
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-compare"
+  /* generates no diagnostic - ok */
+  x += x < y ? 1 : 0;
+#pragma GCC diagnostic pop
+
+  x += x < y ? 1 : 0; /* { dg-error "comparison" } */
+
+  return x;
+}
+
+enum EE { ONE, TWO };
+
+int f (enum EE e)
+{
+  int r = 0;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch-enum"
+
+  switch (e)
+    {
+    case ONE:
+      r = 1;
+      break;
+    }
+#pragma GCC diagnostic pop
+
+  switch (e) /* { dg-warning "switch" } */
+    {
+    case ONE:
+      r = 1;
+      break;
+    }
+  return r;
+}
Index: gcc/testsuite/gcc.dg/pragma-diag-4.c
===================================================================
--- gcc/testsuite/gcc.dg/pragma-diag-4.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pragma-diag-4.c	(revision 0)
@@ -0,0 +1,48 @@ 
+/* { dg-do compile } */
+/* { dg-options "-Wsign-compare -Werror=sign-compare -Werror=switch-enum" } */
+/* { dg-message "warnings being treated as errors" "" {target "*-*-*"} 0 } */
+
+int bar()
+{
+  unsigned x = 0;
+  int y = 1;
+
+  /* generates an error - ok */
+  x += x < y ? 1 : 0; /* { dg-error "comparison" } */
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-compare"
+  /* generates no diagnostic - ok */
+  x += x < y ? 1 : 0;
+#pragma GCC diagnostic pop
+
+  x += x < y ? 1 : 0; /* { dg-error "comparison" } */
+
+  return x;
+}
+
+enum EE { ONE, TWO };
+
+int f (enum EE e)
+{
+  int r = 0;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wswitch-enum"
+
+  switch (e)
+    {
+    case ONE:
+      r = 1;
+      break;
+    }
+#pragma GCC diagnostic pop
+
+  switch (e) /* { dg-error "switch" } */
+    {
+    case ONE:
+      r = 1;
+      break;
+    }
+  return r;
+}