diff options
author | Daniel Dunbar <daniel@zuster.org> | 2008-09-27 07:03:52 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2008-09-27 07:03:52 +0000 |
commit | 55e40721e7c27611174e52378f50435c9ded27db (patch) | |
tree | aa924b0d8ee3aa0e6106f66cf4a033e5ffd05430 | |
parent | 10004916dbda1f6f5d3d0dbea8c1e70b6466ab63 (diff) |
Bug fix, make sure to initialize exception object (to rethrow) even
when there are no @catch blocks.
Also, eliminated unneeded alloca for the rethrow object.
Also, avoid generating code to rethrow exception if the exception will
trivially always be caught.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56751 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 76 |
1 files changed, 38 insertions, 38 deletions
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index d458e463ac..3ea7fb9cf7 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1422,19 +1422,17 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, // Emit the "exception in @try" block. CGF.EmitBlock(ExceptionInTryBlock); - - if (const ObjCAtCatchStmt* CatchStmt = S.getCatchStmts()) { - // Allocate memory for the caught exception and extract it from the - // exception data. - llvm::Value *CaughtPtr = CGF.CreateTempAlloca(ObjCTypes.ObjectPtrTy); - llvm::Value *Extract = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, - ExceptionData); - CGF.Builder.CreateStore(Extract, CaughtPtr); - - // Enter a new exception try block - // (in case a @catch block throws an exception). + + // Retrieve the exception object. We may emit multiple blocks but + // nothing can cross this so the value is already in SSA form. + llvm::Value *Caught = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, + ExceptionData, + "caught"); + if (const ObjCAtCatchStmt* CatchStmt = S.getCatchStmts()) { + // Enter a new exception try block (in case a @catch block throws + // an exception). CGF.Builder.CreateCall(ObjCTypes.ExceptionTryEnterFn, ExceptionData); - + llvm::Value *SetJmpResult = CGF.Builder.CreateCall(ObjCTypes.SetJmpFn, JmpBufPtr, "result"); @@ -1450,29 +1448,31 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, CGF.EmitBlock(CatchBlock); - // Handle catch list + // Handle catch list. As a special case we check if everything is + // matched and avoid generating code for falling off the end if + // so. + bool AllMatched = false; for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { llvm::BasicBlock *NextCatchBlock = llvm::BasicBlock::Create("nextcatch"); - llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught"); QualType T; - bool MatchesAll = false; const DeclStmt *CatchParam = cast_or_null<DeclStmt>(CatchStmt->getCatchParamStmt()); - + const ValueDecl *VD = 0; + // catch(...) always matches. - if (!CatchParam) - MatchesAll = true; - else { - QualType PT = cast<ValueDecl>(CatchParam->getDecl())->getType(); - T = PT->getAsPointerType()->getPointeeType(); + if (!CatchParam) { + AllMatched = true; + } else { + VD = cast<ValueDecl>(CatchParam->getDecl()); // catch(id e) always matches. - if (CGF.getContext().isObjCIdType(T)) - MatchesAll = true; + const PointerType *PT = VD->getType()->getAsPointerType(); + if (PT && CGF.getContext().isObjCIdType(PT->getPointeeType())) + AllMatched = true; } - if (MatchesAll) { + if (AllMatched) { if (CatchParam) { CGF.EmitStmt(CatchParam); @@ -1485,7 +1485,6 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, CGF.EmitStmt(CatchStmt->getCatchBody()); CGF.Builder.CreateBr(FinallyBlock); - CGF.EmitBlock(NextCatchBlock); break; } @@ -1523,20 +1522,21 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, CGF.EmitBlock(NextCatchBlock); } - // None of the handlers caught the exception, so store it and rethrow - // it later. - llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught"); - CGF.Builder.CreateStore(Caught, RethrowPtr); - CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, - ExceptionData); - - CGF.Builder.CreateBr(FinallyBlock); - - CGF.EmitBlock(ExceptionInCatchBlock); + if (!AllMatched) { + // None of the handlers caught the exception, so store it to be + // rethrown at the end of the @finally block. + CGF.Builder.CreateStore(Caught, RethrowPtr); + CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData); + CGF.Builder.CreateBr(FinallyBlock); + } - Extract = CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, - ExceptionData); - CGF.Builder.CreateStore(Extract, RethrowPtr); + // Emit the exception handler for the @catch blocks. + CGF.EmitBlock(ExceptionInCatchBlock); + CGF.Builder.CreateStore(CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, + ExceptionData), + RethrowPtr); + } else { + CGF.Builder.CreateStore(Caught, RethrowPtr); } // Emit the @finally block. |