summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-11-10 09:22:44 +0000
committerJohn McCall <rjmccall@apple.com>2011-11-10 09:22:44 +0000
commite63abb5d2bb4bb6eb0b81e44ce4aea9e78826e0b (patch)
treeac21130db3fff20d3723f6769d89b88aa371ec9d /clang/lib
parent1c7047375a180ff80abb414e2075b1d5a240bb77 (diff)
downloadbcm5719-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.cpp23
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) {
OpenPOWER on IntegriCloud