diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2014-10-23 19:00:10 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2014-10-23 19:00:10 +0000 |
commit | 4c8cb14c1ab0abe44bef7b19e53671d28685372b (patch) | |
tree | ae48aaa0c45f2481783f8d38e64d3f792a710a7a /clang/lib/Sema/SemaChecking.cpp | |
parent | 28d6b27bbad4f1bd1be6e45ee0339dcbe429de56 (diff) | |
download | bcm5719-llvm-4c8cb14c1ab0abe44bef7b19e53671d28685372b.tar.gz bcm5719-llvm-4c8cb14c1ab0abe44bef7b19e53671d28685372b.zip |
patch to issue warning on comparing parameters with
nonnull attribute when comparison is always
true/false. Patch by Steven Wu with few fixes and minor
refactoring and adding tests by me. rdar://18712242
llvm-svn: 220496
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index fd2fa0c3f36..495fa3253e6 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -6678,7 +6678,37 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E, // Weak Decls can be null. if (!D || D->isWeak()) return; - + // Check for parameter decl with nonnull attribute + if (ParmVarDecl* PV = dyn_cast<ParmVarDecl>(D)) { + if (FunctionDecl* FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) { + unsigned NumArgs = FD->getNumParams(); + llvm::SmallBitVector AttrNonNull(NumArgs); + for (const auto *NonNull : FD->specific_attrs<NonNullAttr>()) { + if (!NonNull->args_size()) { + AttrNonNull.set(0, NumArgs); + break; + } + for (unsigned Val : NonNull->args()) { + if (Val >= NumArgs) + continue; + AttrNonNull.set(Val); + } + } + if (!AttrNonNull.empty()) + for (unsigned i = 0; i < NumArgs; ++i) + if (FD->getParamDecl(i) == PV && AttrNonNull[i]) { + std::string Str; + llvm::raw_string_ostream S(Str); + E->printPretty(S, nullptr, getPrintingPolicy()); + unsigned DiagID = IsCompare ? diag::warn_nonnull_parameter_compare + : diag::warn_cast_nonnull_to_bool; + Diag(E->getExprLoc(), DiagID) << S.str() << E->getSourceRange() + << Range << IsEqual; + return; + } + } + } + QualType T = D->getType(); const bool IsArray = T->isArrayType(); const bool IsFunction = T->isFunctionType(); |