Another round. The other occurrence of maybe_warn_zero_as_null_pointer_constant
in typeck.c seems superfluous. The one in cvt.c seems necessary for
cpp0x/Wzero-as-null* tests. It seems like cp_build_binary_op is far more suited
to check the EQ_EXPR/NE_EXPR cases than conversion_null_warnings is.

Tested manually on Linux-x64, running full suite on Linux-PPC64. Ok for trunk?

2018-05-29  Ville Voutilainen  <ville.voutilai...@gmail.com>

    gcc/cp/

    Do not warn about zero-as-null when NULL is used.
    * typeck.c (cp_build_binary_op): Diagnose zero as null here..
    * call.c (conversion_null_warnings): ..and here..
    * cvt.c (cp_convert_to_pointer): ..not here.

    testsuite/

    Do not warn about zero-as-null when NULL is used.
    * g++.dg/warn/Wzero-as-null-pointer-constant-7.C: New.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7aadd64..5890b73 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6517,6 +6517,7 @@ build_temp (tree expr, tree type, int flags,
 }
 
 /* Perform warnings about peculiar, but valid, conversions from/to NULL.
+   Also handle a subset of zero as null warnings.
    EXPR is implicitly converted to type TOTYPE.
    FN and ARGNUM are used for diagnostics.  */
 
@@ -6551,6 +6552,17 @@ conversion_null_warnings (tree totype, tree expr, tree fn, int argnum)
 	warning_at (input_location, OPT_Wconversion_null,
 		    "converting %<false%> to pointer type %qT", totype);
     }
+  /* Handle zero as null pointer warnings for cases other
+     than EQ_EXPR and NE_EXPR */
+  else if (!null_node_p (expr))
+    {
+      source_location loc =
+	expansion_point_location_if_in_system_header (input_location);
+      if (null_ptr_cst_p (expr)
+	  && (TYPE_PTRMEMFUNC_P (totype) || TYPE_PTRDATAMEM_P (totype)
+	      || TYPE_PTR_P (totype)))
+	maybe_warn_zero_as_null_pointer_constant (expr, loc);
+    }
 }
 
 /* We gave a diagnostic during a conversion.  If this was in the second
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index f29dacd..e2f8579 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -208,9 +208,6 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold,
 	return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
 				 /*c_cast_p=*/false, complain);
 
-      if (complain & tf_warning)
-	maybe_warn_zero_as_null_pointer_constant (expr, loc);
-
       /* A NULL pointer-to-data-member is represented by -1, not by
 	 zero.  */
       tree val = (TYPE_PTRDATAMEM_P (type)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 3df043e..2eb4cf1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4353,6 +4353,21 @@ cp_build_binary_op (location_t location,
       warning_at (loc, OPT_Wpointer_arith, "NULL used in arithmetic");
     }
 
+  /* Handle zero as null pointer warnings for pointer comparisons */
+  if (code == EQ_EXPR || code == NE_EXPR)
+    {
+      source_location loc =
+	expansion_point_location_if_in_system_header (input_location);
+      if ((TYPE_PTRMEMFUNC_P (type0) || TYPE_PTRDATAMEM_P (type0)
+	   || TYPE_PTR_P (type0))
+	  && !null_node_p (op1) && null_ptr_cst_p (op1))
+	  maybe_warn_zero_as_null_pointer_constant (op1, loc);
+      else if ((TYPE_PTRMEMFUNC_P (type1) || TYPE_PTRDATAMEM_P (type1)
+	   || TYPE_PTR_P (type1))
+	  && !null_node_p (op0) && null_ptr_cst_p (op0))
+	maybe_warn_zero_as_null_pointer_constant (op0, loc);
+    }
+
   /* In case when one of the operands of the binary operation is
      a vector and another is a scalar -- convert scalar to vector.  */
   if ((code0 == VECTOR_TYPE) != (code1 == VECTOR_TYPE))
@@ -4833,9 +4848,6 @@ cp_build_binary_op (location_t location,
 				       integer_one_node,
 				       complain);
 
-	      if (complain & tf_warning)
-		maybe_warn_zero_as_null_pointer_constant (op1, input_location);
-
 	      e2 = cp_build_binary_op (location,
 				       EQ_EXPR, e2, integer_zero_node,
 				       complain);
diff --git a/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-7.C b/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-7.C
new file mode 100644
index 0000000..0d06dbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wzero-as-null-pointer-constant-7.C
@@ -0,0 +1,13 @@
+// { dg-options "-Wzero-as-null-pointer-constant" }
+// { dg-do compile { target c++11 } }
+
+#include <cstddef>
+
+void test01()
+{
+  char* x(NULL);
+  char* x2{NULL};
+  char* x3 = NULL;
+  char* x4(0); // { dg-warning "zero as null pointer" }
+  char* x5 = 0; // { dg-warning "zero as null pointer" }
+}

Reply via email to