diff options
author | John McCall <rjmccall@apple.com> | 2011-02-16 08:02:54 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-02-16 08:02:54 +0000 |
commit | e996ffd240f20a1048179d7727a6ee3227261921 (patch) | |
tree | 4401959697b60e22969148b60cd09e9b343fec14 /lib/CodeGen/CGException.cpp | |
parent | c515d18023e952357d5dee645e6e3539b7b3d992 (diff) |
Save a copy expression for non-trivial copy constructions of catch variables.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125661 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGException.cpp')
-rw-r--r-- | lib/CodeGen/CGException.cpp | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index f110f797b0..cde27288c3 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -1034,7 +1034,8 @@ static void InitCatchParam(CodeGenFunction &CGF, const llvm::Type *PtrTy = LLVMCatchTy->getPointerTo(0); // addrspace 0 ok - if (RD->hasTrivialCopyConstructor()) { + const Expr *copyExpr = CatchParam.getInit(); + if (!copyExpr) { llvm::Value *AdjustedExn = CallBeginCatch(CGF, Exn, true); llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); CGF.EmitAggregateCopy(ParamAddr, Cast, CatchType); @@ -1043,38 +1044,37 @@ static void InitCatchParam(CodeGenFunction &CGF, // We have to call __cxa_get_exception_ptr to get the adjusted // pointer before copying. - llvm::CallInst *AdjustedExn = + llvm::CallInst *rawAdjustedExn = CGF.Builder.CreateCall(getGetExceptionPtrFn(CGF), Exn); - AdjustedExn->setDoesNotThrow(); - llvm::Value *Cast = CGF.Builder.CreateBitCast(AdjustedExn, PtrTy); + rawAdjustedExn->setDoesNotThrow(); - CXXConstructorDecl *CD = RD->getCopyConstructor(CGF.getContext(), 0); - assert(CD && "record has no copy constructor!"); - llvm::Value *CopyCtor = CGF.CGM.GetAddrOfCXXConstructor(CD, Ctor_Complete); + // Cast that to the appropriate type. + llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy); - CallArgList CallArgs; - CallArgs.push_back(std::make_pair(RValue::get(ParamAddr), - CD->getThisType(CGF.getContext()))); - CallArgs.push_back(std::make_pair(RValue::get(Cast), - CD->getParamDecl(0)->getType())); - - const FunctionProtoType *FPT - = CD->getType()->getAs<FunctionProtoType>(); + // The copy expression is defined in terms of an OpaqueValueExpr. + // Find it and map it to the adjusted expression. + CodeGenFunction::OpaqueValueMapping + opaque(CGF, OpaqueValueExpr::findInCopyConstruct(copyExpr), adjustedExn); // Call the copy ctor in a terminate scope. CGF.EHStack.pushTerminate(); - CGF.EmitCall(CGF.CGM.getTypes().getFunctionInfo(CallArgs, FPT), - CopyCtor, ReturnValueSlot(), CallArgs, CD); + + // Perform the copy construction. + CGF.EmitAggExpr(copyExpr, AggValueSlot::forAddr(ParamAddr, false, false)); + + // Leave the terminate scope. CGF.EHStack.popTerminate(); + // Undo the opaque value mapping. + opaque.pop(); + // Finally we can call __cxa_begin_catch. CallBeginCatch(CGF, Exn, true); } /// Begins a catch statement by initializing the catch variable and /// calling __cxa_begin_catch. -static void BeginCatch(CodeGenFunction &CGF, - const CXXCatchStmt *S) { +static void BeginCatch(CodeGenFunction &CGF, const CXXCatchStmt *S) { // We have to be very careful with the ordering of cleanups here: // C++ [except.throw]p4: // The destruction [of the exception temporary] occurs |