neil.hickey created this revision.
neil.hickey added a reviewer: cfe-commits.
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.
http://reviews.llvm.org/D15691
Files:
include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseExpr.cpp
test/SemaOpenCL/cond.cl
test/SemaOpenCL/func_ptr.cl
Index: test/SemaOpenCL/func_ptr.cl
===
--- test/SemaOpenCL/func_ptr.cl
+++ test/SemaOpenCL/func_ptr.cl
@@ -11,6 +11,9 @@
foo((void*)foo); // expected-error{{taking address of function is not
allowed}}
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, }; // 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);
}
Index: test/SemaOpenCL/cond.cl
===
--- test/SemaOpenCL/cond.cl
+++ test/SemaOpenCL/cond.cl
@@ -128,5 +128,5 @@
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}}
}
Index: lib/Parse/ParseExpr.cpp
===
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -1334,8 +1334,23 @@
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);
+ Expr *PostfixExpr = Res.get();
+ if (PostfixExpr) {
+QualType Ty = PostfixExpr->getType();
+if (!Ty.isNull() && Ty->isFunctionType() && getLangOpts().OpenCL) {
+ 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
Index: include/clang/Basic/DiagnosticParseKinds.td
===
--- include/clang/Basic/DiagnosticParseKinds.td
+++ include/clang/Basic/DiagnosticParseKinds.td
@@ -910,6 +910,10 @@
def warn_pragma_unknown_extension : Warning<
"unknown OpenCL extension %0 - ignoring">, InGroup;
+// 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,
DefaultIgnore;
Index: test/SemaOpenCL/func_ptr.cl
===
--- test/SemaOpenCL/func_ptr.cl
+++ test/SemaOpenCL/func_ptr.cl
@@ -11,6 +11,9 @@
foo((void*)foo); // expected-error{{taking address of function is not allowed}}
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, }; // 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);
}
Index: test/SemaOpenCL/cond.cl
===
--- test/SemaOpenCL/cond.cl
+++ test/SemaOpenCL/cond.cl
@@ -128,5 +128,5 @@
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}}
}
Index: lib/Parse/ParseExpr.cpp
===
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -1334,8 +1334,23 @@
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);
+ Expr *PostfixExpr = Res.get();
+ if (PostfixExpr) {
+QualType Ty = PostfixExpr->getType();
+if