On Sun, Apr 26, 2015 at 8:56 PM, Patrick Palka <patr...@parcs.ath.cx> wrote: > Here is an updated version of the patch with, hopefully, all your > suggestions made. I decided to add calls to STRIP_NOPS before emitting > the warning so that we properly warn for cases where there's a cast in > between the whole thing, e.g. > > if (!&(int &)a) > > I also added guards to emit the warnings only when the stripped operand > is actually a decl so that we don't pass a non-decl argument to > warning_at() which can happen in a case like > > if (!&(int &)*(int *)0) > > Does this look OK now after testing? > > gcc/c-family/ChangeLog: > > PR c++/65168 > * c-common.c (c_common_truthvalue_conversion): Warn when > converting an address of a reference to a truth value. > > gcc/cp/ChangeLog: > > PR c++/65168 > * typeck.c (cp_build_binary_op): Warn when comparing an address > of a reference against NULL. > > gcc/testsuite/ChangeLog: > > PR c++/65168 > g++.dg/warn/Walways-true-3.C: New test. > --- > gcc/c-family/c-common.c | 14 ++++++++++ > gcc/cp/typeck.c | 34 ++++++++++++++++++++++ > gcc/testsuite/g++.dg/warn/Walways-true-3.C | 45 > ++++++++++++++++++++++++++++++ > 3 files changed, 93 insertions(+) > create mode 100644 gcc/testsuite/g++.dg/warn/Walways-true-3.C > > diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c > index 9797e17..c353c72 100644 > --- a/gcc/c-family/c-common.c > +++ b/gcc/c-family/c-common.c > @@ -4806,6 +4806,20 @@ c_common_truthvalue_conversion (location_t location, > tree expr) > tree totype = TREE_TYPE (expr); > tree fromtype = TREE_TYPE (TREE_OPERAND (expr, 0)); > > + if (POINTER_TYPE_P (totype) > + && TREE_CODE (fromtype) == REFERENCE_TYPE) > + { > + tree inner = expr; > + STRIP_NOPS (inner); > + > + if (DECL_P (inner)) > + warning_at (location, > + OPT_Waddress, > + "the compiler can assume that the address of " > + "%qD will always evaluate to %<true%>", > + inner); > + } > + > /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE, > since that affects how `default_conversion' will behave. */ > if (TREE_CODE (totype) == REFERENCE_TYPE > diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c > index 91db32a..13fb401 100644 > --- a/gcc/cp/typeck.c > +++ b/gcc/cp/typeck.c > @@ -4423,6 +4423,23 @@ cp_build_binary_op (location_t location, > warning (OPT_Waddress, "the address of %qD will never be > NULL", > TREE_OPERAND (op0, 0)); > } > + > + if (CONVERT_EXPR_P (op0) > + && TREE_CODE (TREE_TYPE (TREE_OPERAND (op0, 0))) > + == REFERENCE_TYPE) > + { > + tree inner_op0 = op0; > + STRIP_NOPS (inner_op0); > + > + if ((complain & tf_warning) > + && c_inhibit_evaluation_warnings == 0 > + && !TREE_NO_WARNING (op0) > + && DECL_P (inner_op0)) > + warning (OPT_Waddress, > + "the compiler can assume that the address of " > + "%qD will never be NULL", > + inner_op0); > + } > } > else if (((code1 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type1)) > && null_ptr_cst_p (op0)) > @@ -4445,6 +4462,23 @@ cp_build_binary_op (location_t location, > warning (OPT_Waddress, "the address of %qD will never be > NULL", > TREE_OPERAND (op1, 0)); > } > + > + if (CONVERT_EXPR_P (op1) > + && TREE_CODE (TREE_TYPE (TREE_OPERAND (op1, 0))) > + == REFERENCE_TYPE) > + { > + tree inner_op1 = op1; > + STRIP_NOPS (inner_op1); > + > + if ((complain & tf_warning) > + && c_inhibit_evaluation_warnings == 0 > + && !TREE_NO_WARNING (op1) > + && DECL_P (inner_op1)) > + warning (OPT_Waddress, > + "the compiler can assume that the address of " > + "%qD will never be NULL", > + inner_op1); > + } > } > else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE) > || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1))) > diff --git a/gcc/testsuite/g++.dg/warn/Walways-true-3.C > b/gcc/testsuite/g++.dg/warn/Walways-true-3.C > new file mode 100644 > index 0000000..0d13d3f > --- /dev/null > +++ b/gcc/testsuite/g++.dg/warn/Walways-true-3.C > @@ -0,0 +1,45 @@ > +// { dg-options "-Waddress" } > + > +void foo (void); > + > +int d; > +int &c = d; > + > +void > +bar (int &a) > +{ > + int &b = a; > + > + if ((int *)&a) // { dg-warning "address of" } > + foo (); > + > + if (&b) // { dg-warning "address of" } > + foo (); > + > + if (!&c) // { dg-warning "address of" } > + foo (); > + > + if (!&(int &)(int &)a) // { dg-warning "address of" } > + foo (); > + > + if (&a == 0) // { dg-warning "never be NULL" } > + foo (); > + > + if (&b != 0) // { dg-warning "never be NULL" } > + foo (); > + > + if (0 == &(int &)(int &)c) // { dg-warning "never be NULL" } > + foo (); > + > + if (&a != (int *)0) // { dg-warning "never be NULL" } > + foo (); > +} > + > +bool > +bar_1 (int &a) > +{ > + if (d == 5) > + return &a; // { dg-warning "address of" } > + else > + return !&(int &)(int &)a; // { dg-warning "address of" } > +} > -- > 2.4.0.rc2.31.g7c597ef >
Ping.