aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/CFRefCount.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-05-04 04:57:00 +0000
committerTed Kremenek <kremenek@apple.com>2009-05-04 04:57:00 +0000
commit7faca821633c9521030127bf7f42f032c73b24e2 (patch)
treee95a4f85a29931dde0e2a70f68745eed0d0fa7e2 /lib/Analysis/CFRefCount.cpp
parent3189e4be4f79f22e0e076e21615b9526de529b43 (diff)
retain checker: RetainSummaryManager now has a 'DefaultSummary' object
which is returned instead of a null pointer. This helps centralize the logic concerning "default effects". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70826 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/CFRefCount.cpp')
-rw-r--r--lib/Analysis/CFRefCount.cpp69
1 files changed, 30 insertions, 39 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 505ec7d11d..6f9cbbba31 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -569,6 +569,7 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
/// ScratchArgs - A holding buffer for construct ArgEffects.
ArgEffects ScratchArgs;
+ RetainSummary DefaultSummary;
RetainSummary* StopSummary;
//==-----------------------------------------------------------------==//
@@ -582,6 +583,8 @@ class VISIBILITY_HIDDEN RetainSummaryManager {
enum UnaryFuncKind { cfretain, cfrelease, cfmakecollectable };
public:
+ RetainSummary *getDefaultSummary() { return &DefaultSummary; }
+
RetainSummary* getUnarySummary(const FunctionType* FT, UnaryFuncKind func);
RetainSummary* getCFSummaryCreateRule(FunctionDecl* FD);
@@ -698,6 +701,10 @@ public:
: Ctx(ctx),
CFDictionaryCreateII(&ctx.Idents.get("CFDictionaryCreate")),
GCEnabled(gcenabled), AF(BPAlloc), ScratchArgs(AF.GetEmptyMap()),
+ DefaultSummary(AF.GetEmptyMap() /* per-argument effects (none) */,
+ RetEffect::MakeNoRet() /* return effect */,
+ DoNothing /* receiver effect */,
+ MayEscape /* default argument effect */),
StopSummary(0) {
InitializeClassMethodSummaries();
@@ -991,7 +998,7 @@ RetainSummaryManager::getCFCreateGetRuleSummary(FunctionDecl* FD,
if (strstr(FName, "Get"))
return getCFSummaryGetRule(FD);
- return 0;
+ return getDefaultSummary();
}
RetainSummary*
@@ -1026,7 +1033,7 @@ RetainSummaryManager::getUnarySummary(const FunctionType* FT,
default:
assert (false && "Not a supported unary function.");
- return 0;
+ return getDefaultSummary();
}
}
@@ -1064,7 +1071,7 @@ RetainSummaryManager::getInitMethodSummary(QualType RetTy) {
RetainSummary*
RetainSummaryManager::getMethodSummaryFromAnnotations(const ObjCMethodDecl *MD){
if (!MD)
- return 0;
+ return getDefaultSummary();
assert(ScratchArgs.isEmpty());
@@ -1122,7 +1129,7 @@ RetainSummaryManager::getMethodSummaryFromAnnotations(const ObjCMethodDecl *MD){
}
if (!hasEffect)
- return 0;
+ return getDefaultSummary();
return getPersistentSummary(RE, ReceiverEff);
}
@@ -1185,7 +1192,7 @@ RetainSummaryManager::getCommonMethodSummary(const ObjCMethodDecl* MD,
}
if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
- return 0;
+ return getDefaultSummary();
return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff,
MayEscape);
@@ -1707,7 +1714,7 @@ public:
GRStmtNodeBuilder<GRState>& Builder,
Expr* Ex,
Expr* Receiver,
- RetainSummary* Summ,
+ const RetainSummary& Summ,
ExprIterator arg_beg, ExprIterator arg_end,
ExplodedNode<GRState>* Pred);
@@ -2475,23 +2482,6 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug& D, const CFRefCount &tf,
// Main checker logic.
//===----------------------------------------------------------------------===//
-static inline ArgEffect GetArgE(RetainSummary* Summ, unsigned idx) {
- return Summ ? Summ->getArg(idx) : MayEscape;
-}
-
-static inline RetEffect GetRetEffect(RetainSummary* Summ) {
- return Summ ? Summ->getRetEffect() : RetEffect::MakeNoRet();
-}
-
-static inline ArgEffect GetReceiverE(RetainSummary* Summ) {
- return Summ ? Summ->getReceiverEffect() : DoNothing;
-}
-
-static inline bool IsEndPath(RetainSummary* Summ) {
- return Summ ? Summ->isEndPath() : false;
-}
-
-
/// GetReturnType - Used to get the return type of a message expression or
/// function call with the intention of affixing that type to a tracked symbol.
/// While the the return type can be queried directly from RetEx, when
@@ -2530,7 +2520,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
GRStmtNodeBuilder<GRState>& Builder,
Expr* Ex,
Expr* Receiver,
- RetainSummary* Summ,
+ const RetainSummary& Summ,
ExprIterator arg_beg, ExprIterator arg_end,
ExplodedNode<GRState>* Pred) {
@@ -2550,7 +2540,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
if (Sym)
if (RefBindings::data_type* T = state.get<RefBindings>(Sym)) {
- state = Update(state, Sym, *T, GetArgE(Summ, idx), hasErr);
+ state = Update(state, Sym, *T, Summ.getArg(idx), hasErr);
if (hasErr) {
ErrorExpr = *I;
ErrorSym = Sym;
@@ -2561,7 +2551,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
if (isa<Loc>(V)) {
if (loc::MemRegionVal* MR = dyn_cast<loc::MemRegionVal>(&V)) {
- if (GetArgE(Summ, idx) == DoNothingByRef)
+ if (Summ.getArg(idx) == DoNothingByRef)
continue;
// Invalidate the value of the variable passed by reference.
@@ -2648,7 +2638,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
SymbolRef Sym = state.GetSValAsScalarOrLoc(Receiver).getAsLocSymbol();
if (Sym) {
if (const RefVal* T = state.get<RefBindings>(Sym)) {
- state = Update(state, Sym, *T, GetReceiverE(Summ), hasErr);
+ state = Update(state, Sym, *T, Summ.getReceiverEffect(), hasErr);
if (hasErr) {
ErrorExpr = Receiver;
ErrorSym = Sym;
@@ -2665,7 +2655,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
}
// Consult the summary for the return value.
- RetEffect RE = GetRetEffect(Summ);
+ RetEffect RE = Summ.getRetEffect();
switch (RE.getKind()) {
default:
@@ -2746,13 +2736,11 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
// Generate a sink node if we are at the end of a path.
GRExprEngine::NodeTy *NewNode =
- IsEndPath(Summ) ? Builder.MakeSinkNode(Dst, Ex, Pred, state)
- : Builder.MakeNode(Dst, Ex, Pred, state);
+ Summ.isEndPath() ? Builder.MakeSinkNode(Dst, Ex, Pred, state)
+ : Builder.MakeNode(Dst, Ex, Pred, state);
// Annotate the edge with summary we used.
- // FIXME: This assumes that we always use the same summary when generating
- // this node.
- if (NewNode) SummaryLog[NewNode] = Summ;
+ if (NewNode) SummaryLog[NewNode] = &Summ;
}
@@ -2762,10 +2750,11 @@ void CFRefCount::EvalCall(ExplodedNodeSet<GRState>& Dst,
CallExpr* CE, SVal L,
ExplodedNode<GRState>* Pred) {
const FunctionDecl* FD = L.getAsFunctionDecl();
- RetainSummary* Summ = !FD ? 0
+ RetainSummary* Summ = !FD ? Summaries.getDefaultSummary()
: Summaries.getSummary(const_cast<FunctionDecl*>(FD));
- EvalSummary(Dst, Eng, Builder, CE, 0, Summ,
+ assert(Summ);
+ EvalSummary(Dst, Eng, Builder, CE, 0, *Summ,
CE->arg_begin(), CE->arg_end(), Pred);
}
@@ -2774,7 +2763,7 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
GRStmtNodeBuilder<GRState>& Builder,
ObjCMessageExpr* ME,
ExplodedNode<GRState>* Pred) {
- RetainSummary* Summ;
+ RetainSummary* Summ = 0;
if (Expr* Receiver = ME->getReceiver()) {
// We need the type-information of the tracked receiver object
@@ -2829,8 +2818,10 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<GRState>& Dst,
else
Summ = Summaries.getClassMethodSummary(ME);
+ if (!Summ)
+ Summ = Summaries.getDefaultSummary();
- EvalSummary(Dst, Eng, Builder, ME, ME->getReceiver(), Summ,
+ EvalSummary(Dst, Eng, Builder, ME, ME->getReceiver(), *Summ,
ME->arg_begin(), ME->arg_end(), Pred);
}
@@ -2972,8 +2963,8 @@ void CFRefCount::EvalReturn(ExplodedNodeSet<GRState>& Dst,
const Decl *CD = &Eng.getStateManager().getCodeDecl();
if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(CD)) {
- RetainSummary *Summ = Summaries.getMethodSummary(MD);
- if (!GetRetEffect(Summ).isOwned()) {
+ const RetainSummary &Summ = *Summaries.getMethodSummary(MD);
+ if (!Summ.getRetEffect().isOwned()) {
static int ReturnOwnLeakTag = 0;
state = state.set<RefBindings>(Sym, X ^ RefVal::ErrorLeakReturned);
// Generate an error node.