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