Automatic Reference Counting.

Language-design credit goes to a lot of people, but I particularly want
to single out Blaine Garst and Patrick Beard for their contributions.

Compiler implementation credit goes to Argyrios, Doug, Fariborz, and myself,
in no particular order.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133103 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index 07de870..73ce359 100644
--- a/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -121,6 +121,11 @@
     return;  
   
   if (R->hasStackStorage()) {
+    // Automatic reference counting automatically copies blocks.
+    if (C.getASTContext().getLangOptions().ObjCAutoRefCount &&
+        isa<BlockDataRegion>(R))
+      return;
+
     EmitStackError(C, R, RetE);
     return;
   }
@@ -135,12 +140,13 @@
   // a memory region in the stack space.
   class CallBack : public StoreManager::BindingsHandler {
   private:
+    ExprEngine &Eng;
     const StackFrameContext *CurSFC;
   public:
     llvm::SmallVector<std::pair<const MemRegion*, const MemRegion*>, 10> V;
 
-    CallBack(const LocationContext *LCtx)
-      : CurSFC(LCtx->getCurrentStackFrame()) {}
+    CallBack(ExprEngine &Eng, const LocationContext *LCtx)
+      : Eng(Eng), CurSFC(LCtx->getCurrentStackFrame()) {}
     
     bool HandleBinding(StoreManager &SMgr, Store store,
                        const MemRegion *region, SVal val) {
@@ -151,7 +157,13 @@
       const MemRegion *vR = val.getAsRegion();
       if (!vR)
         return true;
-      
+        
+      // Under automated retain release, it is okay to assign a block
+      // directly to a global variable.
+      if (Eng.getContext().getLangOptions().ObjCAutoRefCount &&
+          isa<BlockDataRegion>(vR))
+        return true;
+
       if (const StackSpaceRegion *SSR = 
           dyn_cast<StackSpaceRegion>(vR->getMemorySpace())) {
         // If the global variable holds a location in the current stack frame,
@@ -164,7 +176,7 @@
     }
   };
     
-  CallBack cb(B.getPredecessor()->getLocationContext());
+  CallBack cb(Eng, B.getPredecessor()->getLocationContext());
   state->getStateManager().getStoreManager().iterBindings(state->getStore(),cb);
 
   if (cb.V.empty())