diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:18:08 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:18:08 +0000 |
commit | bab175ec4b075c8076ba14c762900392533f6ee4 (patch) | |
tree | 01f4f29419a2cb10abe13c1e63cd2a66068b0137 /lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp | |
parent | 8b7a8012d223fac5d17d16a66bb39168a9a1dfc0 (diff) |
Notes
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp new file mode 100644 index 0000000000000..b9857e51f3eaa --- /dev/null +++ b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp @@ -0,0 +1,82 @@ +//==- ObjCPropertyChecker.cpp - Check ObjC properties ------------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This checker finds issues with Objective-C properties. +// Currently finds only one kind of issue: +// - Find synthesized properties with copy attribute of mutable NS collection +// types. Calling -copy on such collections produces an immutable copy, +// which contradicts the type of the property. +// +//===----------------------------------------------------------------------===// + +#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" +#include "clang/StaticAnalyzer/Core/Checker.h" + +using namespace clang; +using namespace ento; + +namespace { +class ObjCPropertyChecker + : public Checker<check::ASTDecl<ObjCPropertyDecl>> { + void checkCopyMutable(const ObjCPropertyDecl *D, BugReporter &BR) const; + +public: + void checkASTDecl(const ObjCPropertyDecl *D, AnalysisManager &Mgr, + BugReporter &BR) const; +}; +} // end anonymous namespace. + +void ObjCPropertyChecker::checkASTDecl(const ObjCPropertyDecl *D, + AnalysisManager &Mgr, + BugReporter &BR) const { + checkCopyMutable(D, BR); +} + +void ObjCPropertyChecker::checkCopyMutable(const ObjCPropertyDecl *D, + BugReporter &BR) const { + if (D->isReadOnly() || D->getSetterKind() != ObjCPropertyDecl::Copy) + return; + + QualType T = D->getType(); + if (!T->isObjCObjectPointerType()) + return; + + const std::string &PropTypeName(T->getPointeeType().getCanonicalType() + .getUnqualifiedType() + .getAsString()); + if (!StringRef(PropTypeName).startswith("NSMutable")) + return; + + const ObjCImplDecl *ImplD = nullptr; + if (const ObjCInterfaceDecl *IntD = + dyn_cast<ObjCInterfaceDecl>(D->getDeclContext())) { + ImplD = IntD->getImplementation(); + } else { + const ObjCCategoryDecl *CatD = cast<ObjCCategoryDecl>(D->getDeclContext()); + ImplD = CatD->getClassInterface()->getImplementation(); + } + + if (!ImplD || ImplD->HasUserDeclaredSetterMethod(D)) + return; + + SmallString<128> Str; + llvm::raw_svector_ostream OS(Str); + OS << "Property of mutable type '" << PropTypeName + << "' has 'copy' attribute; an immutable object will be stored instead"; + + BR.EmitBasicReport( + D, this, "Objective-C property misuse", "Logic error", OS.str(), + PathDiagnosticLocation::createBegin(D, BR.getSourceManager()), + D->getSourceRange()); +} + +void ento::registerObjCPropertyChecker(CheckerManager &Mgr) { + Mgr.registerChecker<ObjCPropertyChecker>(); +} |