diff options
| author | Anders Carlsson <andersca@mac.com> | 2009-09-12 06:04:24 +0000 |
|---|---|---|
| committer | Anders Carlsson <andersca@mac.com> | 2009-09-12 06:04:24 +0000 |
| commit | 360e7d0a8f2dc24de4e70abd43f4f35483e19754 (patch) | |
| tree | 68e1cd01da0155367fbb0885f8adc3915fc486e3 /clang/lib/CodeGen | |
| parent | 12f5a25f1524c8b356de4f6bfd5a6e60401e60c3 (diff) | |
| download | llvm-360e7d0a8f2dc24de4e70abd43f4f35483e19754.zip llvm-360e7d0a8f2dc24de4e70abd43f4f35483e19754.tar.gz llvm-360e7d0a8f2dc24de4e70abd43f4f35483e19754.tar.bz2 | |
When necessary, null check the base value in GetAddressCXXOfBaseClass.
llvm-svn: 81611
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGCXXClass.cpp | 30 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 10 |
2 files changed, 39 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGCXXClass.cpp b/clang/lib/CodeGen/CGCXXClass.cpp index 1fb8f83..b2ff232 100644 --- a/clang/lib/CodeGen/CGCXXClass.cpp +++ b/clang/lib/CodeGen/CGCXXClass.cpp @@ -81,6 +81,22 @@ CodeGenFunction::GetAddressCXXOfBaseClass(llvm::Value *BaseValue, uint64_t Offset = ComputeBaseClassOffset(getContext(), ClassDecl, BaseClassDecl); + llvm::BasicBlock *CastNull = 0; + llvm::BasicBlock *CastNotNull = 0; + llvm::BasicBlock *CastEnd = 0; + + if (NullCheckValue) { + CastNull = createBasicBlock("cast.null"); + CastNotNull = createBasicBlock("cast.notnull"); + CastEnd = createBasicBlock("cast.end"); + + llvm::Value *IsNull = + Builder.CreateICmpEQ(BaseValue, + llvm::Constant::getNullValue(BaseValue->getType())); + Builder.CreateCondBr(IsNull, CastNull, CastNotNull); + EmitBlock(CastNotNull); + } + const llvm::Type *LongTy = CGM.getTypes().ConvertType(CGM.getContext().LongTy); const llvm::Type *Int8PtrTy = @@ -99,6 +115,20 @@ CodeGenFunction::GetAddressCXXOfBaseClass(llvm::Value *BaseValue, // Cast back. const llvm::Type *BasePtr = llvm::PointerType::getUnqual(ConvertType(BTy)); BaseValue = Builder.CreateBitCast(BaseValue, BasePtr); + + if (NullCheckValue) { + Builder.CreateBr(CastEnd); + EmitBlock(CastNull); + Builder.CreateBr(CastEnd); + EmitBlock(CastEnd); + + llvm::PHINode *PHI = Builder.CreatePHI(BaseValue->getType()); + PHI->reserveOperandSpace(2); + PHI->addIncoming(BaseValue, CastNotNull); + PHI->addIncoming(llvm::Constant::getNullValue(BaseValue->getType()), + CastNull); + BaseValue = PHI; + } return BaseValue; } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 7adbc9f..aee5446 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -669,8 +669,16 @@ Value *ScalarExprEmitter::EmitCastExpr(const Expr *E, QualType DestTy, CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseClassTy->getDecl()); Value *Src = Visit(const_cast<Expr*>(E)); + + // FIXME: This should be true, but that leads to a failure in virt.cpp + bool NullCheckValue = false; + + // We always assume that 'this' is never null. + if (isa<CXXThisExpr>(E)) + NullCheckValue = false; + return CGF.GetAddressCXXOfBaseClass(Src, DerivedClassDecl, BaseClassDecl, - /*NullCheckValue=*/true); + NullCheckValue); } } |
