summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-09-17 00:50:28 +0000
committerJohn McCall <rjmccall@apple.com>2010-09-17 00:50:28 +0000
commit7f9c92a9a0740c2e198ae3a38770b59150555ea0 (patch)
tree00928edca348bfd85e66495833d671c7cc77d299 /clang/lib/CodeGen/CodeGenFunction.cpp
parent2cc3f17a26417de82ccd8f3e381f30afff78afed (diff)
downloadbcm5719-llvm-7f9c92a9a0740c2e198ae3a38770b59150555ea0.tar.gz
bcm5719-llvm-7f9c92a9a0740c2e198ae3a38770b59150555ea0.zip
When emitting a new-expression inside a conditional expression,
the cleanup might not be dominated by the allocation code. In this case, we have to store aside all the delete arguments in case we need them later. There's room for optimization here in cases where we end up not actually needing the cleanup in different branches (or being able to pop it after the initialization code). Also make sure we only call this operator delete along the path where we actually allocated something. Fixes rdar://problem/8439196. llvm-svn: 114145
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 0dbc6120ed0..aae8ecf6670 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1431,9 +1431,11 @@ static void SetupCleanupBlockActivation(CodeGenFunction &CGF,
EHScopeStack::stable_iterator C,
ForActivation_t Kind) {
EHCleanupScope &Scope = cast<EHCleanupScope>(*CGF.EHStack.find(C));
- assert(!Scope.getActiveFlag() && "scope already has activation flag");
- bool NeedFlag = false;
+ // We always need the flag if we're activating the cleanup, because
+ // we have to assume that the current location doesn't necessarily
+ // dominate all future uses of the cleanup.
+ bool NeedFlag = (Kind == ForActivation);
// Calculate whether the cleanup was used:
@@ -1452,16 +1454,17 @@ static void SetupCleanupBlockActivation(CodeGenFunction &CGF,
// If it hasn't yet been used as either, we're done.
if (!NeedFlag) return;
- llvm::AllocaInst *Var = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty());
- Scope.setActiveFlag(Var);
+ llvm::AllocaInst *Var = Scope.getActiveFlag();
+ if (!Var) {
+ Var = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "cleanup.isactive");
+ Scope.setActiveFlag(Var);
- if (Kind == ForActivation) {
- CGF.InitTempAlloca(Var, CGF.Builder.getFalse());
- CGF.Builder.CreateStore(CGF.Builder.getTrue(), Var);
- } else {
- CGF.InitTempAlloca(Var, CGF.Builder.getTrue());
- CGF.Builder.CreateStore(CGF.Builder.getFalse(), Var);
+ // Initialize to true or false depending on whether it was
+ // active up to this point.
+ CGF.InitTempAlloca(Var, CGF.Builder.getInt1(Kind == ForDeactivation));
}
+
+ CGF.Builder.CreateStore(CGF.Builder.getInt1(Kind == ForActivation), Var);
}
/// Activate a cleanup that was created in an inactivated state.
@@ -1479,7 +1482,7 @@ void CodeGenFunction::ActivateCleanupBlock(EHScopeStack::stable_iterator C) {
void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C) {
assert(C != EHStack.stable_end() && "deactivating bottom of stack?");
EHCleanupScope &Scope = cast<EHCleanupScope>(*EHStack.find(C));
- assert(Scope.isActive() && "double activation");
+ assert(Scope.isActive() && "double deactivation");
// If it's the top of the stack, just pop it.
if (C == EHStack.stable_begin()) {
OpenPOWER on IntegriCloud