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