From: Anastasia Stulova Date: Wed, 24 Feb 2021 12:27:15 +0000 (+0000) Subject: [OpenCL] Allow taking address of functions as an extension. X-Git-Tag: llvmorg-14-init~14172 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=abbdb5639c70d167bd66cd62296927330782c3b4;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 6acf76d..3b0dd3f 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 8a9c202..bcac30b 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@-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@-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);