diff options
author | Mike Stump <mrs@apple.com> | 2010-01-01 02:51:52 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2010-01-01 02:51:52 +0000 |
commit | 5ee041873b6c525bf43758880b08437ad2d572cb (patch) | |
tree | 8872be51e1020eac1e330b64577e56358216b504 /clang/lib/CodeGen/CGException.cpp | |
parent | ee1f861d812fb205688e13bb48c724e34abb2baf (diff) | |
download | bcm5719-llvm-5ee041873b6c525bf43758880b08437ad2d572cb.tar.gz bcm5719-llvm-5ee041873b6c525bf43758880b08437ad2d572cb.zip |
Fix catching a reference to a pointer.
llvm-svn: 92385
Diffstat (limited to 'clang/lib/CodeGen/CGException.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 8b37457ccdf..8c1a6d28ff8 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -207,14 +207,21 @@ static void CopyObject(CodeGenFunction &CGF, const Expr *E, // CopyObject - Utility to copy an object. Calls copy constructor as necessary. // N is casted to the right type. static void CopyObject(CodeGenFunction &CGF, QualType ObjectType, - bool WasPointer, llvm::Value *E, llvm::Value *N) { + bool WasPointer, bool WasReference, llvm::Value *E, + llvm::Value *N) { // Store the throw exception in the exception object. if (WasPointer || !CGF.hasAggregateLLVMType(ObjectType)) { llvm::Value *Value = E; if (!WasPointer) Value = CGF.Builder.CreateLoad(Value); const llvm::Type *ValuePtrTy = Value->getType()->getPointerTo(0); - CGF.Builder.CreateStore(Value, CGF.Builder.CreateBitCast(N, ValuePtrTy)); + if (WasReference) { + llvm::Value *Tmp = CGF.CreateTempAlloca(Value->getType(), "catch.param"); + CGF.Builder.CreateStore(Value, Tmp); + Value = Tmp; + } else + N = CGF.Builder.CreateBitCast(N, ValuePtrTy); + CGF.Builder.CreateStore(Value, N); } else { const llvm::Type *Ty = CGF.ConvertType(ObjectType)->getPointerTo(0); const CXXRecordDecl *RD; @@ -563,6 +570,10 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { QualType CatchType = CatchParam->getType().getNonReferenceType(); setInvokeDest(TerminateHandler); bool WasPointer = true; + bool WasReference = false; + CatchType = CGM.getContext().getCanonicalType(CatchType); + if (isa<ReferenceType>(CatchParam->getType())) + WasReference = true; if (!CatchType.getTypePtr()->isPointerType()) { if (!isa<ReferenceType>(CatchParam->getType())) WasPointer = false; @@ -574,7 +585,8 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { // cleanup doesn't start until after the ctor completes, use a decl // init? CopyObject(*this, CatchParam->getType().getNonReferenceType(), - WasPointer, ExcObject, GetAddrOfLocalVar(CatchParam)); + WasPointer, WasReference, ExcObject, + GetAddrOfLocalVar(CatchParam)); setInvokeDest(MatchHandler); } |