summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGeorge Karpenkov <ekarpenkov@apple.com>2018-08-21 03:09:02 +0000
committerGeorge Karpenkov <ekarpenkov@apple.com>2018-08-21 03:09:02 +0000
commit3025b837ed076a70786893c4a96a4389c53c487e (patch)
treec1a491b871058f9efcb526967506b194aa7fcc93 /lib
parent43e71a0b50e85ee4b755ca43e554099dba14decc (diff)
downloadclang-3025b837ed076a70786893c4a96a4389c53c487e.tar.gz
[analyzer] [NFC] Split up RetainSummaryManager from RetainCountChecker - try #2
Turns out it can't be removed from the analyzer since it relies on CallEvent. Moving to staticAnalyzer/core Differential Revision: https://reviews.llvm.org/D51023 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340247 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/ARCMigrate/ObjCMT.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CMakeLists.txt4
-rw-r--r--lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp54
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h6
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h2
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.h518
-rw-r--r--lib/StaticAnalyzer/Checkers/SelectorExtras.h46
-rw-r--r--lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/CMakeLists.txt1
-rw-r--r--lib/StaticAnalyzer/Core/RetainSummaryManager.cpp (renamed from lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.cpp)58
12 files changed, 59 insertions, 640 deletions
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index 7353c8c479..d202411429 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include "Transforms.h"
-#include "clang/Analysis/ObjCRetainCount.h"
#include "clang/ARCMigrate/ARCMT.h"
#include "clang/ARCMigrate/ARCMTActions.h"
#include "clang/AST/ASTConsumer.h"
@@ -28,6 +27,7 @@
#include "clang/Lex/PPConditionalDirectiveRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Path.h"
@@ -36,7 +36,7 @@
using namespace clang;
using namespace arcmt;
-using namespace ento::objc_retain;
+using namespace ento;
namespace {
diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index cff0f0a29b..70ce41ac89 100644
--- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -14,13 +14,13 @@
//===----------------------------------------------------------------------===//
#include "ClangSACheckers.h"
-#include "SelectorExtras.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/StmtObjC.h"
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
+#include "clang/Analysis/SelectorExtras.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 0b2aab94da..306813b880 100644
--- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -77,7 +77,6 @@ add_clang_library(clangStaticAnalyzerCheckers
PointerSubChecker.cpp
PthreadLockChecker.cpp
RetainCountChecker/RetainCountChecker.cpp
- RetainCountChecker/RetainCountSummaries.cpp
RetainCountChecker/RetainCountDiagnostics.cpp
ReturnPointerRangeChecker.cpp
ReturnUndefChecker.cpp
@@ -104,9 +103,6 @@ add_clang_library(clangStaticAnalyzerCheckers
ValistChecker.cpp
VirtualCallChecker.cpp
- DEPENDS
- ClangSACheckers
-
LINK_LIBS
clangAST
clangASTMatchers
diff --git a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
index 8a5c769b6b..44674eb4d7 100644
--- a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
@@ -13,8 +13,8 @@
//===----------------------------------------------------------------------===//
#include "ClangSACheckers.h"
-#include "SelectorExtras.h"
#include "clang/AST/Attr.h"
+#include "clang/Analysis/SelectorExtras.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
index a8957e1704..9d6c8314d8 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -16,7 +16,6 @@
using namespace clang;
using namespace ento;
-using namespace objc_retain;
using namespace retaincountchecker;
using llvm::StrInStrNoCase;
@@ -331,7 +330,19 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
void RetainCountChecker::checkPostCall(const CallEvent &Call,
CheckerContext &C) const {
RetainSummaryManager &Summaries = getSummaryManager(C);
- const RetainSummary *Summ = Summaries.getSummary(Call, C.getState());
+
+ // Leave null if no receiver.
+ QualType ReceiverType;
+ if (const auto *MC = dyn_cast<ObjCMethodCall>(&Call)) {
+ if (MC->isInstanceMessage()) {
+ SVal ReceiverV = MC->getReceiverSVal();
+ if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
+ if (const RefVal *T = getRefBinding(C.getState(), Sym))
+ ReceiverType = T->getType();
+ }
+ }
+
+ const RetainSummary *Summ = Summaries.getSummary(Call, ReceiverType);
if (C.wasInlined) {
processSummaryOfInlined(*Summ, Call, C);
@@ -1388,45 +1399,6 @@ void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
}
//===----------------------------------------------------------------------===//
-// Implementation of the CallEffects API.
-//===----------------------------------------------------------------------===//
-
-namespace clang {
-namespace ento {
-namespace objc_retain {
-
-// This is a bit gross, but it allows us to populate CallEffects without
-// creating a bunch of accessors. This kind is very localized, so the
-// damage of this macro is limited.
-#define createCallEffect(D, KIND)\
- ASTContext &Ctx = D->getASTContext();\
- LangOptions L = Ctx.getLangOpts();\
- RetainSummaryManager M(Ctx, L.ObjCAutoRefCount);\
- const RetainSummary *S = M.get ## KIND ## Summary(D);\
- CallEffects CE(S->getRetEffect());\
- CE.Receiver = S->getReceiverEffect();\
- unsigned N = D->param_size();\
- for (unsigned i = 0; i < N; ++i) {\
- CE.Args.push_back(S->getArg(i));\
- }
-
-CallEffects CallEffects::getEffect(const ObjCMethodDecl *MD) {
- createCallEffect(MD, Method);
- return CE;
-}
-
-CallEffects CallEffects::getEffect(const FunctionDecl *FD) {
- createCallEffect(FD, Function);
- return CE;
-}
-
-#undef createCallEffect
-
-} // end namespace objc_retain
-} // end namespace ento
-} // end namespace clang
-
-//===----------------------------------------------------------------------===//
// Checker registration.
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
index 9946591c4d..15172a9deb 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h
@@ -17,10 +17,7 @@
#include "../ClangSACheckers.h"
#include "../AllocationDiagnostics.h"
-#include "../SelectorExtras.h"
-#include "RetainCountSummaries.h"
#include "RetainCountDiagnostics.h"
-#include "clang/Analysis/ObjCRetainCount.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -28,6 +25,7 @@
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Analysis/SelectorExtras.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
@@ -36,6 +34,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
+#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableList.h"
@@ -46,7 +45,6 @@
#include <cstdarg>
#include <utility>
-using namespace objc_retain;
using llvm::StrInStrNoCase;
namespace clang {
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
index cbdfe3a916..83c2be8298 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h
@@ -15,10 +15,10 @@
#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H
#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_DIAGNOSTICS_H
-#include "RetainCountSummaries.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
namespace clang {
namespace ento {
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.h b/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.h
deleted file mode 100644
index dd56a44858..0000000000
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.h
+++ /dev/null
@@ -1,518 +0,0 @@
-//=== RetainCountSummaries.h - Checks for leaks and other issues -*- C++ -*--//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines summaries implementation for RetainCountChecker, which
-// implements a reference count checker for Core Foundation and Cocoa
-// on (Mac OS X).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_SUMMARY_H
-#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_RETAINCOUNTCHECKER_SUMMARY_H
-
-#include "../ClangSACheckers.h"
-#include "../AllocationDiagnostics.h"
-#include "../SelectorExtras.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "clang/Analysis/ObjCRetainCount.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/ParentMap.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include "clang/StaticAnalyzer/Core/Checker.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "llvm/ADT/ImmutableList.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/STLExtras.h"
-
-//===----------------------------------------------------------------------===//
-// Adapters for FoldingSet.
-//===----------------------------------------------------------------------===//
-
-using namespace clang;
-using namespace ento;
-using namespace objc_retain;
-
-namespace clang {
-namespace ento {
-namespace retaincountchecker {
-
-/// A key identifying a summary.
-class ObjCSummaryKey {
- IdentifierInfo* II;
- Selector S;
-public:
- ObjCSummaryKey(IdentifierInfo* ii, Selector s)
- : II(ii), S(s) {}
-
- ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s)
- : II(d ? d->getIdentifier() : nullptr), S(s) {}
-
- ObjCSummaryKey(Selector s)
- : II(nullptr), S(s) {}
-
- IdentifierInfo *getIdentifier() const { return II; }
- Selector getSelector() const { return S; }
-};
-
-} // end namespace retaincountchecker
-} // end namespace ento
-} // end namespace clang
-
-namespace llvm {
-using namespace retaincountchecker;
-
-template <> struct FoldingSetTrait<ArgEffect> {
-static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {
- ID.AddInteger((unsigned) X);
-}
-};
-template <> struct FoldingSetTrait<RetEffect> {
- static inline void Profile(const RetEffect &X, FoldingSetNodeID &ID) {
- ID.AddInteger((unsigned) X.getKind());
- ID.AddInteger((unsigned) X.getObjKind());
-}
-};
-
-template <> struct DenseMapInfo<ObjCSummaryKey> {
- static inline ObjCSummaryKey getEmptyKey() {
- return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),
- DenseMapInfo<Selector>::getEmptyKey());
- }
-
- static inline ObjCSummaryKey getTombstoneKey() {
- return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(),
- DenseMapInfo<Selector>::getTombstoneKey());
- }
-
- static unsigned getHashValue(const ObjCSummaryKey &V) {
- typedef std::pair<IdentifierInfo*, Selector> PairTy;
- return DenseMapInfo<PairTy>::getHashValue(PairTy(V.getIdentifier(),
- V.getSelector()));
- }
-
- static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {
- return LHS.getIdentifier() == RHS.getIdentifier() &&
- LHS.getSelector() == RHS.getSelector();
- }
-
-};
-
-} // end llvm namespace
-
-
-namespace clang {
-namespace ento {
-namespace retaincountchecker {
-
-/// ArgEffects summarizes the effects of a function/method call on all of
-/// its arguments.
-typedef llvm::ImmutableMap<unsigned, ArgEffect> ArgEffects;
-
-/// Summary for a function with respect to ownership changes.
-class RetainSummary {
- /// Args - a map of (index, ArgEffect) pairs, where index
- /// specifies the argument (starting from 0). This can be sparsely
- /// populated; arguments with no entry in Args use 'DefaultArgEffect'.
- ArgEffects Args;
-
- /// DefaultArgEffect - The default ArgEffect to apply to arguments that
- /// do not have an entry in Args.
- ArgEffect DefaultArgEffect;
-
- /// Receiver - If this summary applies to an Objective-C message expression,
- /// this is the effect applied to the state of the receiver.
- ArgEffect Receiver;
-
- /// Ret - The effect on the return value. Used to indicate if the
- /// function/method call returns a new tracked symbol.
- RetEffect Ret;
-
-public:
- RetainSummary(ArgEffects A, RetEffect R, ArgEffect defaultEff,
- ArgEffect ReceiverEff)
- : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R) {}
-
- /// getArg - Return the argument effect on the argument specified by
- /// idx (starting from 0).
- ArgEffect getArg(unsigned idx) const {
- if (const ArgEffect *AE = Args.lookup(idx))
- return *AE;
-
- return DefaultArgEffect;
- }
-
- void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e) {
- Args = af.add(Args, idx, e);
- }
-
- /// setDefaultArgEffect - Set the default argument effect.
- void setDefaultArgEffect(ArgEffect E) {
- DefaultArgEffect = E;
- }
-
- /// getRetEffect - Returns the effect on the return value of the call.
- RetEffect getRetEffect() const { return Ret; }
-
- /// setRetEffect - Set the effect of the return value of the call.
- void setRetEffect(RetEffect E) { Ret = E; }
-
-
- /// Sets the effect on the receiver of the message.
- void setReceiverEffect(ArgEffect e) { Receiver = e; }
-
- /// getReceiverEffect - Returns the effect on the receiver of the call.
- /// This is only meaningful if the summary applies to an ObjCMessageExpr*.
- ArgEffect getReceiverEffect() const { return Receiver; }
-
- /// Test if two retain summaries are identical. Note that merely equivalent
- /// summaries are not necessarily identical (for example, if an explicit
- /// argument effect matches the default effect).
- bool operator==(const RetainSummary &Other) const {
- return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&
- Receiver == Other.Receiver && Ret == Other.Ret;
- }
-
- /// Profile this summary for inclusion in a FoldingSet.
- void Profile(llvm::FoldingSetNodeID& ID) const {
- ID.Add(Args);
- ID.Add(DefaultArgEffect);
- ID.Add(Receiver);
- ID.Add(Ret);
- }
-
- /// A retain summary is simple if it has no ArgEffects other than the default.
- bool isSimple() const {
- return Args.isEmpty();
- }
-
-private:
- ArgEffects getArgEffects() const { return Args; }
- ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
-
- friend class RetainSummaryManager;
- friend class RetainCountChecker;
-};
-
-class ObjCSummaryCache {
- typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *> MapTy;
- MapTy M;
-public:
- ObjCSummaryCache() {}
-
- const RetainSummary * find(const ObjCInterfaceDecl *D, Selector S) {
- // Do a lookup with the (D,S) pair. If we find a match return
- // the iterator.
- ObjCSummaryKey K(D, S);
- MapTy::iterator I = M.find(K);
-
- if (I != M.end())
- return I->second;
- if (!D)
- return nullptr;
-
- // Walk the super chain. If we find a hit with a parent, we'll end
- // up returning that summary. We actually allow that key (null,S), as
- // we cache summaries for the null ObjCInterfaceDecl* to allow us to
- // generate initial summaries without having to worry about NSObject
- // being declared.
- // FIXME: We may change this at some point.
- for (ObjCInterfaceDecl *C=D->getSuperClass() ;; C=C->getSuperClass()) {
- if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())
- break;
-
- if (!C)
- return nullptr;
- }
-
- // Cache the summary with original key to make the next lookup faster
- // and return the iterator.
- const RetainSummary *Summ = I->second;
- M[K] = Summ;
- return Summ;
- }
-
- const RetainSummary *find(IdentifierInfo* II, Selector S) {
- // FIXME: Class method lookup. Right now we don't have a good way
- // of going between IdentifierInfo* and the class hierarchy.
- MapTy::iterator I = M.find(ObjCSummaryKey(II, S));
-
- if (I == M.end())
- I = M.find(ObjCSummaryKey(S));
-
- return I == M.end() ? nullptr : I->second;
- }
-
- const RetainSummary *& operator[](ObjCSummaryKey K) {
- return M[K];
- }
-
- const RetainSummary *& operator[](Selector S) {
- return M[ ObjCSummaryKey(S) ];
- }
-};
-
-class RetainSummaryManager {
- typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *>
- FuncSummariesTy;
-
- typedef ObjCSummaryCache ObjCMethodSummariesTy;
-
- typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;
-
- /// Ctx - The ASTContext object for the analyzed ASTs.
- ASTContext &Ctx;
-
- /// Records whether or not the analyzed code runs in ARC mode.
- const bool ARCEnabled;
-
- /// FuncSummaries - A map from FunctionDecls to summaries.
- FuncSummariesTy FuncSummaries;
-
- /// ObjCClassMethodSummaries - A map from selectors (for instance methods)
- /// to summaries.
- ObjCMethodSummariesTy ObjCClassMethodSummaries;
-
- /// ObjCMethodSummaries - A map from selectors to summaries.
- ObjCMethodSummariesTy ObjCMethodSummaries;
-
- /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,
- /// and all other data used by the checker.
- llvm::BumpPtrAllocator BPAlloc;
-
- /// AF - A factory for ArgEffects objects.
- ArgEffects::Factory AF;
-
- /// ScratchArgs - A holding buffer for construct ArgEffects.
- ArgEffects ScratchArgs;
-
- /// ObjCAllocRetE - Default return effect for methods returning Objective-C
- /// objects.
- RetEffect ObjCAllocRetE;
-
- /// ObjCInitRetE - Default return effect for init methods returning
- /// Objective-C objects.
- RetEffect ObjCInitRetE;
-
- /// SimpleSummaries - Used for uniquing summaries that don't have special
- /// effects.
- llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;
-
- /// getArgEffects - Returns a persistent ArgEffects object based on the
- /// data in ScratchArgs.
- ArgEffects getArgEffects();
-
- enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };
-
- const RetainSummary *getUnarySummary(const FunctionType* FT,
- UnaryFuncKind func);
-
- const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);
- const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);
- const RetainSummary *getCFCreateGetRuleSummary(const FunctionDecl *FD);
-
- const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);
-
- const RetainSummary *getPersistentSummary(RetEffect RetEff,
- ArgEffect ReceiverEff = DoNothing,
- ArgEffect DefaultEff = MayEscape) {
- RetainSummary Summ(getArgEffects(), RetEff, DefaultEff, ReceiverEff);
- return getPersistentSummary(Summ);
- }
-
- const RetainSummary *getDoNothingSummary() {
- return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
- }
-
- const RetainSummary *getDefaultSummary() {
- return getPersistentSummary(RetEffect::MakeNoRet(),
- DoNothing, MayEscape);
- }
-
- const RetainSummary *getPersistentStopSummary() {
- return getPersistentSummary(RetEffect::MakeNoRet(),
- StopTracking, StopTracking);
- }
-
- void InitializeClassMethodSummaries();
- void InitializeMethodSummaries();
-
- void addNSObjectClsMethSummary(Selector S, const RetainSummary *Summ) {
- ObjCClassMethodSummaries[S] = Summ;
- }
-
- void addNSObjectMethSummary(Selector S, const RetainSummary *Summ) {
- ObjCMethodSummaries[S] = Summ;
- }
-
- void addClassMethSummary(const char* Cls, const char* name,
- const RetainSummary *Summ, bool isNullary = true) {
- IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
- Selector S = isNullary ? GetNullarySelector(name, Ctx)
- : GetUnarySelector(name, Ctx);
- ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
- }
-
- void addInstMethSummary(const char* Cls, const char* nullaryName,
- const RetainSummary *Summ) {
- IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);
- Selector S = GetNullarySelector(nullaryName, Ctx);
- ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
- }
-
- template <typename... Keywords>
- void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
- const RetainSummary *Summ, Keywords *... Kws) {
- Selector S = getKeywordSelector(Ctx, Kws...);
- Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
- }
-
- template <typename... Keywords>
- void addInstMethSummary(const char *Cls, const RetainSummary *Summ,
- Keywords *... Kws) {
- addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, Kws...);
- }
-
- template <typename... Keywords>
- void addClsMethSummary(const char *Cls, const RetainSummary *Summ,
- Keywords *... Kws) {
- addMethodSummary(&Ctx.Idents.get(Cls), ObjCClassMethodSummaries, Summ,
- Kws...);
- }
-
- template <typename... Keywords>
- void addClsMethSummary(IdentifierInfo *II, const RetainSummary *Summ,
- Keywords *... Kws) {
- addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);
- }
-
-public:
- RetainSummaryManager(ASTContext &ctx, bool usesARC)
- : Ctx(ctx),
- ARCEnabled(usesARC),
- AF(BPAlloc), ScratchArgs(AF.getEmptyMap()),
- ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
- : RetEffect::MakeOwned(RetEffect::ObjC)),
- ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)
- : RetEffect::MakeOwnedWhenTrackedReceiver()) {
- InitializeClassMethodSummaries();
- InitializeMethodSummaries();
- }
-
- bool canEval(const CallExpr *CE,
- const FunctionDecl *FD,
- bool &hasTrustedImplementationAnnotation);
-
- bool isTrustedReferenceCountImplementation(const FunctionDecl *FD);
-
- const RetainSummary *getSummary(const CallEvent &Call,
- ProgramStateRef State = nullptr);
-
- const RetainSummary *getFunctionSummary(const FunctionDecl *FD);
-
- const RetainSummary *getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,
- const ObjCMethodDecl *MD,
- QualType RetTy,
- ObjCMethodSummariesTy &CachedSummaries);
-
- const RetainSummary *getInstanceMethodSummary(const ObjCMethodCall &M,
- ProgramStateRef State);
-
- const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) {
- assert(!M.isInstanceMessage());
- const ObjCInterfaceDecl *Class = M.getReceiverInterface();
-
- return getMethodSummary(M.getSelector(), Class, M.getDecl(),
- M.getResultType(), ObjCClassMethodSummaries);
- }
-
- /// getMethodSummary - This version of getMethodSummary is used to query
- /// the summary for the current method being analyzed.
- const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {
- const ObjCInterfaceDecl *ID = MD->getClassInterface();
- Selector S = MD->getSelector();
- QualType ResultTy = MD->getReturnType();
-
- ObjCMethodSummariesTy *CachedSummaries;
- if (MD->isInstanceMethod())
- CachedSummaries = &ObjCMethodSummaries;
- else
- CachedSummaries = &ObjCClassMethodSummaries;
-
- return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);
- }
-
- const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD,
- Selector S, QualType RetTy);
-
- /// Determine if there is a special return effect for this function or method.
- Optional<RetEffect> getRetEffectFromAnnotations(QualType RetTy,
- const Decl *D);
-
- void updateSummaryFromAnnotations(const RetainSummary *&Summ,
- const ObjCMethodDecl *MD);
-
- void updateSummaryFromAnnotations(const RetainSummary *&Summ,
- const FunctionDecl *FD);
-
- void updateSummaryForCall(const RetainSummary *&Summ,
- const CallEvent &Call);
-
- bool isARCEnabled() const { return ARCEnabled; }
-
- RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }
-
-private:
- const RetainSummary * generateSummary(const FunctionDecl *FD,
- bool &AllowAnnotations);
-
- friend class RetainSummaryTemplate;
-};
-
-// Used to avoid allocating long-term (BPAlloc'd) memory for default retain
-// summaries. If a function or method looks like it has a default summary, but
-// it has annotations, the annotations are added to the stack-based template
-// and then copied into managed memory.
-class RetainSummaryTemplate {
- RetainSummaryManager &Manager;
- const RetainSummary *&RealSummary;
- RetainSummary ScratchSummary;
- bool Accessed;
-public:
- RetainSummaryTemplate(const RetainSummary *&real, RetainSummaryManager &mgr)
- : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(false) {}
-
- ~RetainSummaryTemplate() {
- if (Accessed)
- RealSummary = Manager.getPersistentSummary(ScratchSummary);
- }
-
- RetainSummary &operator*() {
- Accessed = true;
- return ScratchSummary;
- }
-
- RetainSummary *operator->() {
- Accessed = true;
- return &ScratchSummary;
- }
-};
-
-} // end namespace retaincountchecker
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/lib/StaticAnalyzer/Checkers/SelectorExtras.h b/lib/StaticAnalyzer/Checkers/SelectorExtras.h
deleted file mode 100644
index b11d070c62..0000000000
--- a/lib/StaticAnalyzer/Checkers/SelectorExtras.h
+++ /dev/null
@@ -1,46 +0,0 @@
-//=== SelectorExtras.h - Helpers for checkers using selectors -----*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SELECTOREXTRAS_H
-#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SELECTOREXTRAS_H
-
-#include "clang/AST/ASTContext.h"
-
-namespace clang {
-namespace ento {
-
-template <typename... IdentifierInfos>
-static inline Selector getKeywordSelector(ASTContext &Ctx,
- IdentifierInfos *... IIs) {
- static_assert(sizeof...(IdentifierInfos),
- "keyword selectors must have at least one argument");
- SmallVector<IdentifierInfo *, 10> II({&Ctx.Idents.get(IIs)...});
-
- return Ctx.Selectors.getSelector(II.size(), &II[0]);
-}
-
-template <typename... IdentifierInfos>
-static inline void lazyInitKeywordSelector(Selector &Sel, ASTContext &Ctx,
- IdentifierInfos *... IIs) {
- if (!Sel.isNull())
- return;
- Sel = getKeywordSelector(Ctx, IIs...);
-}
-
-static inline void lazyInitNullarySelector(Selector &Sel, ASTContext &Ctx,
- const char *Name) {
- if (!Sel.isNull())
- return;
- Sel = GetNullarySelector(Name, Ctx);
-}
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp b/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp
index f42c78a769..eed1efd10e 100644
--- a/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp
@@ -20,7 +20,7 @@
//===----------------------------------------------------------------------===//
#include "ClangSACheckers.h"
-#include "SelectorExtras.h"
+#include "clang/Analysis/SelectorExtras.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
diff --git a/lib/StaticAnalyzer/Core/CMakeLists.txt b/lib/StaticAnalyzer/Core/CMakeLists.txt
index de994b598e..86f2abf8b2 100644
--- a/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -44,6 +44,7 @@ add_clang_library(clangStaticAnalyzerCore
RangeConstraintManager.cpp
RangedConstraintManager.cpp
RegionStore.cpp
+ RetainSummaryManager.cpp
SValBuilder.cpp
SVals.cpp
SimpleConstraintManager.cpp
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.cpp b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
index 18813741f2..a2e716f56f 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.cpp
+++ b/lib/StaticAnalyzer/Core/RetainSummaryManager.cpp
@@ -1,4 +1,4 @@
-//== RetainCountSummaries.cpp - Checks for leaks and other issues -*- C++ -*--//
+//== RetainSummaryManager.cpp - Summaries for reference counting --*- C++ -*--//
//
// The LLVM Compiler Infrastructure
//
@@ -7,25 +7,21 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines summaries implementation for RetainCountChecker, which
+// This file defines summaries implementation for retain counting, which
// implements a reference count checker for Core Foundation and Cocoa
// on (Mac OS X).
//
//===----------------------------------------------------------------------===//
-#include "RetainCountSummaries.h"
-#include "RetainCountChecker.h"
-
+#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ParentMap.h"
-using namespace objc_retain;
using namespace clang;
using namespace ento;
-using namespace retaincountchecker;
ArgEffects RetainSummaryManager::getArgEffects() {
ArgEffects AE = ScratchArgs;
@@ -408,7 +404,7 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,
const RetainSummary *
RetainSummaryManager::getSummary(const CallEvent &Call,
- ProgramStateRef State) {
+ QualType ReceiverType) {
const RetainSummary *Summ;
switch (Call.getKind()) {
case CE_Function:
@@ -425,7 +421,7 @@ RetainSummaryManager::getSummary(const CallEvent &Call,
case CE_ObjCMessage: {
const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
if (Msg.isInstanceMessage())
- Summ = getInstanceMethodSummary(Msg, State);
+ Summ = getInstanceMethodSummary(Msg, ReceiverType);
else
Summ = getClassMethodSummary(Msg);
break;
@@ -739,22 +735,15 @@ RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,
return getPersistentSummary(ResultEff, ReceiverEff, MayEscape);
}
-const RetainSummary *
-RetainSummaryManager::getInstanceMethodSummary(const ObjCMethodCall &Msg,
- ProgramStateRef State) {
+const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(
+ const ObjCMethodCall &Msg, QualType ReceiverType) {
const ObjCInterfaceDecl *ReceiverClass = nullptr;
// We do better tracking of the type of the object than the core ExprEngine.
// See if we have its type in our private state.
- // FIXME: Eventually replace the use of state->get<RefBindings> with
- // a generic API for reasoning about the Objective-C types of symbolic
- // objects.
- SVal ReceiverV = Msg.getReceiverSVal();
- if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
- if (const RefVal *T = getRefBinding(State, Sym))
- if (const ObjCObjectPointerType *PT =
- T->getType()->getAs<ObjCObjectPointerType>())
- ReceiverClass = PT->getInterfaceDecl();
+ if (!ReceiverType.isNull())
+ if (const auto *PT = ReceiverType->getAs<ObjCObjectPointerType>())
+ ReceiverClass = PT->getInterfaceDecl();
// If we don't know what kind of object this is, fall back to its static type.
if (!ReceiverClass)
@@ -884,3 +873,30 @@ void RetainSummaryManager::InitializeMethodSummaries() {
"format", "colorSpace");
addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info");
}
+
+CallEffects CallEffects::getEffect(const ObjCMethodDecl *MD) {
+ ASTContext &Ctx = MD->getASTContext();
+ LangOptions L = Ctx.getLangOpts();
+ RetainSummaryManager M(Ctx, L.ObjCAutoRefCount);
+ const RetainSummary *S = M.getMethodSummary(MD);
+ CallEffects CE(S->getRetEffect());
+ CE.Receiver = S->getReceiverEffect();
+ unsigned N = MD->param_size();
+ for (unsigned i = 0; i < N; ++i) {
+ CE.Args.push_back(S->getArg(i));
+ }
+ return CE;
+}
+
+CallEffects CallEffects::getEffect(const FunctionDecl *FD) {
+ ASTContext &Ctx = FD->getASTContext();
+ LangOptions L = Ctx.getLangOpts();
+ RetainSummaryManager M(Ctx, L.ObjCAutoRefCount);
+ const RetainSummary *S = M.getFunctionSummary(FD);
+ CallEffects CE(S->getRetEffect());
+ unsigned N = FD->param_size();
+ for (unsigned i = 0; i < N; ++i) {
+ CE.Args.push_back(S->getArg(i));
+ }
+ return CE;
+}