This patch enables the Wzero-as-null-pointer-constant for C.

Bootstrapped and regression tested on x86_64.



    c: add Wzero-as-null-pointer-constant [PR117059]
    
    Add warnings for the use of zero as a null pointer constant to the C FE.
    
            PR c/117059
    
    gcc/c-family/ChangeLog:
            * c.opt (Wzero-as-null-pointer-constant): Enable for C and ObjC.
    
    gcc/c/ChangeLog:
            * c-typeck.cc (parse_build_binary_op): Add warning.
            (build_conditional_expr): Add warning.
            (convert_for_assignment): Add warning.
    
    gcc/testsuite/ChangeLog:
            * gcc.dg/Wzero-as-null-pointer-constant.c: New test.

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 9b9f5e744f6..b4e967ce000 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1632,7 +1632,7 @@ C ObjC C++ ObjC++ Var(warn_xor_used_as_pow) Warning 
Init(1)
 Warn about xor operators where it appears the user meant exponentiation.
 
 Wzero-as-null-pointer-constant
-C++ ObjC++ Var(warn_zero_as_null_pointer_constant) Warning
+C ObjC C++ ObjC++ Var(warn_zero_as_null_pointer_constant) Warning
 Warn when a literal '0' is used as null pointer.
 
 Wzero-length-bounds
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 3fdf3437bf5..0266d685933 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -4600,15 +4600,24 @@ parser_build_binary_op (location_t location, enum 
tree_code code,
                "comparison with string literal results in unspecified "
                "behavior");
 
-  if (true
-      && TREE_CODE_CLASS (code) == tcc_comparison
-      && ((TREE_CODE (type1) == POINTER_TYPE
-          && TREE_CODE (type2) == INTEGER_TYPE
-          && null_pointer_constant_p (arg2.value))
-         || (TREE_CODE (type2) == POINTER_TYPE
-             && TREE_CODE (type1) == INTEGER_TYPE
-              && null_pointer_constant_p (arg1.value))))
-     warning_at (location, 0, "zero as null pointer constant");
+  if (warn_zero_as_null_pointer_constant
+      && c_inhibit_evaluation_warnings == 0
+      && TREE_CODE_CLASS (code) == tcc_comparison)
+    {
+      if ((TREE_CODE (type1) == POINTER_TYPE
+          || TREE_CODE (type1) == NULLPTR_TYPE)
+         && TREE_CODE (type2) == INTEGER_TYPE
+         && null_pointer_constant_p (arg2.value))
+       warning_at (arg2.get_location(), OPT_Wzero_as_null_pointer_constant,
+                   "zero as null pointer constant");
+
+      if ((TREE_CODE (type2) == POINTER_TYPE
+          || TREE_CODE (type2) == NULLPTR_TYPE)
+         && TREE_CODE (type1) == INTEGER_TYPE
+         && null_pointer_constant_p (arg1.value))
+       warning_at (arg1.get_location(), OPT_Wzero_as_null_pointer_constant,
+                   "zero as null pointer constant");
+    }
 
   if (warn_array_compare
       && TREE_CODE_CLASS (code) == tcc_comparison
@@ -5975,6 +5984,20 @@ build_conditional_expr (location_t colon_loc, tree 
ifexp, bool ifexp_bcp,
                    t1, t2);
     }
 
+  if (warn_zero_as_null_pointer_constant
+      && c_inhibit_evaluation_warnings == 0)
+    {
+      if ((code1 == POINTER_TYPE || code1 == NULLPTR_TYPE)
+         && code2 == INTEGER_TYPE && null_pointer_constant_p (orig_op2))
+       warning_at (op2_loc, OPT_Wzero_as_null_pointer_constant,
+                   "zero as null pointer constant");
+
+      if ((code2 == POINTER_TYPE || code2 == NULLPTR_TYPE)
+         && code1 == INTEGER_TYPE && null_pointer_constant_p (orig_op1))
+       warning_at (op1_loc, OPT_Wzero_as_null_pointer_constant,
+                   "zero as null pointer constant");
+    }
+
   /* Quickly detect the usual case where op1 and op2 have the same type
      after promotion.  */
   if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2))
@@ -8406,8 +8429,9 @@ convert_for_assignment (location_t location, location_t 
expr_loc, tree type,
               || coder == NULLPTR_TYPE
               || coder == BITINT_TYPE))
     {
-      if (null_pointer_constant)
-       warning_at (location, 0, "zero as null pointer constant");
+      if (null_pointer_constant && c_inhibit_evaluation_warnings == 0)
+       warning_at (location, OPT_Wzero_as_null_pointer_constant,
+                   "zero as null pointer constant");
 
       /* An explicit constant 0 or type nullptr_t can convert to a pointer,
         or one that results from arithmetic, even including a cast to
diff --git a/gcc/testsuite/gcc.dg/Wzero-as-null-pointer-constant.c 
b/gcc/testsuite/gcc.dg/Wzero-as-null-pointer-constant.c
new file mode 100644
index 00000000000..f493b2ea2c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wzero-as-null-pointer-constant.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -Wzero-as-null-pointer-constant" } */
+
+#define NULL (void*)0
+
+void foo(void*);
+void bar()
+{
+       foo(0);                         /* { dg-warning "zero as null pointer 
constant" } */
+       foo(NULL);
+
+       void *p = 0;                    /* { dg-warning "zero as null pointer 
constant" } */
+       void *r = NULL;
+       void *q = { 0 };                /* { dg-warning "zero as null pointer 
constant" } */
+       void *s = { NULL };
+       struct { void *q; } x = { 0 };  /* { dg-warning "zero as null pointer 
constant" } */
+       struct { void *q; } y = { NULL };
+
+       1 ? 0 : p;                      /* { dg-warning "zero as null pointer 
constant" } */
+       1 ? p : 0;                      /* { dg-warning "zero as null pointer 
constant" } */
+       1 ? 0 : NULL;                   /* { dg-warning "zero as null pointer 
constant" } */
+       1 ? NULL : 0;                   /* { dg-warning "zero as null pointer 
constant" } */
+
+       if (p == 0);                    /* { dg-warning "zero as null pointer 
constant" } */
+       if (0 == p);                    /* { dg-warning "zero as null pointer 
constant" } */
+       if (NULL == 0);                 /* { dg-warning "zero as null pointer 
constant" } */
+       if (0 == NULL);                 /* { dg-warning "zero as null pointer 
constant" } */
+       if (0 == nullptr);              /* { dg-warning "zero as null pointer 
constant" } */
+       if (nullptr == 0);              /* { dg-warning "zero as null pointer 
constant" } */
+}
+


Reply via email to