summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven van Haastregt <sven.vanhaastregt@arm.com>2019-11-21 10:39:33 +0000
committerSven van Haastregt <sven.vanhaastregt@arm.com>2019-11-21 10:39:33 +0000
commit35388dcbbc4ce6ce7125f718b3050be33c339464 (patch)
treebd0fcf5e68094ed75c5c37c8973d552beaca8544
parent5cf58768cb3ba31ee37facaf23f7a74f78781590 (diff)
downloadbcm5719-llvm-35388dcbbc4ce6ce7125f718b3050be33c339464.tar.gz
bcm5719-llvm-35388dcbbc4ce6ce7125f718b3050be33c339464.zip
[OpenCL] Fix address space for base method call (PR43145)
Clang was creating an UncheckedDerivedToBase ImplicitCastExpr that was also casting between address spaces. Insert an ImplicitCastExpr node for doing the address space conversion. Differential Revision: https://reviews.llvm.org/D69810
-rw-r--r--clang/lib/Sema/SemaExpr.cpp14
-rw-r--r--clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl23
2 files changed, 35 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ea4321cdd72..3be8af1dd9e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2711,6 +2711,20 @@ Sema::PerformObjectMemberConversion(Expr *From,
FromRecordType = FromType;
DestType = DestRecordType;
}
+
+ LangAS FromAS = FromRecordType.getAddressSpace();
+ LangAS DestAS = DestRecordType.getAddressSpace();
+ if (FromAS != DestAS) {
+ QualType FromRecordTypeWithoutAS =
+ Context.removeAddrSpaceQualType(FromRecordType);
+ QualType FromTypeWithDestAS =
+ Context.getAddrSpaceQualType(FromRecordTypeWithoutAS, DestAS);
+ if (PointerConversions)
+ FromTypeWithDestAS = Context.getPointerType(FromTypeWithDestAS);
+ From = ImpCastExprToType(From, FromTypeWithDestAS,
+ CK_AddressSpaceConversion, From->getValueKind())
+ .get();
+ }
} else {
// No conversion necessary.
return From;
diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl b/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl
index ba76dbb4c6f..d5d369fa80b 100644
--- a/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl
+++ b/clang/test/CodeGenOpenCLCXX/addrspace-derived-base.cl
@@ -28,6 +28,7 @@ void foo() {
class B2 {
public:
void baseMethod() const { }
+ int &getRef() { return bb; }
int bb;
};
@@ -46,7 +47,25 @@ void pr43145(const Derived *argDerived) {
void pr43145_2(B *argB) {
Derived *x = (Derived*)argB;
+ // CHECK-LABEL: @_Z9pr43145_2
+ // CHECK: bitcast %struct.B addrspace(4)* %0 to %class.Derived addrspace(4)*
}
-// CHECK-LABEL: @_Z9pr43145_2
-// CHECK: bitcast %struct.B addrspace(4)* %0 to %class.Derived addrspace(4)*
+// Assigning to reference returned by base class method through derived class.
+
+void pr43145_3(int n) {
+ Derived d;
+ d.getRef() = n;
+
+ // CHECK-LABEL: @_Z9pr43145_3
+ // CHECK: addrspacecast %class.Derived* %d to %class.Derived addrspace(4)*
+ // CHECK: bitcast i8 addrspace(4)* %add.ptr to %class.B2 addrspace(4)*
+ // CHECK: call {{.*}} @_ZNU3AS42B26getRefEv
+
+ private Derived *pd = &d;
+ pd->getRef() = n;
+
+ // CHECK: addrspacecast %class.Derived* %4 to %class.Derived addrspace(4)*
+ // CHECK: bitcast i8 addrspace(4)* %add.ptr1 to %class.B2 addrspace(4)*
+ // CHECK: call {{.*}} @_ZNU3AS42B26getRefEv
+}
OpenPOWER on IntegriCloud