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">; 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/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/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@-3{{reference to function type cannot have '__generic' qualifier}} +#endif // FPTREXT +}; + +void (&glob)(); +#ifndef FPTREXT +//expected-error@-2{{references to functions are not allowed}} +//expected-error@-3{{declaration of reference variable 'glob' requires an initializer}} +#endif // FPTREXT +template +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@-2{{references to functions are not allowed}} +//expected-error@-3{{declaration of reference variable 'loc' requires an initializer}} +#endif // FPTREXT + + void (*&ref2fptr)(); +#ifndef FPTREXT +//expected-error@-2{{pointers to functions are not allowed}} +//expected-error@-3{{declaration of reference variable 'ref2fptr' requires an initializer}} +#endif // FPTREXT + + templ(); //expected-note{{in instantiation of function template specialization}} +}