Skip to content

Commit

Permalink
[OpenCL] Allow taking address of functions as an extension.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Anastasia Stulova committed Feb 24, 2021
1 parent 2105912 commit abbdb56
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
3 changes: 2 additions & 1 deletion clang/lib/Parse/ParseExpr.cpp
Expand Up @@ -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()) {
Expand Down
26 changes: 24 additions & 2 deletions clang/test/SemaOpenCL/func.cl
Expand Up @@ -38,6 +38,9 @@ typedef struct s

//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();
Expand All @@ -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@-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);
Expand Down

0 comments on commit abbdb56

Please sign in to comment.