]> granicus.if.org Git - clang/commitdiff
[OpenCL] Disallow taking an address of a function.
authorAnastasia Stulova <anastasia.stulova@arm.com>
Tue, 5 Jan 2016 14:39:27 +0000 (14:39 +0000)
committerAnastasia Stulova <anastasia.stulova@arm.com>
Tue, 5 Jan 2016 14:39:27 +0000 (14:39 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@256838 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseExpr.cpp
test/SemaOpenCL/cond.cl
test/SemaOpenCL/func_ptr.cl

index 446852a86b0dd971a4f5c62600a10753ba59e2b5..f8dee2f98cca48674086336b0e57b4a95d46f70b 100644 (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;
index 490bd5ada62de92c73e5e5392a69dcb0f31f0652..1fd98c140e0e6415d775137fe6560ff3c1c2d66e 100644 (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
index 8cc4f1e8e9104a3272ea81a6d1ae176f181feb58..60f70564d8616e339dcb201abd00d78183ac2b52 100644 (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}}
 }
index f21a3d3265a56c711b85d74989dd371ab93542ec..abeab73a779ca02cfa8ee3cfcd883de0a478fd47 100644 (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);
 }