Anastasia created this revision.
Anastasia added a reviewer: mantognini.
Herald added subscribers: ebevhan, yaxunl.
Anastasia requested review of this revision.

When `__cl_clang_function_pointers` extension is enabled clang should allow 
obtaining the function address.

FYI, taking function addresses is not disallowed by OpenCL C. It is not clear 
why exactly this diagnostic was introduced, potentially it was trying to 
prevent from writing incorrect code, but however, the address of the function 
can be taken without calling the function. Potentially in the future, this 
should be changed to a warning or perhaps even removed.

Note that allowing this feature fully triggered some issues (PR49315) that got 
revealed in OpenCL C but not C++ for OpenCL. However, any further issues will 
be addressed separately.


https://reviews.llvm.org/D97203

Files:
  clang/lib/Parse/ParseExpr.cpp
  clang/test/SemaOpenCL/func.cl


Index: clang/test/SemaOpenCL/func.cl
===================================================================
--- clang/test/SemaOpenCL/func.cl
+++ clang/test/SemaOpenCL/func.cl
@@ -38,6 +38,9 @@
 
 //Function pointer
 void foo(void*);
+#ifdef FUNCPTREXT
+//expected-note@-2{{passing argument to parameter here}}
+#endif
 
 // Expect no diagnostics for an empty parameter list.
 void bar();
@@ -51,11 +54,30 @@
 #endif
 
   // taking the address of a function is an error
-  foo((void*)foo); // expected-error{{taking address of function is not 
allowed}}
-  foo(&foo); // expected-error{{taking address of function is not allowed}}
+  foo((void*)foo);
+#ifndef FUNCPTREXT
+  // expected-error@-2{{taking address of function is not allowed}}
+#else
+  // FIXME: Functions should probably be in the address space defined by the
+  // implementation. It might make sense to put them into the Default address
+  // space that is bind to a physical segment by the target rather than fixing
+  // it to any of the concrete OpenCL address spaces during parsing.
+  // expected-error@-8{{casting 'void (*)(__private void *__private)' to type 
'__private void *' changes address space}}
+#endif
 
+  foo(&foo);
+#ifndef FUNCPTREXT
+  // expected-error@-2{{taking address of function is not allowed}}
+#else
+  // expected-error@-4{{passing 'void (*)(__private void *__private)' to 
parameter of type '__private void *' changes address space of pointer}}
+#endif
+
+  // FIXME: If we stop rejecting the line below a bug (PR49315) gets
+  // hit due to incorrectly handled pointer conversion.
+#ifndef FUNCPTREXT
   // initializing an array with the address of functions is an error
   void* vptrarr[2] = {foo, &foo}; // expected-error{{taking address of 
function is not allowed}} expected-error{{taking address of function is not 
allowed}}
+#endif
 
   // just calling a function is correct
   foo(0);
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -1807,7 +1807,8 @@
   // These can be followed by postfix-expr pieces.
   PreferredType = SavedType;
   Res = ParsePostfixExpressionSuffix(Res);
-  if (getLangOpts().OpenCL)
+  if (getLangOpts().OpenCL && !getActions().getOpenCLOptions().isEnabled(
+                                  "__cl_clang_function_pointers"))
     if (Expr *PostfixExpr = Res.get()) {
       QualType Ty = PostfixExpr->getType();
       if (!Ty.isNull() && Ty->isFunctionType()) {


Index: clang/test/SemaOpenCL/func.cl
===================================================================
--- clang/test/SemaOpenCL/func.cl
+++ clang/test/SemaOpenCL/func.cl
@@ -38,6 +38,9 @@
 
 //Function pointer
 void foo(void*);
+#ifdef FUNCPTREXT
+//expected-note@-2{{passing argument to parameter here}}
+#endif
 
 // Expect no diagnostics for an empty parameter list.
 void bar();
@@ -51,11 +54,30 @@
 #endif
 
   // taking the address of a function is an error
-  foo((void*)foo); // expected-error{{taking address of function is not allowed}}
-  foo(&foo); // expected-error{{taking address of function is not allowed}}
+  foo((void*)foo);
+#ifndef FUNCPTREXT
+  // expected-error@-2{{taking address of function is not allowed}}
+#else
+  // FIXME: Functions should probably be in the address space defined by the
+  // implementation. It might make sense to put them into the Default address
+  // space that is bind to a physical segment by the target rather than fixing
+  // it to any of the concrete OpenCL address spaces during parsing.
+  // expected-error@-8{{casting 'void (*)(__private void *__private)' to type '__private void *' changes address space}}
+#endif
 
+  foo(&foo);
+#ifndef FUNCPTREXT
+  // expected-error@-2{{taking address of function is not allowed}}
+#else
+  // expected-error@-4{{passing 'void (*)(__private void *__private)' to parameter of type '__private void *' changes address space of pointer}}
+#endif
+
+  // FIXME: If we stop rejecting the line below a bug (PR49315) gets
+  // hit due to incorrectly handled pointer conversion.
+#ifndef FUNCPTREXT
   // initializing an array with the address of functions is an error
   void* vptrarr[2] = {foo, &foo}; // expected-error{{taking address of function is not allowed}} expected-error{{taking address of function is not allowed}}
+#endif
 
   // just calling a function is correct
   foo(0);
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -1807,7 +1807,8 @@
   // These can be followed by postfix-expr pieces.
   PreferredType = SavedType;
   Res = ParsePostfixExpressionSuffix(Res);
-  if (getLangOpts().OpenCL)
+  if (getLangOpts().OpenCL && !getActions().getOpenCLOptions().isEnabled(
+                                  "__cl_clang_function_pointers"))
     if (Expr *PostfixExpr = Res.get()) {
       QualType Ty = PostfixExpr->getType();
       if (!Ty.isNull() && Ty->isFunctionType()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to