summaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-07-26 19:36:28 +0000
commitcfca06d7963fa0909f90483b42a6d7d194d01e08 (patch)
tree209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
parent706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff)
Notes
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp33
1 files changed, 23 insertions, 10 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
index 85370bf133cd..90c5583d8969 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp
@@ -95,6 +95,15 @@ public:
};
}
+static bool hasReservedReturnType(const FunctionDecl *D) {
+ if (isa<CXXConstructorDecl>(D))
+ return true;
+
+ // operators delete and delete[] are required to have 'void' return type
+ auto OperatorKind = D->getOverloadedOperator();
+ return OperatorKind == OO_Delete || OperatorKind == OO_Array_Delete;
+}
+
void CFErrorFunctionChecker::checkASTDecl(const FunctionDecl *D,
AnalysisManager &mgr,
BugReporter &BR) const {
@@ -102,6 +111,8 @@ void CFErrorFunctionChecker::checkASTDecl(const FunctionDecl *D,
return;
if (!D->getReturnType()->isVoidType())
return;
+ if (hasReservedReturnType(D))
+ return;
if (!II)
II = &D->getASTContext().Idents.get("CFErrorRef");
@@ -133,14 +144,14 @@ namespace {
class NSErrorDerefBug : public BugType {
public:
- NSErrorDerefBug(const CheckerBase *Checker)
+ NSErrorDerefBug(const CheckerNameRef Checker)
: BugType(Checker, "NSError** null dereference",
"Coding conventions (Apple)") {}
};
class CFErrorDerefBug : public BugType {
public:
- CFErrorDerefBug(const CheckerBase *Checker)
+ CFErrorDerefBug(const CheckerNameRef Checker)
: BugType(Checker, "CFErrorRef* null dereference",
"Coding conventions (Apple)") {}
};
@@ -155,9 +166,9 @@ class NSOrCFErrorDerefChecker
mutable std::unique_ptr<NSErrorDerefBug> NSBT;
mutable std::unique_ptr<CFErrorDerefBug> CFBT;
public:
- bool ShouldCheckNSError, ShouldCheckCFError;
- NSOrCFErrorDerefChecker() : NSErrorII(nullptr), CFErrorII(nullptr),
- ShouldCheckNSError(0), ShouldCheckCFError(0) { }
+ DefaultBool ShouldCheckNSError, ShouldCheckCFError;
+ CheckerNameRef NSErrorName, CFErrorName;
+ NSOrCFErrorDerefChecker() : NSErrorII(nullptr), CFErrorII(nullptr) {}
void checkLocation(SVal loc, bool isLoad, const Stmt *S,
CheckerContext &C) const;
@@ -265,12 +276,12 @@ void NSOrCFErrorDerefChecker::checkEvent(ImplicitNullDerefEvent event) const {
BugType *bug = nullptr;
if (isNSError) {
if (!NSBT)
- NSBT.reset(new NSErrorDerefBug(this));
+ NSBT.reset(new NSErrorDerefBug(NSErrorName));
bug = NSBT.get();
}
else {
if (!CFBT)
- CFBT.reset(new CFErrorDerefBug(this));
+ CFBT.reset(new CFErrorDerefBug(CFErrorName));
bug = CFBT.get();
}
BR.emitReport(
@@ -312,7 +323,7 @@ void ento::registerNSOrCFErrorDerefChecker(CheckerManager &mgr) {
mgr.registerChecker<NSOrCFErrorDerefChecker>();
}
-bool ento::shouldRegisterNSOrCFErrorDerefChecker(const LangOptions &LO) {
+bool ento::shouldRegisterNSOrCFErrorDerefChecker(const CheckerManager &mgr) {
return true;
}
@@ -320,9 +331,10 @@ void ento::registerNSErrorChecker(CheckerManager &mgr) {
mgr.registerChecker<NSErrorMethodChecker>();
NSOrCFErrorDerefChecker *checker = mgr.getChecker<NSOrCFErrorDerefChecker>();
checker->ShouldCheckNSError = true;
+ checker->NSErrorName = mgr.getCurrentCheckerName();
}
-bool ento::shouldRegisterNSErrorChecker(const LangOptions &LO) {
+bool ento::shouldRegisterNSErrorChecker(const CheckerManager &mgr) {
return true;
}
@@ -330,8 +342,9 @@ void ento::registerCFErrorChecker(CheckerManager &mgr) {
mgr.registerChecker<CFErrorFunctionChecker>();
NSOrCFErrorDerefChecker *checker = mgr.getChecker<NSOrCFErrorDerefChecker>();
checker->ShouldCheckCFError = true;
+ checker->CFErrorName = mgr.getCurrentCheckerName();
}
-bool ento::shouldRegisterCFErrorChecker(const LangOptions &LO) {
+bool ento::shouldRegisterCFErrorChecker(const CheckerManager &mgr) {
return true;
}