Anastasia updated this revision to Diff 319369.
Anastasia added a comment.

Improved diagnostics to cover more cases.

NOTE that this now also contains similar improvements for the pointers to 
member functions.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D95442/new/

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/members.cl
  clang/test/SemaOpenCLCXX/references.cl

Index: clang/test/SemaOpenCLCXX/references.cl
===================================================================
--- /dev/null
+++ clang/test/SemaOpenCLCXX/references.cl
@@ -0,0 +1,46 @@
+//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 {
+//FIXME: Here we provide incorrect diagnostic.
+  void (&mem)(); //expected-error{{reference to function type cannot have '__generic' qualifier}}
+};
+
+void (&glob)();
+#ifndef FPTREXT
+//expected-error@-2{{references to functions are not allowed}}
+#else
+//expected-error@-4{{declaration of reference variable 'glob' requires an initializer}}
+#endif // FPTREXT
+
+using ref2fct_t = void (&)();
+#ifndef FPTREXT
+//expected-error@-2{{references to functions are not allowed}}
+#endif // FPTREXT
+typedef void (&ref2fct_t)();
+#ifndef FPTREXT
+//expected-error@-2{{references to functions are not allowed}}
+#endif // FPTREXT
+
+void test(void (&par)()) {
+#ifndef FPTREXT
+//expected-error@-2{{references to functions are not allowed}}
+#endif // FPTREXT
+  void (&loc)();
+#ifndef FPTREXT
+//expected-error@-2{{references to functions are not allowed}}
+#else
+//expected-error@-4{{declaration of reference variable 'loc' requires an initializer}}
+#endif // FPTREXT
+
+  void (*&ref2fptr)();
+#ifndef FPTREXT
+//expected-error@-2{{pointers to functions are not allowed}}
+#endif // FPTREXT
+//expected-error@-4{{declaration of reference variable 'ref2fptr' requires an initializer}}
+}
Index: clang/test/SemaOpenCLCXX/members.cl
===================================================================
--- clang/test/SemaOpenCLCXX/members.cl
+++ clang/test/SemaOpenCLCXX/members.cl
@@ -13,31 +13,13 @@
 };
 
 typedef void (C::*p_t)(int);
-
-template <class T> struct remove_reference { typedef T type; };
-template <class T> struct remove_reference<T &> { typedef T type; };
-
-template <typename T>
-void templ_test() {
-  typename remove_reference<T>::type *ptr;
 #ifndef FUNCPTREXT
-  //expected-error@-2{{pointers to functions are not allowed}}
+//expected-error@-2{{pointers to functions are not allowed}}
 #endif
-}
 
 void test() {
   void (C::*p)(int);
 #ifndef FUNCPTREXT
 //expected-error@-2{{pointers to functions are not allowed}}
-#endif
-
-  p_t p1;
-#ifndef FUNCPTREXT
-//expected-error@-2{{pointers to functions are not allowed}}
-#endif
-
-  templ_test<int (&)()>();
-#ifndef FUNCPTREXT
-//expected-note@-2{{in instantiation of function template specialization}}
 #endif
 }
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();
   }
 
@@ -2163,6 +2163,12 @@
   if (checkQualifiedFunction(*this, T, Loc, QFK_Reference))
     return QualType();
 
+  if (T->isFunctionType() && getLangOpts().OpenCL &&
+      !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) {
+    Diag(Loc, diag::err_opencl_function_pointer) << /*reference*/ 1;
+    return QualType();
+  }
+
   // In ARC, it is forbidden to build references to unqualified pointers.
   if (getLangOpts().ObjCAutoRefCount)
     T = inferARCLifetimeForPointee(*this, T, Loc, /*reference*/ true);
@@ -2889,6 +2895,12 @@
     return QualType();
   }
 
+  if (T->isFunctionType() && getLangOpts().OpenCL &&
+      !getOpenCLOptions().isEnabled("__cl_clang_function_pointers")) {
+    Diag(Loc, diag::err_opencl_function_pointer) << /*pointer*/ 0;
+    return QualType();
+  }
+
   // Adjust the default free function calling convention to the default method
   // calling convention.
   bool IsCtorOrDtor =
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -6751,10 +6751,13 @@
 
   // 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);
+    QualType NR = R.getCanonicalType();
+    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">;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to