Anastasia updated this revision to Diff 320484. Anastasia retitled this revision from "[OpenCL][PR48896] Add default address space in template argument deduction only if missing" to "[OpenCL][PR48896] Fix default address space in template argument deduction". Anastasia edited the summary of this revision. Anastasia added reviewers: rjmccall, olestrohm, mantognini. Anastasia added a subscriber: cfe-commits. Anastasia added a comment.
Added test. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95624/new/ https://reviews.llvm.org/D95624 Files: clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/SemaOpenCLCXX/address-space-templates.cl Index: clang/test/SemaOpenCLCXX/address-space-templates.cl =================================================================== --- clang/test/SemaOpenCLCXX/address-space-templates.cl +++ clang/test/SemaOpenCLCXX/address-space-templates.cl @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -verify -fsyntax-only +//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -verify -ast-dump | FileCheck %s template <typename T> struct S { @@ -28,8 +28,10 @@ typedef typename remove_reference<_Tp>::type* type; }; +// Check address space deduction in template parameter deduction. struct rep { - // CHECK |-CXXConstructorDecl {{.*}} rep 'void (const __generic rep &__private) __generic' + // When there is no address space on a reference use __generic. + // CHECK: |-CXXConstructorDecl {{.*}} rep 'void (const __generic rep &__private) __generic' template<class U, class = typename as_pointer<U>::type> rep(U&& v) {} }; @@ -39,11 +41,22 @@ : rep(0) {} }; + +template<class T, class F> +void foo4(T t, F f){ + f(t); +} + void bar() { S<const __global int> sintgl; // expected-note{{in instantiation of template class 'S<const __global int>' requested here}} foo1<__local int>(1); // expected-error{{no matching function for call to 'foo1'}} foo2<__global int>(0); foo3<__global int>(); // expected-note{{in instantiation of function template specialization 'foo3<__global int>' requested here}} + rep_outer r; + int i; + // Preserve the address space of the type in forwarding reference. + // CHECK: CXXMethodDecl {{.*}} operator() 'void (__private int &__private) const __generic' + foo4(i, [](auto&& x){;}); } Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3886,7 +3886,7 @@ // "lvalue reference to A" is used in place of A for type deduction. if (isForwardingReference(QualType(ParamRefType, 0), FirstInnerIndex) && Arg->isLValue()) { - if (S.getLangOpts().OpenCL) + if (S.getLangOpts().OpenCL && !ArgType.hasAddressSpace()) ArgType = S.Context.getAddrSpaceQualType(ArgType, LangAS::opencl_generic); ArgType = S.Context.getLValueReferenceType(ArgType); }
Index: clang/test/SemaOpenCLCXX/address-space-templates.cl =================================================================== --- clang/test/SemaOpenCLCXX/address-space-templates.cl +++ clang/test/SemaOpenCLCXX/address-space-templates.cl @@ -1,4 +1,4 @@ -//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -verify -fsyntax-only +//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -verify -ast-dump | FileCheck %s template <typename T> struct S { @@ -28,8 +28,10 @@ typedef typename remove_reference<_Tp>::type* type; }; +// Check address space deduction in template parameter deduction. struct rep { - // CHECK |-CXXConstructorDecl {{.*}} rep 'void (const __generic rep &__private) __generic' + // When there is no address space on a reference use __generic. + // CHECK: |-CXXConstructorDecl {{.*}} rep 'void (const __generic rep &__private) __generic' template<class U, class = typename as_pointer<U>::type> rep(U&& v) {} }; @@ -39,11 +41,22 @@ : rep(0) {} }; + +template<class T, class F> +void foo4(T t, F f){ + f(t); +} + void bar() { S<const __global int> sintgl; // expected-note{{in instantiation of template class 'S<const __global int>' requested here}} foo1<__local int>(1); // expected-error{{no matching function for call to 'foo1'}} foo2<__global int>(0); foo3<__global int>(); // expected-note{{in instantiation of function template specialization 'foo3<__global int>' requested here}} + rep_outer r; + int i; + // Preserve the address space of the type in forwarding reference. + // CHECK: CXXMethodDecl {{.*}} operator() 'void (__private int &__private) const __generic' + foo4(i, [](auto&& x){;}); } Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3886,7 +3886,7 @@ // "lvalue reference to A" is used in place of A for type deduction. if (isForwardingReference(QualType(ParamRefType, 0), FirstInnerIndex) && Arg->isLValue()) { - if (S.getLangOpts().OpenCL) + if (S.getLangOpts().OpenCL && !ArgType.hasAddressSpace()) ArgType = S.Context.getAddrSpaceQualType(ArgType, LangAS::opencl_generic); ArgType = S.Context.getLValueReferenceType(ArgType); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits