[PATCH] D95442: [OpenCL] Add diagnostics for references to functions

Anastasia Stulova via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 26 06:30:58 PST 2021


Anastasia created this revision.
Anastasia added a reviewer: mantognini.
Herald added subscribers: ebevhan, yaxunl.
Anastasia requested review of this revision.

References to functions are less permissive than pointers to functions and therefore some use cases could be allowed for example:

- For local variables
- For non-extern static and global variables
- For template parameters that are not used as function parameters or class members
- In constexpr

However, more language work is needed to analyze the invalid/valid cases. This can be done in the future language versions if there is enough interest in the feature from the application developers. Even if we had  a request for allowing some function pointer functionality (PR44788), OpenCL has never adopted the feature as a part of the standard and therefore many applications have been written successfully without it. On the other hand C++ provides other related features - lambdas and function objects that are allowed in OpenCL and can be used to express some sort of the indirect function call logic. For now it seems reasonable to just disallow the references to functions just like we disallow function pointers. This prevents erroneous programs from being compiled silently.

Note that for the advanced users there is the following extension available `__cl_clang_function_pointers` that can be used if there is knowledge about the application sources or compilation options to make sure the non-conformant functionality is safe (more details are in https://clang.llvm.org/docs/LanguageExtensions.html#opencl-features).


https://reviews.llvm.org/D95442

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/SemaOpenCLCXX/references.cl


Index: clang/test/SemaOpenCLCXX/references.cl
===================================================================
--- /dev/null
+++ clang/test/SemaOpenCLCXX/references.cl
@@ -0,0 +1,43 @@
+//RUN: %clang_cc1 %s -cl-std=clc++ -verify -fsyntax-only
+//RUN: %clang_cc1 %s -cl-std=clc++ -verify -fsyntax-only -DFPTREXT
+
+#ifdef FPTREXT
+#pragma OPENCL EXTENSION __cl_clang_function_pointers : enable
+#endif // FPTREXT
+
+// References to functions are not allowed.
+struct myclass {
+  void (&mem)();
+//FIXME: Here we provide incorrect diagnostic.
+#ifndef FPTREXT
+//expected-error at -3{{reference to function type cannot have '__generic' qualifier}}
+#endif // FPTREXT
+};
+
+void (&glob)();
+#ifndef FPTREXT
+//expected-error at -2{{references to functions are not allowed}}
+//expected-error at -3{{declaration of reference variable 'glob' requires an initializer}}
+#endif // FPTREXT
+template <typename T>
+void templ() {
+  // FIXME: We miss to diagnose the reference to function.
+  T loc; //expected-error{{declaration of reference variable 'loc' requires an initializer}}
+}
+
+void foo();
+void test(void (&par)()) {
+  void (&loc)();
+#ifndef FPTREXT
+//expected-error at -2{{references to functions are not allowed}}
+//expected-error at -3{{declaration of reference variable 'loc' requires an initializer}}
+#endif // FPTREXT
+
+  void (*&ref2fptr)();
+#ifndef FPTREXT
+//expected-error at -2{{pointers to functions are not allowed}}
+//expected-error at -3{{declaration of reference variable 'ref2fptr' requires an initializer}}
+#endif // FPTREXT
+
+  templ<void (&)()>(); //expected-note{{in instantiation of function template specialization}}
+}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -2091,7 +2091,7 @@
 
   if (T->isFunctionType() && getLangOpts().OpenCL &&
       !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) {
-    Diag(Loc, diag::err_opencl_function_pointer);
+    Diag(Loc, diag::err_opencl_function_pointer) << /*pointer*/ 0;
     return QualType();
   }
 
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -6752,9 +6752,12 @@
   // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed.
   if (!Se.getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) {
     QualType NR = R;
-    while (NR->isPointerType() || NR->isMemberFunctionPointerType()) {
-      if (NR->isFunctionPointerType() || NR->isMemberFunctionPointerType()) {
-        Se.Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer);
+    while (NR->isPointerType() || NR->isMemberFunctionPointerType() ||
+           NR->isReferenceType()) {
+      if (NR->isFunctionPointerType() || NR->isMemberFunctionPointerType() ||
+          NR->isFunctionReferenceType()) {
+        Se.Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer)
+            << NR->isReferenceType();
         D.setInvalidType();
         return false;
       }
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8541,7 +8541,7 @@
   "of different size">;
 
 def err_opencl_function_pointer : Error<
-  "pointers to functions are not allowed">;
+  "%select{pointers|references}0 to functions are not allowed">;
 
 def err_opencl_taking_address_capture : Error<
   "taking address of a capture is not allowed">;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95442.319277.patch
Type: text/x-patch
Size: 3627 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210126/31678871/attachment.bin>


More information about the cfe-commits mailing list