@@ -716,15 +716,20 @@ class ToIRVisitor : public Visitor {
716716
717717 assert (stmt->catches );
718718
719+ typedef llvm::SmallVector<std::pair<ClassDeclaration*, llvm::BasicBlock*>, 6 >
720+ CatchBlocks;
721+ CatchBlocks catchBlocks;
722+ catchBlocks.reserve (stmt->catches ->dim );
723+
719724 for (Catches::reverse_iterator it = stmt->catches ->rbegin (),
720725 end = stmt->catches ->rend ();
721726 it != end; ++it
722727 ) {
723- llvm::BasicBlock* catchBlock = llvm::BasicBlock::Create (irs->context (),
728+ llvm::BasicBlock* catchBB = llvm::BasicBlock::Create (irs->context (),
724729 llvm::Twine (" catch." ) + (*it)->type ->toChars (),
725730 irs->topfunc (), endbb);
726731
727- irs->scope () = IRScope (catchBlock );
732+ irs->scope () = IRScope (catchBB );
728733 irs->DBuilder .EmitBlockStart ((*it)->loc );
729734
730735 llvm::Function* enterCatchFn =
@@ -733,7 +738,7 @@ class ToIRVisitor : public Visitor {
733738
734739 // For catches that use the Throwable object, create storage for it.
735740 // We will set it in the code that branches from the landing pads
736- // (there might be more than one) to catchBlock .
741+ // (there might be more than one) to catchBB .
737742 if ((*it)->var ) {
738743 llvm::Value* ehPtr = irs->func ()->getOrCreateEhPtrSlot ();
739744
@@ -777,12 +782,20 @@ class ToIRVisitor : public Visitor {
777782
778783 irs->DBuilder .EmitBlockEnd ();
779784
780- ClassDeclaration* catchType =
781- (*it)->type ->toBasetype ()->isClassHandle ();
782- DtoResolveClass (catchType);
785+ catchBlocks. push_back ( std::make_pair (
786+ (*it)->type ->toBasetype ()->isClassHandle (), catchBB)) ;
787+ }
783788
789+ // Only after emitting all the catch bodies, register the catch scopes.
790+ // This is so that (re)throwing inside a catch does not match later
791+ // catches.
792+ for (CatchBlocks::iterator it = catchBlocks.begin (),
793+ end = catchBlocks.end ();
794+ it != end; ++it
795+ ) {
796+ DtoResolveClass (it->first );
784797 irs->func ()->scopes ->pushCatch (
785- getIrAggr (catchType )->getClassInfoSymbol (), catchBlock );
798+ getIrAggr (it-> first )->getClassInfoSymbol (), it-> second );
786799 }
787800
788801 // Emit the try block.
@@ -799,10 +812,7 @@ class ToIRVisitor : public Visitor {
799812
800813 // Now that we have done the try block, remove the catches and continue
801814 // codegen in the end block the try and all the catches branch to.
802- for (Catches::reverse_iterator it = stmt->catches ->rbegin (),
803- end = stmt->catches ->rend ();
804- it != end; ++it
805- ) {
815+ for (size_t i = 0 ; i < catchBlocks.size (); ++i) {
806816 irs->func ()->scopes ->popCatch ();
807817 }
808818
0 commit comments