Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -7659,6 +7659,18 @@ } } } +/// Helper function for adjusting address spaces for the pointer or reference +/// operands of builtin operators +static QualType AdjustAddressSpaceForBuiltinOperandType(Sema &S, QualType T) { + // For OpenCL all builtin operators should use generic addr space on their + // pointer or reference operands. + if (S.LangOpts.OpenCL) { + return S.Context.getAddrSpaceQualType(S.Context.removeAddrSpaceQualType(T), + LangAS::opencl_generic); + } + // FIXME: Generalise to C++. + return T; +} /// Helper function for AddBuiltinOperatorCandidates() that adds /// the volatile- and non-volatile-qualified assignment operators for the @@ -7670,15 +7682,17 @@ QualType ParamTypes[2]; // T& operator=(T&, T) - ParamTypes[0] = S.Context.getLValueReferenceType(T); + ParamTypes[0] = S.Context.getLValueReferenceType( + AdjustAddressSpaceForBuiltinOperandType(S, T)); ParamTypes[1] = T; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); if (!S.Context.getCanonicalType(T).isVolatileQualified()) { // volatile T& operator=(volatile T&, T) - ParamTypes[0] - = S.Context.getLValueReferenceType(S.Context.getVolatileType(T)); + ParamTypes[0] = S.Context.getLValueReferenceType( + AdjustAddressSpaceForBuiltinOperandType(S, + S.Context.getVolatileType(T))); ParamTypes[1] = T; S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); Index: test/CodeGenOpenCLCXX/addrspace-operators.cl =================================================================== --- /dev/null +++ test/CodeGenOpenCLCXX/addrspace-operators.cl @@ -0,0 +1,24 @@ +//RUN: %clang_cc1 %s -triple spir -cl-std=c++ -emit-llvm -O0 -o - | FileCheck %s + +enum E { + a, + b, +}; + +class C { +public: + void foo(E e) { me = e; } + E me; +}; + +void bar() { + C c; + //CHECK: addrspacecast %class.C* %c to %class.C addrspace(4)* + //CHECK: call void @_ZNU3AS41C3fooE1E(%class.C addrspace(4)* %{{[0-9]+}}, i32 0) + c.foo(a); +} + +//CHECK: define linkonce_odr void @_ZNU3AS41C3fooE1E(%class.C addrspace(4)* %this, i32 %e) +//CHECK: [[E:%[0-9]+]] = load i32, i32* %e.addr +//CHECK: %me = getelementptr inbounds %class.C, %class.C addrspace(4)* %this1, i32 0, i32 0 +//CHECK: store i32 [[E]], i32 addrspace(4)* %me