From: Daniel Dunbar Date: Sat, 27 Sep 2008 07:36:24 +0000 (+0000) Subject: Simplify generate code for exceptions: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=129271a42975f8b9d42adc707be9883db91c8a5d;p=clang Simplify generate code for exceptions: - There is no need to branch on the rethrow variable to determine if we need to call objc_exception_try_exit. We know whether an exception was thrown, so just branch to a different target if we want to skip the try_exit. This is a slight semantic departure from gcc, but only for throwing nil, which is undefined (and for which gcc emits broken code). - Also fixes a bug in current code which was calling try_exit too many times when an exception was uncaught (but there were some handlers). Fix bug introduced in prev. commit, the type of the @catch parameter was uninitialized. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56754 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 3ea7fb9cf7..f8d5c5c6d4 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1405,6 +1405,7 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, llvm::BasicBlock *FinallyBlock = llvm::BasicBlock::Create("finally"); + llvm::BasicBlock *FinallyNoExit = llvm::BasicBlock::Create("finally.noexit"); llvm::BasicBlock *TryBlock = llvm::BasicBlock::Create("try"); llvm::BasicBlock *ExceptionInTryBlock = @@ -1455,19 +1456,19 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) { llvm::BasicBlock *NextCatchBlock = llvm::BasicBlock::Create("nextcatch"); - QualType T; const DeclStmt *CatchParam = cast_or_null(CatchStmt->getCatchParamStmt()); - const ValueDecl *VD = 0; - + const VarDecl *VD = 0; + const PointerType *PT = 0; + // catch(...) always matches. if (!CatchParam) { AllMatched = true; } else { - VD = cast(CatchParam->getDecl()); + VD = cast(CatchParam->getDecl()); + PT = VD->getType()->getAsPointerType(); // catch(id e) always matches. - const PointerType *PT = VD->getType()->getAsPointerType(); if (PT && CGF.getContext().isObjCIdType(PT->getPointeeType())) AllMatched = true; } @@ -1475,12 +1476,7 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, if (AllMatched) { if (CatchParam) { CGF.EmitStmt(CatchParam); - - const VarDecl *VD = cast(CatchParam->getDecl()); - - llvm::Value *V = CGF.GetAddrOfLocalVar(VD); - - CGF.Builder.CreateStore(Caught, V); + CGF.Builder.CreateStore(Caught, CGF.GetAddrOfLocalVar(VD)); } CGF.EmitStmt(CatchStmt->getCatchBody()); @@ -1488,6 +1484,8 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, break; } + assert(PT && "Unexpected non-pointer type in @catch"); + QualType T = PT->getPointeeType(); const ObjCInterfaceType *ObjCType = T->getAsObjCInterfaceType(); assert(ObjCType && "Catch parameter must have Objective-C type!"); @@ -1508,8 +1506,6 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, if (CatchParam) { CGF.EmitStmt(CatchParam); - const VarDecl *VD = cast(CatchParam->getDecl()); - llvm::Value *Tmp = CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(VD->getType()), "tmp"); @@ -1526,7 +1522,6 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, // 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); } @@ -1535,30 +1530,23 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, CGF.Builder.CreateStore(CGF.Builder.CreateCall(ObjCTypes.ExceptionExtractFn, ExceptionData), RethrowPtr); + CGF.Builder.CreateBr(FinallyNoExit); } else { CGF.Builder.CreateStore(Caught, RethrowPtr); + CGF.Builder.CreateBr(FinallyNoExit); } // Emit the @finally block. CGF.EmitBlock(FinallyBlock); + CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData); - llvm::Value *Rethrow = CGF.Builder.CreateLoad(RethrowPtr); - llvm::Value *ZeroPtr = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); + CGF.EmitBlock(FinallyNoExit); - llvm::Value *RethrowIsZero = CGF.Builder.CreateICmpEQ(Rethrow, ZeroPtr); - - llvm::BasicBlock *TryExitBlock = llvm::BasicBlock::Create("tryexit"); - llvm::BasicBlock *AfterTryExitBlock = - llvm::BasicBlock::Create("aftertryexit"); - - CGF.Builder.CreateCondBr(RethrowIsZero, TryExitBlock, AfterTryExitBlock); - CGF.EmitBlock(TryExitBlock); - CGF.Builder.CreateCall(ObjCTypes.ExceptionTryExitFn, ExceptionData); - CGF.EmitBlock(AfterTryExitBlock); - if (const ObjCAtFinallyStmt* FinallyStmt = S.getFinallyStmt()) CGF.EmitStmt(FinallyStmt->getFinallyBody()); + llvm::Value *Rethrow = CGF.Builder.CreateLoad(RethrowPtr); + llvm::Value *ZeroPtr = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy); llvm::Value *RethrowIsNotZero = CGF.Builder.CreateICmpNE(Rethrow, ZeroPtr); llvm::BasicBlock *RethrowBlock = llvm::BasicBlock::Create("rethrow");