diff options
author | Anders Carlsson <andersca@mac.com> | 2010-01-31 01:43:37 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-01-31 01:43:37 +0000 |
commit | a552ea76b0e4ce4ccdbb845667f0a12da6608c52 (patch) | |
tree | eeea5b543ec0564fdbce0cde24441b2e58dc3aae | |
parent | bb7e17b52ffaa4097b4c4d7935746d23539ffe2a (diff) |
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
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 25 | ||||
-rw-r--r-- | test/CodeGenCXX/derived-to-base.cpp | 9 |
2 files changed, 23 insertions, 11 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index 18d33ad2be..eaebf140fc 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -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); diff --git a/test/CodeGenCXX/derived-to-base.cpp b/test/CodeGenCXX/derived-to-base.cpp index 45728b7c01..79aeea70e3 100644 --- a/test/CodeGenCXX/derived-to-base.cpp +++ b/test/CodeGenCXX/derived-to-base.cpp @@ -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); +} |