When doing a base-to-derived cast we don't need to null check the derived value if the class offset is 0.

llvm-svn: 94939
This commit is contained in:
Anders Carlsson 2010-01-31 01:43:37 +00:00
parent 84673e200f
commit 600f737b95
2 changed files with 23 additions and 11 deletions

View File

@ -224,6 +224,14 @@ CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
return Builder.CreateBitCast(Value, DerivedPtrTy);
}
llvm::Value *NonVirtualOffset =
CGM.GetNonVirtualBaseClassOffset(DerivedClass, Class);
if (!NonVirtualOffset) {
// No offset, we can just cast back.
return Builder.CreateBitCast(Value, DerivedPtrTy);
}
llvm::BasicBlock *CastNull = 0;
llvm::BasicBlock *CastNotNull = 0;
llvm::BasicBlock *CastEnd = 0;
@ -240,16 +248,13 @@ CodeGenFunction::GetAddressOfDerivedClass(llvm::Value *Value,
EmitBlock(CastNotNull);
}
if (llvm::Value *NonVirtualOffset =
CGM.GetNonVirtualBaseClassOffset(DerivedClass, Class)) {
// Apply the offset.
Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType());
Value = Builder.CreateSub(Value, NonVirtualOffset);
Value = Builder.CreateIntToPtr(Value, DerivedPtrTy);
} else {
// Just cast.
Value = Builder.CreateBitCast(Value, DerivedPtrTy);
}
// Apply the offset.
Value = Builder.CreatePtrToInt(Value, NonVirtualOffset->getType());
Value = Builder.CreateSub(Value, NonVirtualOffset);
Value = Builder.CreateIntToPtr(Value, DerivedPtrTy);
// Just cast.
Value = Builder.CreateBitCast(Value, DerivedPtrTy);
if (NullCheckValue) {
Builder.CreateBr(CastEnd);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -emit-llvm %s -o -
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
struct A {
void f();
@ -14,3 +14,10 @@ void f() {
b.f();
}
// CHECK: define %struct.B* @_Z1fP1A(%struct.A* %a) nounwind
B *f(A *a) {
// CHECK-NOT: br label
// CHECK: ret %struct.B*
return static_cast<B*>(a);
}