[C++] Avoid code generation changes with -Wnonnull-compare vs. -Wno-nonnull-compare (PR c++/86569)

Message ID 20180722191550.GB7166@tucnak
State New
Headers show
Series
  • [C++] Avoid code generation changes with -Wnonnull-compare vs. -Wno-nonnull-compare (PR c++/86569)
Related show

Commit Message

Jakub Jelinek July 22, 2018, 7:15 p.m.
Hi!

A couple of -fcompare-debug=-Wsomething PRs have been filed recently, this
fixes one of them.  Changing code generation based on TREE_NO_WARNING flag
which usually gets set only in the warning code, or on warn_* option is
undesirable.  This patch prevents that kind of folding regardless of the
warning options, the GIMPLE optimizers can handle it fine (but it makes a
difference with -O0).

Bootstrapped/regtested on x86_64-linux (only, i686-linux bootstrap is
broken), ok for trunk?

2018-07-22  Jakub Jelinek  <jakub@redhat.com>

	PR c++/86569
	* cp-gimplify.c (cp_fold): Don't fold comparisons into other kind
	of expressions other than INTEGER_CST regardless of TREE_NO_WARNING
	or warn_nonnull_compare.

	* g++.dg/warn/Wnonnull-compare-9.C: New test.


	Jakub

Comments

Richard Biener July 22, 2018, 7:22 p.m. | #1
On July 22, 2018 9:15:50 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!

>

>A couple of -fcompare-debug=-Wsomething PRs have been filed recently,

>this

>fixes one of them.  Changing code generation based on TREE_NO_WARNING

>flag

>which usually gets set only in the warning code, or on warn_* option is

>undesirable.  This patch prevents that kind of folding regardless of

>the

>warning options, the GIMPLE optimizers can handle it fine (but it makes

>a

>difference with -O0).

>

>Bootstrapped/regtested on x86_64-linux (only, i686-linux bootstrap is

>broken), ok for trunk?


OK. 

Richard. 

>2018-07-22  Jakub Jelinek  <jakub@redhat.com>

>

>	PR c++/86569

>	* cp-gimplify.c (cp_fold): Don't fold comparisons into other kind

>	of expressions other than INTEGER_CST regardless of TREE_NO_WARNING

>	or warn_nonnull_compare.

>

>	* g++.dg/warn/Wnonnull-compare-9.C: New test.

>

>--- gcc/cp/cp-gimplify.c.jj	2018-07-16 09:43:03.237023048 +0200

>+++ gcc/cp/cp-gimplify.c	2018-07-19 11:44:24.881759294 +0200

>@@ -2381,21 +2381,26 @@ cp_fold (tree x)

>       else

> 	x = fold (x);

> 

>-      if (TREE_NO_WARNING (org_x)

>-	  && warn_nonnull_compare

>-	  && COMPARISON_CLASS_P (org_x))

>+      /* This is only needed for -Wnonnull-compare and only if

>+	 TREE_NO_WARNING (org_x), but to avoid that option affecting code

>+	 generation, we do it always.  */

>+      if (COMPARISON_CLASS_P (org_x))

> 	{

> 	  if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)

> 	    ;

> 	  else if (COMPARISON_CLASS_P (x))

>-	    TREE_NO_WARNING (x) = 1;

>+	    {

>+	      if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)

>+		TREE_NO_WARNING (x) = 1;

>+	    }

> 	  /* Otherwise give up on optimizing these, let GIMPLE folders

> 	     optimize those later on.  */

> 	  else if (op0 != TREE_OPERAND (org_x, 0)

> 		   || op1 != TREE_OPERAND (org_x, 1))

> 	    {

> 	      x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);

>-	      TREE_NO_WARNING (x) = 1;

>+	      if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)

>+		TREE_NO_WARNING (x) = 1;

> 	    }

> 	  else

> 	    x = org_x;

>--- gcc/testsuite/g++.dg/warn/Wnonnull-compare-9.C.jj	2018-07-19

>11:57:41.909727597 +0200

>+++ gcc/testsuite/g++.dg/warn/Wnonnull-compare-9.C	2018-07-19

>11:57:14.627696497 +0200

>@@ -0,0 +1,11 @@

>+// PR c++/86569

>+// { dg-do compile }

>+// { dg-options "-fcompare-debug=-Wnonnull-compare" }

>+

>+bool b;

>+

>+int

>+main ()

>+{

>+  return ((!b) != 0);

>+}

>

>	Jakub

Patch

--- gcc/cp/cp-gimplify.c.jj	2018-07-16 09:43:03.237023048 +0200
+++ gcc/cp/cp-gimplify.c	2018-07-19 11:44:24.881759294 +0200
@@ -2381,21 +2381,26 @@  cp_fold (tree x)
       else
 	x = fold (x);
 
-      if (TREE_NO_WARNING (org_x)
-	  && warn_nonnull_compare
-	  && COMPARISON_CLASS_P (org_x))
+      /* This is only needed for -Wnonnull-compare and only if
+	 TREE_NO_WARNING (org_x), but to avoid that option affecting code
+	 generation, we do it always.  */
+      if (COMPARISON_CLASS_P (org_x))
 	{
 	  if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
 	    ;
 	  else if (COMPARISON_CLASS_P (x))
-	    TREE_NO_WARNING (x) = 1;
+	    {
+	      if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
+		TREE_NO_WARNING (x) = 1;
+	    }
 	  /* Otherwise give up on optimizing these, let GIMPLE folders
 	     optimize those later on.  */
 	  else if (op0 != TREE_OPERAND (org_x, 0)
 		   || op1 != TREE_OPERAND (org_x, 1))
 	    {
 	      x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
-	      TREE_NO_WARNING (x) = 1;
+	      if (TREE_NO_WARNING (org_x) && warn_nonnull_compare)
+		TREE_NO_WARNING (x) = 1;
 	    }
 	  else
 	    x = org_x;
--- gcc/testsuite/g++.dg/warn/Wnonnull-compare-9.C.jj	2018-07-19 11:57:41.909727597 +0200
+++ gcc/testsuite/g++.dg/warn/Wnonnull-compare-9.C	2018-07-19 11:57:14.627696497 +0200
@@ -0,0 +1,11 @@ 
+// PR c++/86569
+// { dg-do compile }
+// { dg-options "-fcompare-debug=-Wnonnull-compare" }
+
+bool b;
+
+int
+main ()
+{
+  return ((!b) != 0);
+}