diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp | 63 |
1 files changed, 35 insertions, 28 deletions
diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp index 9f01522..2be7f1d 100644 --- a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp +++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp @@ -42,7 +42,7 @@ class NSErrorMethodChecker mutable IdentifierInfo *II; public: - NSErrorMethodChecker() : II(0) { } + NSErrorMethodChecker() : II(nullptr) {} void checkASTDecl(const ObjCMethodDecl *D, AnalysisManager &mgr, BugReporter &BR) const; @@ -54,16 +54,15 @@ void NSErrorMethodChecker::checkASTDecl(const ObjCMethodDecl *D, BugReporter &BR) const { if (!D->isThisDeclarationADefinition()) return; - if (!D->getResultType()->isVoidType()) + if (!D->getReturnType()->isVoidType()) return; if (!II) II = &D->getASTContext().Idents.get("NSError"); bool hasNSError = false; - for (ObjCMethodDecl::param_const_iterator - I = D->param_begin(), E = D->param_end(); I != E; ++I) { - if (IsNSError((*I)->getType(), II)) { + for (const auto *I : D->params()) { + if (IsNSError(I->getType(), II)) { hasNSError = true; break; } @@ -75,7 +74,7 @@ void NSErrorMethodChecker::checkASTDecl(const ObjCMethodDecl *D, "error occurred"; PathDiagnosticLocation L = PathDiagnosticLocation::create(D, BR.getSourceManager()); - BR.EmitBasicReport(D, "Bad return type when passing NSError**", + BR.EmitBasicReport(D, this, "Bad return type when passing NSError**", "Coding conventions (Apple)", err, L); } } @@ -90,7 +89,7 @@ class CFErrorFunctionChecker mutable IdentifierInfo *II; public: - CFErrorFunctionChecker() : II(0) { } + CFErrorFunctionChecker() : II(nullptr) {} void checkASTDecl(const FunctionDecl *D, AnalysisManager &mgr, BugReporter &BR) const; @@ -102,16 +101,15 @@ void CFErrorFunctionChecker::checkASTDecl(const FunctionDecl *D, BugReporter &BR) const { if (!D->doesThisDeclarationHaveABody()) return; - if (!D->getResultType()->isVoidType()) + if (!D->getReturnType()->isVoidType()) return; if (!II) II = &D->getASTContext().Idents.get("CFErrorRef"); bool hasCFError = false; - for (FunctionDecl::param_const_iterator - I = D->param_begin(), E = D->param_end(); I != E; ++I) { - if (IsCFError((*I)->getType(), II)) { + for (auto I : D->params()) { + if (IsCFError(I->getType(), II)) { hasCFError = true; break; } @@ -123,7 +121,7 @@ void CFErrorFunctionChecker::checkASTDecl(const FunctionDecl *D, "error occurred"; PathDiagnosticLocation L = PathDiagnosticLocation::create(D, BR.getSourceManager()); - BR.EmitBasicReport(D, "Bad return type when passing CFErrorRef*", + BR.EmitBasicReport(D, this, "Bad return type when passing CFErrorRef*", "Coding conventions (Apple)", err, L); } } @@ -136,14 +134,16 @@ namespace { class NSErrorDerefBug : public BugType { public: - NSErrorDerefBug() : BugType("NSError** null dereference", - "Coding conventions (Apple)") {} + NSErrorDerefBug(const CheckerBase *Checker) + : BugType(Checker, "NSError** null dereference", + "Coding conventions (Apple)") {} }; class CFErrorDerefBug : public BugType { public: - CFErrorDerefBug() : BugType("CFErrorRef* null dereference", - "Coding conventions (Apple)") {} + CFErrorDerefBug(const CheckerBase *Checker) + : BugType(Checker, "CFErrorRef* null dereference", + "Coding conventions (Apple)") {} }; } @@ -153,9 +153,11 @@ class NSOrCFErrorDerefChecker : public Checker< check::Location, check::Event<ImplicitNullDerefEvent> > { mutable IdentifierInfo *NSErrorII, *CFErrorII; + mutable std::unique_ptr<NSErrorDerefBug> NSBT; + mutable std::unique_ptr<CFErrorDerefBug> CFBT; public: bool ShouldCheckNSError, ShouldCheckCFError; - NSOrCFErrorDerefChecker() : NSErrorII(0), CFErrorII(0), + NSOrCFErrorDerefChecker() : NSErrorII(nullptr), CFErrorII(nullptr), ShouldCheckNSError(0), ShouldCheckCFError(0) { } void checkLocation(SVal loc, bool isLoad, const Stmt *S, @@ -262,13 +264,18 @@ void NSOrCFErrorDerefChecker::checkEvent(ImplicitNullDerefEvent event) const { os << " may be null"; - BugType *bug = 0; - if (isNSError) - bug = new NSErrorDerefBug(); - else - bug = new CFErrorDerefBug(); - BugReport *report = new BugReport(*bug, os.str(), - event.SinkNode); + BugType *bug = nullptr; + if (isNSError) { + if (!NSBT) + NSBT.reset(new NSErrorDerefBug(this)); + bug = NSBT.get(); + } + else { + if (!CFBT) + CFBT.reset(new CFErrorDerefBug(this)); + bug = CFBT.get(); + } + BugReport *report = new BugReport(*bug, os.str(), event.SinkNode); BR.emitReport(report); } @@ -305,14 +312,14 @@ static bool IsCFError(QualType T, IdentifierInfo *II) { void ento::registerNSErrorChecker(CheckerManager &mgr) { mgr.registerChecker<NSErrorMethodChecker>(); - NSOrCFErrorDerefChecker * - checker = mgr.registerChecker<NSOrCFErrorDerefChecker>(); + NSOrCFErrorDerefChecker *checker = + mgr.registerChecker<NSOrCFErrorDerefChecker>(); checker->ShouldCheckNSError = true; } void ento::registerCFErrorChecker(CheckerManager &mgr) { mgr.registerChecker<CFErrorFunctionChecker>(); - NSOrCFErrorDerefChecker * - checker = mgr.registerChecker<NSOrCFErrorDerefChecker>(); + NSOrCFErrorDerefChecker *checker = + mgr.registerChecker<NSOrCFErrorDerefChecker>(); checker->ShouldCheckCFError = true; } |