summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2017-05-05 16:11:08 +0000
committerNico Weber <nicolasweber@gmx.de>2017-05-05 16:11:08 +0000
commitd7ba86b6bf54740dd4007e65a927151cb9f510b4 (patch)
treef74f2de716ddadb5b2a99864578e05bb341aceb7
parent8b66b00ecd04c3d37fcfa6bfd03595365c7efd30 (diff)
downloadbcm5719-llvm-d7ba86b6bf54740dd4007e65a927151cb9f510b4.tar.gz
bcm5719-llvm-d7ba86b6bf54740dd4007e65a927151cb9f510b4.zip
Introduce Wzero-as-null-pointer-constant.
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. https://reviews.llvm.org/D32914 llvm-svn: 302247
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/include/clang/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/Sema.cpp14
-rw-r--r--clang/test/SemaCXX/warn-zero-nullptr.cpp27
4 files changed, 47 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0a80c46b7eb..444dd978ae3 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8975,6 +8975,9 @@ def warn_nullability_lost : Warning<
"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">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index eca383bee2f..e5961079f7c 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3766,6 +3766,9 @@ public:
void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType,
SourceLocation Loc);
+ /// Warn when implicitly casting 0 to nullptr.
+ void diagnoseZeroToNullptrConversion(CastKind Kind, const Expr *E);
+
ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) {
return DelayedDiagnostics.push(pool);
}
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 94e792c1d17..2f493fa5fbe 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -383,6 +383,19 @@ void Sema::diagnoseNullableToNonnullConversion(QualType DstType,
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 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
#endif
diagnoseNullableToNonnullConversion(Ty, E->getType(), E->getLocStart());
+ diagnoseZeroToNullptrConversion(Kind, E);
QualType ExprTy = Context.getCanonicalType(E->getType());
QualType TypeTy = Context.getCanonicalType(Ty);
diff --git a/clang/test/SemaCXX/warn-zero-nullptr.cpp b/clang/test/SemaCXX/warn-zero-nullptr.cpp
new file mode 100644
index 00000000000..edd2a759b70
--- /dev/null
+++ b/clang/test/SemaCXX/warn-zero-nullptr.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++11
+
+struct S {};
+
+int (S::*mp0) = nullptr;
+void (*fp0)() = nullptr;
+void* p0 = nullptr;
+
+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}}
+
+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}}
OpenPOWER on IntegriCloud