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.