[clang] cd29e19 - [Sema] -Wzero-as-null-pointer-constant: don't warn for __null (#69126)

via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 25 08:58:33 PDT 2023


Author: Arseny Kapoulkine
Date: 2023-10-25T11:58:28-04:00
New Revision: cd29e19e9476e221015d895618512717d872a83b

URL: https://github.com/llvm/llvm-project/commit/cd29e19e9476e221015d895618512717d872a83b
DIFF: https://github.com/llvm/llvm-project/commit/cd29e19e9476e221015d895618512717d872a83b.diff

LOG: [Sema] -Wzero-as-null-pointer-constant: don't warn for __null (#69126)

The implementation of -Wzero-as-null-pointer-constant was done before
the following fix has been committed to GCC:

https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=752e7593b0f19af233a0b7e72daab8413662b605;hp=298434c916c14e8adca2cab8a746aee29038c5b3

As a result, clang and gcc diverge on the use of `__null` and,
consequently, on the use of `NULL` on systems like Linux/macOS where
`NULL` is defined as `__null`.

This is a problem for compatibility between gcc and clang, particularly
for code bases that support C++98 or for single-source libraries that
are implemented in C, but compiled as C++ via inclusion into a C++
translation unit. Code like this can not be changed to use `nullptr`, as
it needs to maintain compatibility with C before C23 or C++ before
C++11, but warns on the use of `NULL` in clang.

The warning `Wzero-as-null-pointer-constant` is still useful with this
change, as it allows to change `0` to `NULL`, which fixes
gcc warnings and helps the reader distinguish between pointers and
non-pointers. Users who require a full C++11 modernization pass can
still use clang-tidy for that purpose.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/Sema.cpp
    clang/test/SemaCXX/warn-zero-nullptr.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1bb842f9b8888a1..e7db9512faf2645 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -401,6 +401,10 @@ Improvements to Clang's diagnostics
     24 | return decltype(fun_ptr)( f_ptr /*comment*/);
        |        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+- ``-Wzero-as-null-pointer-constant`` diagnostic is no longer emitted when using ``__null``
+  (or, more commonly, ``NULL`` when the platform defines it as ``__null``) to be more consistent
+  with GCC.
+
 Bug Fixes in This Version
 -------------------------
 - Fixed an issue where a class template specialization whose declaration is

diff  --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 67533ccbdf347c7..acb765559e6a8d4 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -590,7 +590,11 @@ void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E) {
 
   if (Kind != CK_NullToPointer && Kind != CK_NullToMemberPointer)
     return;
-  if (E->IgnoreParenImpCasts()->getType()->isNullPtrType())
+
+  const Expr *EStripped = E->IgnoreParenImpCasts();
+  if (EStripped->getType()->isNullPtrType())
+    return;
+  if (isa<GNUNullExpr>(EStripped))
     return;
 
   if (Diags.isIgnored(diag::warn_zero_as_null_pointer_constant,
@@ -612,6 +616,8 @@ void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E) {
 
   // If it is a macro from system header, and if the macro name is not "NULL",
   // do not warn.
+  // Note that uses of "NULL" will be ignored above on systems that define it
+  // as __null.
   SourceLocation MaybeMacroLoc = E->getBeginLoc();
   if (Diags.getSuppressSystemWarnings() &&
       SourceMgr.isInSystemMacro(MaybeMacroLoc) &&

diff  --git a/clang/test/SemaCXX/warn-zero-nullptr.cpp b/clang/test/SemaCXX/warn-zero-nullptr.cpp
index 45f05fa5703b1c3..684572f8ef67d05 100644
--- a/clang/test/SemaCXX/warn-zero-nullptr.cpp
+++ b/clang/test/SemaCXX/warn-zero-nullptr.cpp
@@ -16,10 +16,10 @@ int (S::*mp1) = 0; // expected-warning{{zero as null pointer constant}}
 void (*fp1)() = 0; // expected-warning{{zero as null pointer constant}}
 void* p1 = 0; // expected-warning{{zero as null pointer constant}}
 
-// NULL is an integer constant expression, so warn on it too:
-void* p2 = __null; // expected-warning{{zero as null pointer constant}}
-void (*fp2)() = __null; // expected-warning{{zero as null pointer constant}}
-int (S::*mp2) = __null; // expected-warning{{zero as null pointer constant}}
+// __null is not treated as an integer constant expression for GCC compatibility
+void* p2 = __null;
+void (*fp2)() = __null;
+int (S::*mp2) = __null;
 
 void f0(void* v = MACRO); // expected-warning{{zero as null pointer constant}}
 void f1(void* v = NULL); // expected-warning{{zero as null pointer constant}}


        


More information about the cfe-commits mailing list