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 <ja...@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