Patchwork [C++,preview] PR 44277

login
register
mail settings
Submitter Paolo Carlini
Date Oct. 31, 2011, 8:42 p.m.
Message ID <4EAF081B.2020409@oracle.com>
Download mbox | patch
Permalink /patch/122938/
State New
Headers show

Comments

Paolo Carlini - Oct. 31, 2011, 8:42 p.m.
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.

////////////////////

Patch

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);