diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ac7387846fe..224e3fc5efd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2016-03-17 Marek Polacek + + PR c++/70194 + * typeck.c (warn_for_null_address): New function. + (cp_build_binary_op): Call it. + 2016-03-16 Jason Merrill PR c++/70259 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 20f0afc74d7..447006cb327 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3974,6 +3974,38 @@ build_vec_cmp (tree_code code, tree type, return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec); } +/* Possibly warn about an address never being NULL. */ + +static void +warn_for_null_address (location_t location, tree op, tsubst_flags_t complain) +{ + if (!warn_address + || (complain & tf_warning) == 0 + || c_inhibit_evaluation_warnings != 0 + || TREE_NO_WARNING (op)) + return; + + tree cop = fold_non_dependent_expr (op); + + if (TREE_CODE (cop) == ADDR_EXPR + && decl_with_nonnull_addr_p (TREE_OPERAND (cop, 0)) + && !TREE_NO_WARNING (cop)) + warning_at (location, OPT_Waddress, "the address of %qD will never " + "be NULL", TREE_OPERAND (cop, 0)); + + if (CONVERT_EXPR_P (op) + && TREE_CODE (TREE_TYPE (TREE_OPERAND (op, 0))) == REFERENCE_TYPE) + { + tree inner_op = op; + STRIP_NOPS (inner_op); + + if (DECL_P (inner_op)) + warning_at (location, OPT_Waddress, + "the compiler can assume that the address of " + "%qD will never be NULL", inner_op); + } +} + /* Build a binary-operation expression without default conversions. CODE is the kind of expression to build. LOCATION is the location_t of the operator in the source code. @@ -4520,32 +4552,7 @@ cp_build_binary_op (location_t location, else result_type = type0; - if (TREE_CODE (op0) == ADDR_EXPR - && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))) - { - if ((complain & tf_warning) - && c_inhibit_evaluation_warnings == 0 - && !TREE_NO_WARNING (op0)) - 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_at (location, OPT_Waddress, - "the compiler can assume that the address of " - "%qD will never be NULL", - inner_op0); - } + warn_for_null_address (location, op0, complain); } else if (((code1 == POINTER_TYPE || TYPE_PTRDATAMEM_P (type1)) && null_ptr_cst_p (op0)) @@ -4559,32 +4566,7 @@ cp_build_binary_op (location_t location, else result_type = type1; - if (TREE_CODE (op1) == ADDR_EXPR - && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))) - { - if ((complain & tf_warning) - && c_inhibit_evaluation_warnings == 0 - && !TREE_NO_WARNING (op1)) - 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_at (location, OPT_Waddress, - "the compiler can assume that the address of " - "%qD will never be NULL", - inner_op1); - } + warn_for_null_address (location, op1, complain); } else if ((code0 == POINTER_TYPE && code1 == POINTER_TYPE) || (TYPE_PTRDATAMEM_P (type0) && TYPE_PTRDATAMEM_P (type1))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f59e1c8213d..e27a4e17820 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-03-17 Marek Polacek + + PR c++/70194 + * g++.dg/warn/constexpr-70194.C: New test. + 2016-03-16 Richard Henderson PR middle-end/70240 diff --git a/gcc/testsuite/g++.dg/warn/constexpr-70194.C b/gcc/testsuite/g++.dg/warn/constexpr-70194.C new file mode 100644 index 00000000000..cdc56c0c6f2 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/constexpr-70194.C @@ -0,0 +1,12 @@ +// PR c++/70194 +// { dg-do compile { target c++11 } } +// { dg-options "-Wall" } + +int i; + +const bool b0 = &i == 0; // { dg-warning "the address of .i. will never be NULL" } +constexpr int *p = &i; +const bool b1 = p == 0; // { dg-warning "the address of .i. will never be NULL" } +const bool b2 = 0 == p; // { dg-warning "the address of .i. will never be NULL" } +const bool b3 = p != 0; // { dg-warning "the address of .i. will never be NULL" } +const bool b4 = 0 != p; // { dg-warning "the address of .i. will never be NULL" }