r219774 - Improvements to -Wnull-conversion

Richard Trieu rtrieu at google.com
Tue Oct 14 20:42:07 PDT 2014


Author: rtrieu
Date: Tue Oct 14 22:42:06 2014
New Revision: 219774

URL: http://llvm.org/viewvc/llvm-project?rev=219774&view=rev
Log:
Improvements to -Wnull-conversion

Split logic to separate checking function
Refine the macro checking
Catch nullptr->bool conversions
Add some explanatory comments

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/SemaCXX/conversion.cpp
    cfe/trunk/test/SemaCXX/nullptr.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=219774&r1=219773&r2=219774&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Oct 14 22:42:06 2014
@@ -2490,7 +2490,7 @@ def warn_non_literal_null_pointer : Warn
     "expression which evaluates to zero treated as a null pointer constant of "
     "type %0">, InGroup<NonLiteralNullConversion>;
 def warn_impcast_null_pointer_to_integer : Warning<
-    "implicit conversion of NULL constant to %0">,
+    "implicit conversion of %select{NULL|nullptr}0 constant to %1">,
     InGroup<NullConversion>;
 def warn_impcast_floating_point_to_bool : Warning<
     "implicit conversion turns floating-point number into bool: %0 to %1">,

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=219774&r1=219773&r2=219774&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Oct 14 22:42:06 2014
@@ -6167,6 +6167,41 @@ void CheckImplicitArgumentConversions(Se
   }
 }
 
+static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T,
+                                   SourceLocation CC) {
+  if (S.Diags.isIgnored(diag::warn_impcast_null_pointer_to_integer,
+                        E->getExprLoc()))
+    return;
+
+  // Check for NULL (GNUNull) or nullptr (CXX11_nullptr).
+  const Expr::NullPointerConstantKind NullKind =
+      E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull);
+  if (NullKind != Expr::NPCK_GNUNull && NullKind != Expr::NPCK_CXX11_nullptr)
+    return;
+
+  // Return if target type is a safe conversion.
+  if (T->isAnyPointerType() || T->isBlockPointerType() ||
+      T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType())
+    return;
+
+  SourceLocation Loc = E->getSourceRange().getBegin();
+
+  // __null is usually wrapped in a macro.  Go up a macro if that is the case.
+  if (NullKind == Expr::NPCK_GNUNull) {
+    if (Loc.isMacroID())
+      Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first;
+  }
+
+  // Only warn if the null and context location are in the same macro expansion.
+  if (S.SourceMgr.getFileID(Loc) != S.SourceMgr.getFileID(CC))
+    return;
+
+  S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
+      << (NullKind == Expr::NPCK_CXX11_nullptr) << T << clang::SourceRange(CC)
+      << FixItHint::CreateReplacement(Loc,
+                                      S.getFixItZeroLiteralForType(T, Loc));
+}
+
 void CheckImplicitConversion(Sema &S, Expr *E, QualType T,
                              SourceLocation CC, bool *ICContext = nullptr) {
   if (E->isTypeDependent() || E->isValueDependent()) return;
@@ -6309,19 +6344,7 @@ void CheckImplicitConversion(Sema &S, Ex
     return;
   }
 
-  if ((E->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull)
-           == Expr::NPCK_GNUNull) && !Target->isAnyPointerType()
-      && !Target->isBlockPointerType() && !Target->isMemberPointerType()
-      && Target->isScalarType() && !Target->isNullPtrType()) {
-    SourceLocation Loc = E->getSourceRange().getBegin();
-    if (Loc.isMacroID())
-      Loc = S.SourceMgr.getImmediateExpansionRange(Loc).first;
-    if (!Loc.isMacroID() || CC.isMacroID())
-      S.Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
-          << T << clang::SourceRange(CC)
-          << FixItHint::CreateReplacement(Loc,
-                                          S.getFixItZeroLiteralForType(T, Loc));
-  }
+  DiagnoseNullConversion(S, E, T, CC);
 
   if (!Source->isIntegerType() || !Target->isIntegerType())
     return;

Modified: cfe/trunk/test/SemaCXX/conversion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion.cpp?rev=219774&r1=219773&r2=219774&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conversion.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion.cpp Tue Oct 14 22:42:06 2014
@@ -90,6 +90,18 @@ void test3() {
     ;
   do ;
   while(NULL_COND(true));
+
+#define NULL_WRAPPER NULL_COND(false)
+  if (NULL_WRAPPER)
+    ;
+  while (NULL_WRAPPER)
+    ;
+  for (; NULL_WRAPPER;)
+    ;
+  do
+    ;
+  while (NULL_WRAPPER);
+
   int *ip = NULL;
   int (*fp)() = NULL;
   struct foo {
@@ -137,3 +149,11 @@ namespace test6 {
     return NULL;
   }
 }
+
+namespace test7 {
+  bool fun() {
+    bool x = nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+    if (nullptr) {} // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+    return nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}}
+  }
+}

Modified: cfe/trunk/test/SemaCXX/nullptr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nullptr.cpp?rev=219774&r1=219773&r2=219774&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nullptr.cpp (original)
+++ cfe/trunk/test/SemaCXX/nullptr.cpp Tue Oct 14 22:42:06 2014
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -ffreestanding %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -ffreestanding -Wno-null-conversion %s
 #include <stdint.h>
 
 typedef decltype(nullptr) nullptr_t;





More information about the cfe-commits mailing list