From: Anders Carlsson Date: Thu, 11 Sep 2008 09:15:33 +0000 (+0000) Subject: Make sure to store the exception in the catch parameter. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dde0a94120915fa925d1ffcdb997c7b44dc9fa21;p=clang Make sure to store the exception in the catch parameter. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56102 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 73f948984a..a3da59410d 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -456,12 +456,4 @@ void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S) CGM.getObjCRuntime().EmitThrowStmt(*this, S); } -void CodeGenFunction::EmitObjCAtCatchStmt(const ObjCAtCatchStmt &S) -{ - if (const Stmt *CatchParam = S.getCatchParamStmt()) - EmitStmt(CatchParam); - - EmitStmt(S.getCatchBody()); -} - CGObjCRuntime::~CGObjCRuntime() {} diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index d1875ac40b..2cda9d54b5 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -1442,16 +1442,18 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, // Handle catch list 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(CatchStmt->getCatchParamStmt()); + // catch(...) always matches. - if (CatchStmt->hasEllipsis()) + if (!CatchParam) MatchesAll = true; else { - const DeclStmt *DS = cast(CatchStmt->getCatchParamStmt()); - QualType PT = cast(DS->getDecl())->getType(); + QualType PT = cast(CatchParam->getDecl())->getType(); T = PT->getAsPointerType()->getPointeeType(); // catch(id e) always matches. @@ -1460,10 +1462,18 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, } if (MatchesAll) { - CGF.EmitStmt(CatchStmt); + if (CatchParam) { + CGF.EmitStmt(CatchParam); + + const VarDecl *VD = cast(CatchParam->getDecl()); + + llvm::Value *V = CGF.GetAddrOfLocalVar(VD); + + CGF.Builder.CreateStore(Caught, V); + } + CGF.EmitStmt(CatchStmt->getCatchBody()); CGF.Builder.CreateBr(FinallyBlock); - CGF.EmitBlock(NextCatchBlock); break; } @@ -1474,7 +1484,6 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, // Check if the @catch block matches the exception object. llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl()); - llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught"); llvm::Value *Match = CGF.Builder.CreateCall2(ObjCTypes.ExceptionMatchFn, Class, Caught, "match"); @@ -1486,7 +1495,18 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF, // Emit the @catch block. CGF.EmitBlock(MatchedBlock); - CGF.EmitStmt(CatchStmt); + if (CatchParam) { + CGF.EmitStmt(CatchParam); + + const VarDecl *VD = cast(CatchParam->getDecl()); + + llvm::Value *Tmp = + CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(VD->getType()), + "tmp"); + CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(VD)); + } + + CGF.EmitStmt(CatchStmt->getCatchBody()); CGF.Builder.CreateBr(FinallyBlock); CGF.EmitBlock(NextCatchBlock); diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index 5b88a19cf0..bf3469e538 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -81,8 +81,8 @@ void CodeGenFunction::EmitStmt(const Stmt *S) { EmitObjCAtTryStmt(cast(*S)); break; case Stmt::ObjCAtCatchStmtClass: - EmitObjCAtCatchStmt(cast(*S)); - break; + assert(0 && "@catch statements should be handled by EmitObjCAtTryStmt"); + break; case Stmt::ObjCAtFinallyStmtClass: assert(0 && "@finally statements should be handled by EmitObjCAtTryStmt"); break; diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 8b3dd84bb8..c9ee212d01 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -47,6 +47,11 @@ CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) { return cast(LocalDeclMap[BVD]); } +llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD) +{ + return LocalDeclMap[VD]; +} + const llvm::Type *CodeGenFunction::ConvertType(QualType T) { return CGM.getTypes().ConvertType(T); } diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index e2b0a2b5eb..2884f4cdf9 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -221,6 +221,9 @@ public: /// GetAddrOfStaticLocalVar - Return the address of a static local variable. llvm::Constant *GetAddrOfStaticLocalVar(const VarDecl *BVD); + /// GetAddrOfLocalVar - Return the address of a local variable. + llvm::Value *GetAddrOfLocalVar(const VarDecl *VD); + /// getAccessedFieldNo - Given an encoded value and a result number, return /// the input field number being accessed. static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts); @@ -269,7 +272,6 @@ public: void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S); void EmitObjCAtTryStmt(const ObjCAtTryStmt &S); - void EmitObjCAtCatchStmt(const ObjCAtCatchStmt &S); void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S); //===--------------------------------------------------------------------===//