]> granicus.if.org Git - clang/commitdiff
[PR40778] Preserve addr space in Derived to Base cast.
authorAnastasia Stulova <anastasia.stulova@arm.com>
Thu, 7 Mar 2019 16:23:15 +0000 (16:23 +0000)
committerAnastasia Stulova <anastasia.stulova@arm.com>
Thu, 7 Mar 2019 16:23:15 +0000 (16:23 +0000)
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

lib/CodeGen/CGClass.cpp
lib/Sema/SemaExpr.cpp
test/CodeGenOpenCLCXX/addrspace-derived-base.cl [new file with mode: 0644]

index f45b28098558d0589a6092a2412b96719aa1a065..597d0e9c689def13e77d01a79b3285f5b1d3deae 100644 (file)
@@ -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);
index 187d8e2fdddbbf85fbac6cf55a0b4243ae6aff28..a6724a5288cd428718d15f6d08acf5ef8ec175c0 100644 (file)
@@ -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 (file)
index 0000000..59e29ee
--- /dev/null
@@ -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)*