summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2014-10-15 03:42:06 +0000
committerRichard Trieu <rtrieu@google.com>2014-10-15 03:42:06 +0000
commit5b993500aec59e3b42038e1d335da6fc6a78886d (patch)
treeeb478b689c9a43968b5e83abd0239187ade088b7 /clang
parent2954280f6a2bbc611b5731535473c4fe1b5378bd (diff)
downloadbcm5719-llvm-5b993500aec59e3b42038e1d335da6fc6a78886d.tar.gz
bcm5719-llvm-5b993500aec59e3b42038e1d335da6fc6a78886d.zip
Improvements to -Wnull-conversion
Split logic to separate checking function Refine the macro checking Catch nullptr->bool conversions Add some explanatory comments llvm-svn: 219774
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaChecking.cpp49
-rw-r--r--clang/test/SemaCXX/conversion.cpp20
-rw-r--r--clang/test/SemaCXX/nullptr.cpp2
4 files changed, 58 insertions, 15 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 70ead3ad095..54d7040ce2c 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2490,7 +2490,7 @@ def warn_non_literal_null_pointer : Warning<
"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">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a98b87544a6..fd2fa0c3f36 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6167,6 +6167,41 @@ void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall,
}
}
+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, Expr *E, QualType T,
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;
diff --git a/clang/test/SemaCXX/conversion.cpp b/clang/test/SemaCXX/conversion.cpp
index 852bbba7efa..b8f0e076a2b 100644
--- a/clang/test/SemaCXX/conversion.cpp
+++ b/clang/test/SemaCXX/conversion.cpp
@@ -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'}}
+ }
+}
diff --git a/clang/test/SemaCXX/nullptr.cpp b/clang/test/SemaCXX/nullptr.cpp
index 28798a4f8ce..7d765b482c7 100644
--- a/clang/test/SemaCXX/nullptr.cpp
+++ b/clang/test/SemaCXX/nullptr.cpp
@@ -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;
OpenPOWER on IntegriCloud