Anastasia created this revision. Anastasia added a reviewer: rjmccall. Herald added subscribers: ebevhan, yaxunl.
Since lambdas are represented by callable objects, we need to adjust addr space of implicit obj parameter. This patch suggests to use `__generic` for OpenCL mode. Then any lambda variable declared in `__constant` addr space (which is not convertible to `__generic`) would fail to compile with a diagnostic. Towards generic C++ mode it might be better to just use add space from the lambda variable to qualify internal class member functions of lambda? However, I am not clear how to propagate the addr space since we are handling the initializers before the variable declaration. Alternatively it might make sense to just disallow qualifying lambdas with an addr space since they have internal compiler representation defined by the implementation. https://reviews.llvm.org/D69938 Files: clang/lib/Sema/SemaType.cpp clang/test/SemaOpenCLCXX/address-space-lambda.cl Index: clang/test/SemaOpenCLCXX/address-space-lambda.cl =================================================================== --- /dev/null +++ clang/test/SemaOpenCLCXX/address-space-lambda.cl @@ -0,0 +1,14 @@ +//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify | FileCheck %s + +//CHECK: CXXMethodDecl {{.*}} constexpr operator() 'int (int) const __generic' +auto glambda = [](auto a) { return a; }; + +__kernel void foo() { + int i; +//CHECK: CXXMethodDecl {{.*}} constexpr operator() 'void () const __generic' + auto llambda = [&]() {i++;}; + llambda(); + glambda(1); + __constant auto err = [&]() {}; //expected-note-re{{candidate function not viable: address space mismatch in 'this' argument ('__constant (lambda at {{.*}})'), parameter type must be 'const __generic (lambda at {{.*}})'}} + err(); //expected-error-re{{no matching function for call to object of type '__constant (lambda at {{.*}})'}} +} Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -4916,7 +4916,9 @@ .getScopeRep() ->getKind() == NestedNameSpecifier::TypeSpec) || state.getDeclarator().getContext() == - DeclaratorContext::MemberContext; + DeclaratorContext::MemberContext || + state.getDeclarator().getContext() == + DeclaratorContext::LambdaExprContext; }; if (state.getSema().getLangOpts().OpenCLCPlusPlus && IsClassMember()) {
Index: clang/test/SemaOpenCLCXX/address-space-lambda.cl =================================================================== --- /dev/null +++ clang/test/SemaOpenCLCXX/address-space-lambda.cl @@ -0,0 +1,14 @@ +//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify | FileCheck %s + +//CHECK: CXXMethodDecl {{.*}} constexpr operator() 'int (int) const __generic' +auto glambda = [](auto a) { return a; }; + +__kernel void foo() { + int i; +//CHECK: CXXMethodDecl {{.*}} constexpr operator() 'void () const __generic' + auto llambda = [&]() {i++;}; + llambda(); + glambda(1); + __constant auto err = [&]() {}; //expected-note-re{{candidate function not viable: address space mismatch in 'this' argument ('__constant (lambda at {{.*}})'), parameter type must be 'const __generic (lambda at {{.*}})'}} + err(); //expected-error-re{{no matching function for call to object of type '__constant (lambda at {{.*}})'}} +} Index: clang/lib/Sema/SemaType.cpp =================================================================== --- clang/lib/Sema/SemaType.cpp +++ clang/lib/Sema/SemaType.cpp @@ -4916,7 +4916,9 @@ .getScopeRep() ->getKind() == NestedNameSpecifier::TypeSpec) || state.getDeclarator().getContext() == - DeclaratorContext::MemberContext; + DeclaratorContext::MemberContext || + state.getDeclarator().getContext() == + DeclaratorContext::LambdaExprContext; }; if (state.getSema().getLangOpts().OpenCLCPlusPlus && IsClassMember()) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits