diff options
| author | John McCall <rjmccall@apple.com> | 2011-11-10 09:22:44 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2011-11-10 09:22:44 +0000 |
| commit | e63abb5d2bb4bb6eb0b81e44ce4aea9e78826e0b (patch) | |
| tree | ac21130db3fff20d3723f6769d89b88aa371ec9d /clang/lib | |
| parent | 1c7047375a180ff80abb414e2075b1d5a240bb77 (diff) | |
| download | bcm5719-llvm-e63abb5d2bb4bb6eb0b81e44ce4aea9e78826e0b.tar.gz bcm5719-llvm-e63abb5d2bb4bb6eb0b81e44ce4aea9e78826e0b.zip | |
Fix a subtle bug with cleanups: when activating
a previously-inactive cleanup, not only do we need a
flag variable, but we should also force the cleanup to
query the flag variable. However, we only need to do
this when we're activating in a context that's
conditionally executed; otherwise, we may safely
assume that the cleanup is dominated by the activation
point.
llvm-svn: 144271
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CGCleanup.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index b2d0786cb6c..9e079c65d27 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -1003,27 +1003,32 @@ static void SetupCleanupBlockActivation(CodeGenFunction &CGF, ForActivation_t Kind) { EHCleanupScope &Scope = cast<EHCleanupScope>(*CGF.EHStack.find(C)); - // 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); + // We always need the flag if we're activating the cleanup in a + // conditional context, because we have to assume that the current + // location doesn't necessarily dominate the cleanup's code. + bool isActivatedInConditional = + (Kind == ForActivation && CGF.isInConditionalBranch()); + + bool needFlag = false; // Calculate whether the cleanup was used: // - as a normal cleanup - if (Scope.isNormalCleanup() && IsUsedAsNormalCleanup(CGF.EHStack, C)) { + if (Scope.isNormalCleanup() && + (isActivatedInConditional || IsUsedAsNormalCleanup(CGF.EHStack, C))) { Scope.setTestFlagInNormalCleanup(); - NeedFlag = true; + needFlag = true; } // - as an EH cleanup - if (Scope.isEHCleanup() && IsUsedAsEHCleanup(CGF.EHStack, C)) { + if (Scope.isEHCleanup() && + (isActivatedInConditional || IsUsedAsEHCleanup(CGF.EHStack, C))) { Scope.setTestFlagInEHCleanup(); - NeedFlag = true; + needFlag = true; } // If it hasn't yet been used as either, we're done. - if (!NeedFlag) return; + if (!needFlag) return; llvm::AllocaInst *Var = Scope.getActiveFlag(); if (!Var) { |

