diff options
author | Anastasia Stulova <anastasia.stulova@arm.com> | 2016-01-05 14:39:27 +0000 |
---|---|---|
committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2016-01-05 14:39:27 +0000 |
commit | cf04d04ccf6879aa943e09ca8066105e692ab2df (patch) | |
tree | 9cbbe5d106ea95522f5d11b5ae5d60996979aeac | |
parent | e09fcfb1085dc7c64b6ba4ba078757e1d93b4089 (diff) | |
download | bcm5719-llvm-cf04d04ccf6879aa943e09ca8066105e692ab2df.tar.gz bcm5719-llvm-cf04d04ccf6879aa943e09ca8066105e692ab2df.zip |
[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
-rw-r--r-- | clang/include/clang/Basic/DiagnosticParseKinds.td | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 17 | ||||
-rw-r--r-- | clang/test/SemaOpenCL/cond.cl | 2 | ||||
-rw-r--r-- | clang/test/SemaOpenCL/func_ptr.cl | 3 |
4 files changed, 24 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 446852a86b0..f8dee2f98cc 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -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; diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 490bd5ada62..1fd98c140e0 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -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 diff --git a/clang/test/SemaOpenCL/cond.cl b/clang/test/SemaOpenCL/cond.cl index 8cc4f1e8e91..60f70564d86 100644 --- a/clang/test/SemaOpenCL/cond.cl +++ b/clang/test/SemaOpenCL/cond.cl @@ -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}} } diff --git a/clang/test/SemaOpenCL/func_ptr.cl b/clang/test/SemaOpenCL/func_ptr.cl index f21a3d3265a..abeab73a779 100644 --- a/clang/test/SemaOpenCL/func_ptr.cl +++ b/clang/test/SemaOpenCL/func_ptr.cl @@ -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); } |