aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGBlocks.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-06-28 23:51:26 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-06-28 23:51:26 +0000
commit1077e420b89c9541396135157f22a1eff6062edf (patch)
tree5397b8010ea87645c978b3390ff51273fd113d75 /lib/CodeGen/CGBlocks.cpp
parentd6a4d18f52a775ec9012f5eaec9e5190b0499823 (diff)
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
Diffstat (limited to 'lib/CodeGen/CGBlocks.cpp')
-rw-r--r--lib/CodeGen/CGBlocks.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index a0a8d667df..20b5c9bed0 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 *CodeGenFunction::EmitBlockLiteral(const BlockExpr *blockExpr) {
llvm::Value *result =
Builder.CreateBitCast(blockAddr,
ConvertType(blockInfo.getBlockExpr()->getType()));
+ if (getLangOptions().ResetLocalBlocks)
+ EHStack.pushCleanup<CallMemsetLocalBlockObject>(NormalCleanup, blockAddr,
+ blockInfo.BlockSize);
return result;
}