When necessary, null check the base value in GetAddressCXXOfBaseClass.

llvm-svn: 81611
This commit is contained in:
Anders Carlsson 2009-09-12 06:04:24 +00:00
parent 12f5a25f15
commit 360e7d0a8f
2 changed files with 39 additions and 1 deletions

View File

@ -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;
}

View File

@ -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);
}
}