diff options
author | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-03-07 16:23:15 +0000 |
---|---|---|
committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-03-07 16:23:15 +0000 |
commit | 3bef4a5688250d984c10ef3ed64c85d0f62de5ac (patch) | |
tree | 58636b6721fab1c95d7bc8cd898ad17fd6bfc15b | |
parent | 931a426f3341d5cdbb5f8c92f7d56f7647a013f8 (diff) | |
download | clang-3bef4a5688250d984c10ef3ed64c85d0f62de5ac.tar.gz |
[PR40778] Preserve addr space in Derived to Base cast.
The address space for the Base class pointer when up-casting
from Derived should be taken from the Derived class pointer.
Differential Revision: https://reviews.llvm.org/D53818
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@355606 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGClass.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 9 | ||||
-rw-r--r-- | test/CodeGenOpenCLCXX/addrspace-derived-base.cl | 22 |
3 files changed, 31 insertions, 3 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index f45b280985..597d0e9c68 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -302,7 +302,8 @@ Address CodeGenFunction::GetAddressOfBaseClass( // Get the base pointer type. llvm::Type *BasePtrTy = - ConvertType((PathEnd[-1])->getType())->getPointerTo(); + ConvertType((PathEnd[-1])->getType()) + ->getPointerTo(Value.getType()->getPointerAddressSpace()); QualType DerivedTy = getContext().getRecordType(Derived); CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 187d8e2fdd..a6724a5288 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2660,10 +2660,15 @@ Sema::PerformObjectMemberConversion(Expr *From, bool PointerConversions = false; if (isa<FieldDecl>(Member)) { DestRecordType = Context.getCanonicalType(Context.getTypeDeclType(RD)); + auto FromPtrType = FromType->getAs<PointerType>(); + DestRecordType = Context.getAddrSpaceQualType( + DestRecordType, FromPtrType + ? FromType->getPointeeType().getAddressSpace() + : FromType.getAddressSpace()); - if (FromType->getAs<PointerType>()) { + if (FromPtrType) { DestType = Context.getPointerType(DestRecordType); - FromRecordType = FromType->getPointeeType(); + FromRecordType = FromPtrType->getPointeeType(); PointerConversions = true; } else { DestType = DestRecordType; diff --git a/test/CodeGenOpenCLCXX/addrspace-derived-base.cl b/test/CodeGenOpenCLCXX/addrspace-derived-base.cl new file mode 100644 index 0000000000..59e29ee417 --- /dev/null +++ b/test/CodeGenOpenCLCXX/addrspace-derived-base.cl @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 %s -triple spir -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s + +struct B { + int mb; +}; + +class D : public B { +public: + int getmb() { return mb; } +}; + +void foo() { + D d; + //CHECK: addrspacecast %class.D* %d to %class.D addrspace(4)* + //CHECK: call i32 @_ZNU3AS41D5getmbEv(%class.D addrspace(4)* + d.getmb(); +} + +//Derived and Base are in the same address space. + +//CHECK: define linkonce_odr i32 @_ZNU3AS41D5getmbEv(%class.D addrspace(4)* %this) +//CHECK: bitcast %class.D addrspace(4)* %this1 to %struct.B addrspace(4)* |