diff options
author | Richard Trieu <rtrieu@google.com> | 2014-10-15 03:42:06 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2014-10-15 03:42:06 +0000 |
commit | 5b993500aec59e3b42038e1d335da6fc6a78886d (patch) | |
tree | eb478b689c9a43968b5e83abd0239187ade088b7 /clang/lib/Sema/SemaChecking.cpp | |
parent | 2954280f6a2bbc611b5731535473c4fe1b5378bd (diff) | |
download | bcm5719-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/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 49 |
1 files changed, 36 insertions, 13 deletions
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; |