On 10/31/2011 09:29 PM, Jason Merrill wrote:
On 10/31/2011 04:09 PM, Paolo Carlini wrote:
... 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...

I notice that this patch only changes the C++ front end, and it seems like you already have special cases for pointers/pointers to members, so you might as well go ahead and use nullptr_node.
Right. Thus essentially a mix of the two recent tries, like the below, right? Patch becomes even simpler and more importantly we rely on c_inhibit_* only for c code proper.

If you think I'm on the right track, I will add the testcases, documentation, etc.

Is the name of the warning ok? It's a bit long...

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)
@@ -4058,7 +4058,9 @@ cp_build_binary_op (location_t location,
          else 
            {
              op0 = build_ptrmemfunc_access_expr (op0, pfn_identifier);
-             op1 = cp_convert (TREE_TYPE (op0), integer_zero_node); 
+             op1 = cp_convert (TREE_TYPE (op0),
+                               NULLPTR_TYPE_P (TREE_TYPE (op1))
+                               ? nullptr_node : integer_zero_node);
            }
          result_type = TREE_TYPE (op0);
        }
@@ -4666,11 +4668,21 @@ 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);
+    ret = build_binary_op (EXPR_LOCATION (expr),
+                          NE_EXPR, expr, nullptr_node, 1);
+  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,8 @@ 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))
+    init = convert (type, nullptr_node);
   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