Author: nico Date: Fri May 5 11:11:08 2017 New Revision: 302247 URL: http://llvm.org/viewvc/llvm-project?rev=302247&view=rev Log: 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 Added: cfe/trunk/test/SemaCXX/warn-zero-nullptr.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/lib/Sema/Sema.cpp Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=302247&r1=302246&r2=302247&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri May 5 11:11:08 2017 @@ -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">; Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=302247&r1=302246&r2=302247&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Fri May 5 11:11:08 2017 @@ -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); } Modified: cfe/trunk/lib/Sema/Sema.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=302247&r1=302246&r2=302247&view=diff ============================================================================== --- cfe/trunk/lib/Sema/Sema.cpp (original) +++ cfe/trunk/lib/Sema/Sema.cpp Fri May 5 11:11:08 2017 @@ -383,6 +383,19 @@ void Sema::diagnoseNullableToNonnullConv 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 #endif diagnoseNullableToNonnullConversion(Ty, E->getType(), E->getLocStart()); + diagnoseZeroToNullptrConversion(Kind, E); QualType ExprTy = Context.getCanonicalType(E->getType()); QualType TypeTy = Context.getCanonicalType(Ty); Added: cfe/trunk/test/SemaCXX/warn-zero-nullptr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-zero-nullptr.cpp?rev=302247&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/warn-zero-nullptr.cpp (added) +++ cfe/trunk/test/SemaCXX/warn-zero-nullptr.cpp Fri May 5 11:11:08 2017 @@ -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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits