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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits