# HG changeset patch # User Frits van Bommel # Date 1241431710 -7200 # Node ID 7e303f9f16c73293f023e470202ff49223782de4 # Parent 8e8552601ecdec54caf88b1fdf4038835463a789 Don't forget to update the control flow when deleting an invoke. Fixes #284. diff -r 8e8552601ecd -r 7e303f9f16c7 gen/passes/GarbageCollect2Stack.cpp --- a/gen/passes/GarbageCollect2Stack.cpp Sun May 03 18:01:45 2009 +0200 +++ b/gen/passes/GarbageCollect2Stack.cpp Mon May 04 12:08:30 2009 +0200 @@ -96,6 +96,21 @@ KnownFunctions["_d_newarrayvT"] = new FunctionInfo(0, 1, true); } +static void RemoveCall(Instruction* Inst) { + if (InvokeInst* Invoke = dyn_cast(Inst)) { + // If this was an invoke instruction, we need to do some extra + // work to preserve the control flow. + + // First notify the exception landing pad block that we won't be + // going there anymore. + Invoke->getUnwindDest()->removePredecessor(Invoke->getParent()); + // Create a branch to the "normal" destination. + BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent()); + } + // Remove the runtime call. + Inst->eraseFromParent(); +} + /// runOnFunction - Top level algorithm. /// bool GarbageCollect2Stack::runOnFunction(Function &F) { @@ -146,7 +161,7 @@ if (Inst->use_empty() && info->SafeToDelete) { Changed = true; NumDeleted++; - Inst->eraseFromParent(); + RemoveCall(Inst); continue; } @@ -218,17 +233,7 @@ newVal = Builder.CreateBitCast(newVal, Inst->getType()); Inst->replaceAllUsesWith(newVal); - // If this was an invoke instruction, update the control flow. - if (InvokeInst* Invoke = dyn_cast(Inst)) { - // Notify the exception landing pad block that we won't be - // going there anymore. - Invoke->getUnwindDest()->removePredecessor(Invoke->getParent()); - // Create a branch to the "normal" destination. - BranchInst::Create(Invoke->getNormalDest(), Invoke->getParent()); - } - - // Finally, remove the runtime call. - Inst->eraseFromParent(); + RemoveCall(Inst); } }