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