[OpenCL] Disallow taking an address of a function.

An undecorated function designator implies taking the address of a function,
which is illegal in OpenCL. Implementing a check for this earlier to allow
the error to be reported even in the presence of other more obvious errors.

Patch by Neil Hickey!

http://reviews.llvm.org/D15691

llvm-svn: 256838
This commit is contained in:
Anastasia Stulova 2016-01-05 14:39:27 +00:00
parent e09fcfb108
commit cf04d04ccf
4 changed files with 24 additions and 2 deletions

View File

@ -910,6 +910,10 @@ def warn_pragma_expected_enable_disable : Warning<
def warn_pragma_unknown_extension : Warning<
"unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>;
// OpenCL error
def err_opencl_taking_function_address_parser : Error<
"taking address of function is not allowed">;
// OpenMP support.
def warn_pragma_omp_ignored : Warning<
"unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore;

View File

@ -1334,8 +1334,23 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
return ExprError();
}
// Check to see whether Res is a function designator only. If it is and we
// are compiling for OpenCL, we need to return an error as this implies
// that the address of the function is being taken, which is illegal in CL.
// These can be followed by postfix-expr pieces.
return ParsePostfixExpressionSuffix(Res);
Res = ParsePostfixExpressionSuffix(Res);
if (getLangOpts().OpenCL)
if (Expr *PostfixExpr = Res.get()) {
QualType Ty = PostfixExpr->getType();
if (!Ty.isNull() && Ty->isFunctionType()) {
Diag(PostfixExpr->getExprLoc(),
diag::err_opencl_taking_function_address_parser);
return ExprError();
}
}
return Res;
}
/// \brief Once the leading part of a postfix-expression is parsed, this

View File

@ -128,5 +128,5 @@ int foo2(int);
unsigned int ntest12(int2 C)
{
return (unsigned int)(C ? foo1 : foo2); // expected-error {{taking address of function is not allowed}}
return (unsigned int)(C ? foo1 : foo2); // expected-error {{taking address of function is not allowed}} expected-error {{taking address of function is not allowed}}
}

View File

@ -11,6 +11,9 @@ void bar()
foo((void*)foo); // expected-error{{taking address of function is not allowed}}
foo(&foo); // expected-error{{taking address of function is not allowed}}
// 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}}
// just calling a function is correct
foo(0);
}