[clang] abbdb56 - [OpenCL] Allow taking address of functions as an extension.

Anastasia Stulova via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 24 04:32:25 PST 2021


Author: Anastasia Stulova
Date: 2021-02-24T12:32:02Z
New Revision: abbdb5639c70d167bd66cd62296927330782c3b4

URL: https://github.com/llvm/llvm-project/commit/abbdb5639c70d167bd66cd62296927330782c3b4
DIFF: https://github.com/llvm/llvm-project/commit/abbdb5639c70d167bd66cd62296927330782c3b4.diff

LOG: [OpenCL] Allow taking address of functions as an extension.

When '__cl_clang_function_pointers' extension is enabled
the parser should allow obtaining the function address.

This fixes PR49264!

Differential Revision: https://reviews.llvm.org/D97203

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 6acf76d713fd..3b0dd3f4036f 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1807,7 +1807,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
   // 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()) {

diff  --git a/clang/test/SemaOpenCL/func.cl b/clang/test/SemaOpenCL/func.cl
index 8a9c20289f59..bcac30b67e37 100644
--- a/clang/test/SemaOpenCL/func.cl
+++ b/clang/test/SemaOpenCL/func.cl
@@ -38,6 +38,9 @@ typedef struct s
 
 //Function pointer
 void foo(void*);
+#ifdef FUNCPTREXT
+//expected-note at -2{{passing argument to parameter here}}
+#endif
 
 // Expect no diagnostics for an empty parameter list.
 void bar();
@@ -51,11 +54,30 @@ void bar()
 #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 at -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 at -8{{casting 'void (*)(__private void *__private)' to type '__private void *' changes address space}}
+#endif
 
+  foo(&foo);
+#ifndef FUNCPTREXT
+  // expected-error at -2{{taking address of function is not allowed}}
+#else
+  // expected-error at -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);


        


More information about the cfe-commits mailing list