Message ID | 20160222213025.GU3017@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
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
--- 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" } +}