зеркало из https://github.com/microsoft/clang-1.git
When doing a base-to-derived cast we don't need to null check the derived value if the class offset is 0.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94939 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
bb7e17b52f
Коммит
a552ea76b0
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче