[PATCH] Fix another -Wnonnull-compare false positive (PR c++/70295)

Jakub Jelinek jakub@redhat.com
Mon Mar 21 20:43:00 GMT 2016


Hi!

On the Wnonnull-compare-8.C testcase we emit false positive warning, because
the this != NULL artificial comparison appears together with && optimized
into &, and so it is gimplified as assignment to temporary instead of
GIMPLE_COND.

Unfortunately, this regresses one test in nonnull-1.c, because
TREE_NO_WARNING is used for lots of things, newly for -Wnonnull-compare for
the artificial comparisons added by the C++ FE where comparison of nonnull
argument/this etc. is fine, but also e.g. when parsing (expr) for the
benefit of -Wparentheses and other warnings.  I've tried to stop using
TREE_WARNING for that (for COMPARISON_CLASS_P trees), but while it happened
to work fine outside of templates, inside of templates it regressed in some
cases.  So, I'm afraid it is better for now to live with fewer
-Wnonnull-compare warnings, and for stage1 IMHO we should finally do
something about TREE_NO_WARNING/gimple_no_warning_p, that bit is clearly
not sufficient to determine what we don't warnings on.  Perhaps that bit
could mean that we have the tree or gimple * mapped in some on the side hash
table to some record describing what warnings we don't want to issue for it,
so we could change the current TREE_NO_WARNING or gimple_set_no_warning
setters to fill in the OPT_W* values they want to disable, and have code
that copies the bit also adjust on the side hash table if it is set.

As the testcase is from real-world app (libreoffice) and happens quite a lot
there, I think it is important to get this fixed.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-03-21  Jakub Jelinek  <jakub@redhat.com>

	PR c++/70295
	* gimplify.c (gimplify_modify_expr): Call gimple_set_no_warning
	on assign if (*from_p) is a comparison, set it to
	TREE_NO_WARNING (*from_p).

	* c-c++-common/nonnull-1.c (func): Remove parens around cp4 != 0.
	(func2): New function for cond with parens, xfail warning for c++.
	* g++.dg/warn/Wnonnull-compare-8.C: New test.

--- gcc/gimplify.c.jj	2016-03-21 10:12:26.477833769 +0100
+++ gcc/gimplify.c	2016-03-21 18:56:50.111510051 +0100
@@ -4850,6 +4850,8 @@ gimplify_modify_expr (tree *expr_p, gimp
     {
       assign = gimple_build_assign (*to_p, *from_p);
       gimple_set_location (assign, EXPR_LOCATION (*expr_p));
+      if (COMPARISON_CLASS_P (*from_p))
+	gimple_set_no_warning (assign, TREE_NO_WARNING (*from_p));
     }
 
   if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
--- gcc/testsuite/c-c++-common/nonnull-1.c.jj	2016-02-16 21:43:38.000000000 +0100
+++ gcc/testsuite/c-c++-common/nonnull-1.c	2016-03-21 19:02:02.891301978 +0100
@@ -24,5 +24,11 @@ func (char *cp1, char *cp2, char *cp3, c
   if (NULL != cp3) /* { dg-warning "nonnull argument" "cp3 compared to NULL" } */
     return 3;
 
-  return (cp4 != 0) ? 0 : 1; /* { dg-warning "nonnull argument" "cp4 compared to NULL" } */
+  return cp4 != 0 ? 0 : 1; /* { dg-warning "nonnull argument" "cp4 compared to NULL" } */
+}
+
+__attribute__((nonnull (1))) int
+func2 (char *cp)
+{
+  return (cp != NULL) ? 1 : 0; /* { dg-warning "nonnull argument" "cp compared to NULL" { xfail c++ } } */
 }
--- gcc/testsuite/g++.dg/warn/Wnonnull-compare-8.C.jj	2016-03-21 18:56:50.112510037 +0100
+++ gcc/testsuite/g++.dg/warn/Wnonnull-compare-8.C	2016-03-21 18:56:50.112510037 +0100
@@ -0,0 +1,14 @@
+// PR c++/70295
+// { dg-do compile }
+// { dg-options "-O2 -Wnonnull-compare" }
+
+struct A { A (); virtual ~A (); bool foo (bool); };
+struct B : virtual public A { B (); virtual ~B (); };
+
+bool
+A::foo (bool x)
+{
+  if (x && dynamic_cast<B *>(this) != (B *) 0)	// { dg-bogus "nonnull argument" }
+    return true;
+  return false;
+}

	Jakub



More information about the Gcc-patches mailing list