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