[PATCH] D32914: Introduce Wzero-as-null-pointer-constant.

Nico Weber via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri May 5 08:58:38 PDT 2017


thakis created this revision.

Add an opt-in warning that fires when 0 is used as a null pointer. 
gcc has this warning, and there's some demand for it:
http://stackoverflow.com/questions/34953361/which-clang-warning-is-equivalent-to-wzero-as-null-pointer-constant-from-gcc
https://twitter.com/StephanTLavavej/status/859943696443166720


https://reviews.llvm.org/D32914

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/Sema.cpp
  test/SemaCXX/warn-zero-nullptr.cpp


Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -8962,6 +8962,9 @@
   "implicit conversion from nullable pointer %0 to non-nullable pointer "
   "type %1">,
   InGroup<NullableToNonNullConversion>, DefaultIgnore;
+def warn_zero_as_null_pointer_constant : Warning<
+  "zero as null pointer constant">,
+  InGroup<DiagGroup<"zero-as-null-pointer-constant">>, DefaultIgnore;
 
 def err_nullability_cs_multilevel : Error<
   "nullability keyword %0 cannot be applied to multi-level pointer type %1">;
Index: test/SemaCXX/warn-zero-nullptr.cpp
===================================================================
--- test/SemaCXX/warn-zero-nullptr.cpp
+++ test/SemaCXX/warn-zero-nullptr.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++11
+
+struct S {};
+
+int (S::*mp0) = nullptr;
+void* p0 = nullptr;
+
+int (S::*mp1) = 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}}
+int (S::*mp2) = __null; // expected-warning{{zero as null pointer constant}}
+
+void f0(void* v = 0); // expected-warning{{zero as null pointer constant}}
+void f1(void* v);
+
+void g() {
+  f1(0); // expected-warning{{zero as null pointer constant}}
+}
+
+// Warn on these too. Matches gcc and arguably makes sense.
+void* pp = (decltype(nullptr))0; // expected-warning{{zero as null pointer constant}}
+void* pp2 = static_cast<decltype(nullptr)>(0); // expected-warning{{zero as null pointer constant}}
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -3757,6 +3757,9 @@
   void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType,
                                            SourceLocation Loc);
 
+  /// \brief Warn when implicitly casting 0 to nullptr.
+  void diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E);
+
   ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) {
     return DelayedDiagnostics.push(pool);
   }
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -383,6 +383,19 @@
   Diag(Loc, diag::warn_nullability_lost) << SrcType << DstType;
 }
 
+void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr* E) {
+  if (Kind != CK_NullToPointer && Kind != CK_NullToMemberPointer)
+    return;
+  if (E->getType()->isNullPtrType())
+    return;
+  // nullptr only exists from C++11 on, so don't warn on its absence earlier.
+  if (!getLangOpts().CPlusPlus11)
+    return;
+
+  Diag(E->getLocStart(), diag::warn_zero_as_null_pointer_constant)
+      << FixItHint::CreateReplacement(E->getSourceRange(), "nullptr");
+}
+
 /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
 /// If there is already an implicit cast, merge into the existing one.
 /// The result is of the given category.
@@ -407,6 +420,7 @@
 #endif
 
   diagnoseNullableToNonnullConversion(Ty, E->getType(), E->getLocStart());
+  diagnoseZeroToNullptrConversion(Kind, E);
 
   QualType ExprTy = Context.getCanonicalType(E->getType());
   QualType TypeTy = Context.getCanonicalType(Ty);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32914.97966.patch
Type: text/x-patch
Size: 3566 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170505/4d7fc5b9/attachment-0001.bin>


More information about the cfe-commits mailing list