diff options
author | Mike Stump <mrs@apple.com> | 2009-11-15 16:52:53 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-11-15 16:52:53 +0000 |
commit | f549e898a44fe91aca46fe34e9ba04a2f08318bf (patch) | |
tree | eac640e6f0b5836c560f32b873aa46a796f39a60 /lib/CodeGen | |
parent | 50724302e24d44a27e3bc45e7185a710d6eb3c2d (diff) |
Finish off zero check for typeid(*p) so that it will do a __cxa_bad_typeid.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88852 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGCXXExpr.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/CodeGen/CGCXXExpr.cpp b/lib/CodeGen/CGCXXExpr.cpp index 565685c6d0..ccbb608553 100644 --- a/lib/CodeGen/CGCXXExpr.cpp +++ b/lib/CodeGen/CGCXXExpr.cpp @@ -357,8 +357,31 @@ llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { // FIXME: if subE is an lvalue do LValue Obj = EmitLValue(subE); llvm::Value *This = Obj.getAddress(); - // FIXME: need to do a 0 check here for *p on This - llvm::Value *V = Builder.CreateBitCast(This, LTy->getPointerTo()->getPointerTo()); + LTy = LTy->getPointerTo()->getPointerTo(); + llvm::Value *V = Builder.CreateBitCast(This, LTy); + // We need to do a zero check for *p, unless it has NonNullAttr. + // FIXME: PointerType->hasAttr<NonNullAttr>() + bool CanBeZero = false; + if (UnaryOperator *UO = dyn_cast<UnaryOperator>(subE)) + if (UO->getOpcode() == UnaryOperator::Deref) + CanBeZero = true; + if (CanBeZero) { + llvm::BasicBlock *NonZeroBlock = createBasicBlock(); + llvm::BasicBlock *ZeroBlock = createBasicBlock(); + + llvm::Value *Zero = llvm::Constant::getNullValue(LTy); + Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), + NonZeroBlock, ZeroBlock); + EmitBlock(ZeroBlock); + /// Call __cxa_bad_typeid + const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext); + const llvm::FunctionType *FTy; + FTy = llvm::FunctionType::get(ResultType, false); + llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid"); + Builder.CreateCall(F); + Builder.CreateUnreachable(); + EmitBlock(NonZeroBlock); + } V = Builder.CreateLoad(V, "vtable"); V = Builder.CreateConstInBoundsGEP1_64(V, -1ULL); V = Builder.CreateLoad(V); |