... so today I noticed the c_inhibit_evaluation_warnings use in cp_convert_and_check and occurred to me that we could use the existing mechanism for this warning too?

The below still passes checking and my small set of tests...

What do you think?

Thanks,
Paolo.

//////////////////////////
Index: c-family/c.opt
===================================================================
--- c-family/c.opt      (revision 180705)
+++ c-family/c.opt      (working copy)
@@ -685,6 +685,9 @@ Wpointer-sign
 C ObjC Var(warn_pointer_sign) Init(-1) Warning
 Warn when a pointer differs in signedness in an assignment
 
+Wzero-as-null-pointer-constant
+C++ ObjC++ Var(warn_zero_as_null_pointer_constant) Warning
+
 ansi
 C ObjC C++ ObjC++
 A synonym for -std=c89 (for C) or -std=c++98 (for C++)
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 180705)
+++ cp/typeck.c (working copy)
@@ -4057,8 +4057,13 @@ cp_build_binary_op (location_t location,
            }
          else 
            {
+             bool inhibit = NULLPTR_TYPE_P (TREE_TYPE (op1));
              op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
-             op1 = cp_convert (TREE_TYPE (op0), integer_zero_node); 
+             if (inhibit)
+               ++c_inhibit_evaluation_warnings;
+             op1 = cp_convert (TREE_TYPE (op0), integer_zero_node);
+             if (inhibit)
+               --c_inhibit_evaluation_warnings;
            }
          result_type = TREE_TYPE (op0);
        }
@@ -4666,11 +4671,25 @@ tree
 cp_truthvalue_conversion (tree expr)
 {
   tree type = TREE_TYPE (expr);
+  tree ret;
+
   if (TYPE_PTRMEM_P (type))
-    return build_binary_op (EXPR_LOCATION (expr),
-                           NE_EXPR, expr, integer_zero_node, 1);
+    {
+      ++c_inhibit_evaluation_warnings;
+      ret = build_binary_op (EXPR_LOCATION (expr),
+                            NE_EXPR, expr, integer_zero_node, 1);
+      --c_inhibit_evaluation_warnings;
+    }
+  else if (TYPE_PTR_P (type) || TYPE_PTRMEMFUNC_P (type))
+    {
+      ++c_inhibit_evaluation_warnings;
+      ret = c_common_truthvalue_conversion (input_location, expr);
+      --c_inhibit_evaluation_warnings;
+    }
   else
-    return c_common_truthvalue_conversion (input_location, expr);
+    ret = c_common_truthvalue_conversion (input_location, expr);
+
+  return ret;
 }
 
 /* Just like cp_truthvalue_conversion, but we want a CLEANUP_POINT_EXPR.  */
Index: cp/init.c
===================================================================
--- cp/init.c   (revision 180705)
+++ cp/init.c   (working copy)
@@ -176,6 +176,12 @@ build_zero_init_1 (tree type, tree nelts, bool sta
        items with static storage duration that are not otherwise
        initialized are initialized to zero.  */
     ;
+  else if (TYPE_PTR_P (type) || TYPE_PTR_TO_MEMBER_P (type))
+    {
+      ++c_inhibit_evaluation_warnings;
+      init = convert (type, integer_zero_node);
+      --c_inhibit_evaluation_warnings;
+    }
   else if (SCALAR_TYPE_P (type))
     init = convert (type, integer_zero_node);
   else if (CLASS_TYPE_P (type))
Index: cp/cvt.c
===================================================================
--- cp/cvt.c    (revision 180705)
+++ cp/cvt.c    (working copy)
@@ -198,6 +198,11 @@ cp_convert_to_pointer (tree type, tree expr)
 
   if (null_ptr_cst_p (expr))
     {
+      if (c_inhibit_evaluation_warnings == 0
+         && !NULLPTR_TYPE_P (TREE_TYPE (expr)))
+       warning (OPT_Wzero_as_null_pointer_constant,
+                "zero as null pointer constant");
+
       if (TYPE_PTRMEMFUNC_P (type))
        return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0,
                                 /*c_cast_p=*/false, tf_warning_or_error);

Reply via email to