Hi! And here is a fix for the dynamic_cast issue I've mentioned recently. Alternatively, ifnonnull could build instead NE_EXPR with swapped last two arguments on the COND_EXPR, and then I believe the cp_fold change would not be needed.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Or do you prefer the NE_EXPR variant? 2016-02-18 Jakub Jelinek <ja...@redhat.com> PR c++/69850 * rtti.c (ifnonnull): Set TREE_NO_WARNING on the EQ_EXPR condition. * cp-gimplify.c (cp_fold) <case COND_EXPR>: Preserve TREE_NO_WARNING on comparison if folding swaps arguments. * g++.dg/warn/Wnonnull-compare-4.C: New test. --- gcc/cp/rtti.c.jj 2016-02-11 10:50:58.000000000 +0100 +++ gcc/cp/rtti.c 2016-02-18 18:04:24.611297291 +0100 @@ -507,10 +507,12 @@ get_typeid (tree type, tsubst_flags_t co static tree ifnonnull (tree test, tree result, tsubst_flags_t complain) { - return build3 (COND_EXPR, TREE_TYPE (result), - build2 (EQ_EXPR, boolean_type_node, test, - cp_convert (TREE_TYPE (test), nullptr_node, - complain)), + tree cond = build2 (EQ_EXPR, boolean_type_node, test, + cp_convert (TREE_TYPE (test), nullptr_node, complain)); + /* This is a compiler generated comparison, don't emit + e.g. -Wnonnull-compare warning for it. */ + TREE_NO_WARNING (cond) = 1; + return build3 (COND_EXPR, TREE_TYPE (result), cond, cp_convert (TREE_TYPE (result), nullptr_node, complain), result); } --- gcc/cp/cp-gimplify.c.jj 2016-02-18 11:20:08.000000000 +0100 +++ gcc/cp/cp-gimplify.c 2016-02-18 18:14:26.213996843 +0100 @@ -2101,6 +2101,11 @@ cp_fold (tree x) else x = fold (x); + if (COMPARISON_CLASS_P (TREE_OPERAND (org_x, 0)) + && TREE_NO_WARNING (TREE_OPERAND (org_x, 0)) + && TREE_CODE (x) == TREE_CODE (org_x) + && COMPARISON_CLASS_P (TREE_OPERAND (x, 0))) + TREE_NO_WARNING (TREE_OPERAND (x, 0)) = 1; break; case CALL_EXPR: --- gcc/testsuite/g++.dg/warn/Wnonnull-compare-4.C.jj 2016-02-18 18:03:04.777398778 +0100 +++ gcc/testsuite/g++.dg/warn/Wnonnull-compare-4.C 2016-02-18 18:02:46.414652133 +0100 @@ -0,0 +1,14 @@ +// PR c++/69850 +// { dg-do compile } +// { dg-options "-Wnonnull-compare" } + +struct A { virtual ~A (); int foo (); }; +struct B { virtual ~B () { } }; +struct C : B, A { }; + +int +A::foo () +{ + C *c = dynamic_cast<C *> (this); // { dg-bogus "nonnull argument" } + return !c; +} Jakub