diff options
author | Anders Carlsson <andersca@mac.com> | 2011-04-11 14:13:40 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2011-04-11 14:13:40 +0000 |
commit | 0c63350b0bc492615b1d75e44134dcacfb512489 (patch) | |
tree | a545d8f045ee576182ac2aa4040a12f1b9ae99b3 /clang/lib/CodeGen/CGExprCXX.cpp | |
parent | 0159a1ee114f86ef1307f8f598977700fd10d7fe (diff) | |
download | bcm5719-llvm-0c63350b0bc492615b1d75e44134dcacfb512489.tar.gz bcm5719-llvm-0c63350b0bc492615b1d75e44134dcacfb512489.zip |
If there's an invoke destination, we should use invoke instead of call when calling the __cxa_bad_typeid function. Fixes PR7400.
llvm-svn: 129273
Diffstat (limited to 'clang/lib/CodeGen/CGExprCXX.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index ef71e890778..4d5f8827de2 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1338,6 +1338,28 @@ void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) { EmitBlock(DeleteEnd); } +static llvm::Constant *getBadTypeidFn(CodeGenFunction &CGF) { + // void __cxa_bad_typeid(); + + const llvm::Type *VoidTy = llvm::Type::getVoidTy(CGF.getLLVMContext()); + const llvm::FunctionType *FTy = + llvm::FunctionType::get(VoidTy, false); + + return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid"); +} + +static void EmitBadTypeidCall(CodeGenFunction &CGF) { + llvm::Value *F = getBadTypeidFn(CGF); + if (llvm::BasicBlock *InvokeDest = CGF.getInvokeDest()) { + llvm::BasicBlock *Cont = CGF.createBasicBlock("invoke.cont"); + CGF.Builder.CreateInvoke(F, Cont, InvokeDest)->setDoesNotReturn(); + CGF.EmitBlock(Cont); + } else + CGF.Builder.CreateCall(F)->setDoesNotReturn(); + + CGF.Builder.CreateUnreachable(); +} + llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { QualType Ty = E->getType(); const llvm::Type *LTy = ConvertType(Ty)->getPointerTo(); @@ -1372,13 +1394,9 @@ llvm::Value *CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { Builder.CreateCondBr(Builder.CreateICmpNE(This, Zero), NonZeroBlock, ZeroBlock); EmitBlock(ZeroBlock); - /// Call __cxa_bad_typeid - const llvm::Type *ResultType = llvm::Type::getVoidTy(getLLVMContext()); - const llvm::FunctionType *FTy; - FTy = llvm::FunctionType::get(ResultType, false); - llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid"); - Builder.CreateCall(F)->setDoesNotReturn(); - Builder.CreateUnreachable(); + + EmitBadTypeidCall(*this); + EmitBlock(NonZeroBlock); } llvm::Value *V = GetVTablePtr(This, LTy->getPointerTo()); |