diff mbox

Another -Wnonnull-compare false positive fix (PR c++/69902)

Message ID 20160222213025.GU3017@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Feb. 22, 2016, 9:30 p.m. UTC
Hi!

Here is a fix for another -Wnonnull-compare false positive - the problem
is that during folding the NE_EXPR of a nonnull_arg_p with NULL (on which
the C++ FE set TREE_NO_WARNING, because it is an artificial comparison
for dynamic_cast) is changed by fold-const.c into EQ_EXPR, and the
TREE_NO_WARNING flag is lost.  Unfortunately it is deep enough in an
expression passed to fold that cp_fold can't easily tweak that.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2016-02-22  Jakub Jelinek  <jakub@redhat.com>

	PR c++/69902
	* fold-const.c (fold_truth_not_expr): Propagate TREE_NO_WARNING
	when inverting comparison.

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


	Jakub

Comments

Richard Biener Feb. 23, 2016, 11:45 a.m. UTC | #1
On Mon, Feb 22, 2016 at 10:30 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> Here is a fix for another -Wnonnull-compare false positive - the problem
> is that during folding the NE_EXPR of a nonnull_arg_p with NULL (on which
> the C++ FE set TREE_NO_WARNING, because it is an artificial comparison
> for dynamic_cast) is changed by fold-const.c into EQ_EXPR, and the
> TREE_NO_WARNING flag is lost.  Unfortunately it is deep enough in an
> expression passed to fold that cp_fold can't easily tweak that.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?

Ok.

Thanks,
Richard.

> 2016-02-22  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/69902
>         * fold-const.c (fold_truth_not_expr): Propagate TREE_NO_WARNING
>         when inverting comparison.
>
>         * g++.dg/warn/Wnonnull-compare-5.C: New test.
>
> --- gcc/fold-const.c.jj 2016-02-19 08:55:05.000000000 +0100
> +++ gcc/fold-const.c    2016-02-22 17:46:26.870468937 +0100
> @@ -3589,8 +3589,11 @@ fold_truth_not_expr (location_t loc, tre
>        if (code == ERROR_MARK)
>         return NULL_TREE;
>
> -      return build2_loc (loc, code, type, TREE_OPERAND (arg, 0),
> -                        TREE_OPERAND (arg, 1));
> +      tree ret = build2_loc (loc, code, type, TREE_OPERAND (arg, 0),
> +                            TREE_OPERAND (arg, 1));
> +      if (TREE_NO_WARNING (arg))
> +       TREE_NO_WARNING (ret) = 1;
> +      return ret;
>      }
>
>    switch (code)
> --- gcc/testsuite/g++.dg/warn/Wnonnull-compare-5.C.jj   2016-02-22 17:48:16.996963704 +0100
> +++ gcc/testsuite/g++.dg/warn/Wnonnull-compare-5.C      2016-02-22 17:56:58.235839294 +0100
> @@ -0,0 +1,18 @@
> +// PR c++/69902
> +// { dg-do compile }
> +// { dg-options "-Wall" }
> +
> +struct A { virtual ~A (); };
> +struct B : A {};
> +
> +bool
> +foo (A &a)
> +{
> +  return dynamic_cast<B *>(&a) == (B *) 0;     // { dg-bogus "nonnull argument" }
> +}
> +
> +bool
> +bar (A &a)
> +{
> +  return dynamic_cast<B *>(&a) != (B *) 0;     // { dg-bogus "nonnull argument" }
> +}
>
>         Jakub
diff mbox

Patch

--- gcc/fold-const.c.jj	2016-02-19 08:55:05.000000000 +0100
+++ gcc/fold-const.c	2016-02-22 17:46:26.870468937 +0100
@@ -3589,8 +3589,11 @@  fold_truth_not_expr (location_t loc, tre
       if (code == ERROR_MARK)
 	return NULL_TREE;
 
-      return build2_loc (loc, code, type, TREE_OPERAND (arg, 0),
-			 TREE_OPERAND (arg, 1));
+      tree ret = build2_loc (loc, code, type, TREE_OPERAND (arg, 0),
+			     TREE_OPERAND (arg, 1));
+      if (TREE_NO_WARNING (arg))
+	TREE_NO_WARNING (ret) = 1;
+      return ret;
     }
 
   switch (code)
--- gcc/testsuite/g++.dg/warn/Wnonnull-compare-5.C.jj	2016-02-22 17:48:16.996963704 +0100
+++ gcc/testsuite/g++.dg/warn/Wnonnull-compare-5.C	2016-02-22 17:56:58.235839294 +0100
@@ -0,0 +1,18 @@ 
+// PR c++/69902
+// { dg-do compile }
+// { dg-options "-Wall" }
+
+struct A { virtual ~A (); };
+struct B : A {};
+
+bool
+foo (A &a)
+{
+  return dynamic_cast<B *>(&a) == (B *) 0;	// { dg-bogus "nonnull argument" }
+}
+
+bool
+bar (A &a)
+{
+  return dynamic_cast<B *>(&a) != (B *) 0;	// { dg-bogus "nonnull argument" }
+}