Under a compiler flag, -freset-local-blocks,
wipe out stack blocks when they go out of scope.
// rdar://9227352


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134045 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index a0a8d66..20b5c9b 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -25,6 +25,22 @@
 using namespace clang;
 using namespace CodeGen;
 
+struct CallMemsetLocalBlockObject : EHScopeStack::Cleanup {
+  llvm::AllocaInst *BlockAddr;
+  CharUnits BlockSize;
+  
+  CallMemsetLocalBlockObject(llvm::AllocaInst *blockAddr, 
+                             CharUnits blocSize) 
+    : BlockAddr(blockAddr), BlockSize(blocSize) {}
+  
+  void Emit(CodeGenFunction &CGF, bool isForEH) {
+    CGF.Builder.CreateMemSet(BlockAddr, 
+                             llvm::ConstantInt::get(CGF.Int8Ty, 0xCD), 
+                             BlockSize.getQuantity(), 
+                             BlockAddr->getAlignment());
+  }
+};
+
 CGBlockInfo::CGBlockInfo(const BlockExpr *blockExpr, const char *N)
   : Name(N), CXXThisIndex(0), CanBeGlobal(false), NeedsCopyDispose(false),
     HasCXXObject(false), UsesStret(false), StructureType(0), Block(blockExpr) {
@@ -649,6 +665,9 @@
   llvm::Value *result =
     Builder.CreateBitCast(blockAddr,
                           ConvertType(blockInfo.getBlockExpr()->getType()));
+  if (getLangOptions().ResetLocalBlocks)
+    EHStack.pushCleanup<CallMemsetLocalBlockObject>(NormalCleanup, blockAddr, 
+                                                    blockInfo.BlockSize);
 
   return result;
 }