[clang] 5bbf397 - [OpenCL] Add diagnostics for references to functions
Anastasia Stulova via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 2 07:07:56 PST 2021
Author: Anastasia Stulova
Date: 2021-02-02T15:07:40Z
New Revision: 5bbf39704c2b70581d78a463f3c9d20b0eb7dcd5
URL: https://github.com/llvm/llvm-project/commit/5bbf39704c2b70581d78a463f3c9d20b0eb7dcd5
DIFF: https://github.com/llvm/llvm-project/commit/5bbf39704c2b70581d78a463f3c9d20b0eb7dcd5.diff
LOG: [OpenCL] Add diagnostics for references to functions
Restrict use of references to functions as they can
result in non-conforming behavior.
Tags: #clang
Differential Revision: https://reviews.llvm.org/D95442
Added:
clang/test/SemaOpenCLCXX/references.cl
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaType.cpp
clang/test/SemaOpenCLCXX/members.cl
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 67c59f3ca09a..d31cc76b04d1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8547,7 +8547,7 @@ def err_invalid_conversion_between_vector_and_integer : Error<
"of
diff erent 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">;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ef4947baf665..7da00cb598f4 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6756,10 +6756,13 @@ static bool diagnoseOpenCLTypes(Scope *S, Sema &Se, Declarator &D,
// 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;
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 4178024d1264..e24eb266dd5f 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2091,7 +2091,7 @@ QualType Sema::BuildPointerType(QualType T,
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 @@ QualType Sema::BuildReferenceType(QualType T, bool SpelledAsLValue,
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 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
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 =
diff --git a/clang/test/SemaOpenCLCXX/members.cl b/clang/test/SemaOpenCLCXX/members.cl
index d561445eb8a2..855948f0615e 100644
--- a/clang/test/SemaOpenCLCXX/members.cl
+++ b/clang/test/SemaOpenCLCXX/members.cl
@@ -13,31 +13,13 @@ struct C {
};
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 at -2{{pointers to functions are not allowed}}
+//expected-error at -2{{pointers to functions are not allowed}}
#endif
-}
void test() {
void (C::*p)(int);
#ifndef FUNCPTREXT
//expected-error at -2{{pointers to functions are not allowed}}
-#endif
-
- p_t p1;
-#ifndef FUNCPTREXT
-//expected-error at -2{{pointers to functions are not allowed}}
-#endif
-
- templ_test<int (&)()>();
-#ifndef FUNCPTREXT
-//expected-note at -2{{in instantiation of function template specialization}}
#endif
}
diff --git a/clang/test/SemaOpenCLCXX/references.cl b/clang/test/SemaOpenCLCXX/references.cl
new file mode 100644
index 000000000000..c02d73a4bd69
--- /dev/null
+++ b/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 at -2{{references to functions are not allowed}}
+#else
+//expected-error at -4{{declaration of reference variable 'glob' requires an initializer}}
+#endif // FPTREXT
+
+using ref2fct_t = void (&)();
+#ifndef FPTREXT
+//expected-error at -2{{references to functions are not allowed}}
+#endif // FPTREXT
+typedef void (&ref2fct_t)();
+#ifndef FPTREXT
+//expected-error at -2{{references to functions are not allowed}}
+#endif // FPTREXT
+
+void test(void (&par)()) {
+#ifndef FPTREXT
+//expected-error at -2{{references to functions are not allowed}}
+#endif // FPTREXT
+ void (&loc)();
+#ifndef FPTREXT
+//expected-error at -2{{references to functions are not allowed}}
+#else
+//expected-error at -4{{declaration of reference variable 'loc' requires an initializer}}
+#endif // FPTREXT
+
+ void (*&ref2fptr)();
+#ifndef FPTREXT
+//expected-error at -2{{pointers to functions are not allowed}}
+#endif // FPTREXT
+//expected-error at -4{{declaration of reference variable 'ref2fptr' requires an initializer}}
+}
More information about the cfe-commits
mailing list