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
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 505ec7d..6f9cbbb 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -569,6 +569,7 @@
/// ScratchArgs - A holding buffer for construct ArgEffects.
ArgEffects ScratchArgs;
+ RetainSummary DefaultSummary;
RetainSummary* StopSummary;
//==-----------------------------------------------------------------==//
@@ -582,6 +583,8 @@
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 @@
: 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 @@
if (strstr(FName, "Get"))
return getCFSummaryGetRule(FD);
- return 0;
+ return getDefaultSummary();
}
RetainSummary*
@@ -1026,7 +1033,7 @@
default:
assert (false && "Not a supported unary function.");
- return 0;
+ return getDefaultSummary();
}
}
@@ -1064,7 +1071,7 @@
RetainSummary*
RetainSummaryManager::getMethodSummaryFromAnnotations(const ObjCMethodDecl *MD){
if (!MD)
- return 0;
+ return getDefaultSummary();
assert(ScratchArgs.isEmpty());
@@ -1122,7 +1129,7 @@
}
if (!hasEffect)
- return 0;
+ return getDefaultSummary();
return getPersistentSummary(RE, ReceiverEff);
}
@@ -1185,7 +1192,7 @@
}
if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing)
- return 0;
+ return getDefaultSummary();
return getPersistentSummary(RetEffect::MakeNoRet(), ReceiverEff,
MayEscape);
@@ -1707,7 +1714,7 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
}
// Consult the summary for the return value.
- RetEffect RE = GetRetEffect(Summ);
+ RetEffect RE = Summ.getRetEffect();
switch (RE.getKind()) {
default:
@@ -2746,13 +2736,11 @@
// 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 @@
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 @@
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 @@
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 @@
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.