forked from OSchip/llvm-project
[OpenCL] Restrict various keywords in OpenCL C++ mode
Restrict the following keywords in the OpenCL C++ language mode, according to Sections 2.2 & 2.9 of the OpenCL C++ 1.0 Specification. - dynamic_cast - typeid - register (already restricted in OpenCL C, update the diagnostic) - thread_local - exceptions (try/catch/throw) - access qualifiers read_only, write_only, read_write Support the `__global`, `__local`, `__constant`, `__private`, and `__generic` keywords in OpenCL C++. Leave the unprefixed address space qualifiers such as global available, i.e., do not mark them as reserved keywords in OpenCL C++. libclcxx provides explicit address space pointer classes such as `global_ptr` and `global<T>` that are implemented using the `__`-prefixed qualifiers. Differential Revision: https://reviews.llvm.org/D46022 llvm-svn: 331874
This commit is contained in:
parent
f384bc7166
commit
2ca6ba1045
|
@ -232,6 +232,10 @@ def note_mt_message : Note<"[rewriter] %0">;
|
|||
def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
|
||||
def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">;
|
||||
|
||||
// OpenCL C++.
|
||||
def err_openclcxx_not_supported : Error<
|
||||
"'%0' is not supported in OpenCL C++">;
|
||||
|
||||
// OpenMP
|
||||
def err_omp_more_one_clause : Error<
|
||||
"directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">;
|
||||
|
|
|
@ -1078,6 +1078,8 @@ def err_opencl_logical_exclusive_or : Error<
|
|||
// OpenCL C++.
|
||||
def err_openclcxx_virtual_function : Error<
|
||||
"virtual functions are not supported in OpenCL C++">;
|
||||
def err_openclcxx_reserved : Error<
|
||||
"'%0' is a reserved keyword in OpenCL C++">;
|
||||
|
||||
// OpenMP support.
|
||||
def warn_pragma_omp_ignored : Warning<
|
||||
|
|
|
@ -8609,7 +8609,8 @@ def note_opencl_typedef_access_qualifier : Note<
|
|||
|
||||
// OpenCL Section 6.8.g
|
||||
def err_opencl_unknown_type_specifier : Error<
|
||||
"OpenCL version %0 does not support the '%1' %select{type qualifier|storage class specifier}2">;
|
||||
"OpenCL %select{C|C++}0 version %1 does not support the '%2' "
|
||||
"%select{type qualifier|storage class specifier}3">;
|
||||
|
||||
// OpenCL v2.0 s6.12.5 Blocks restrictions
|
||||
def err_opencl_block_storage_type : Error<
|
||||
|
|
|
@ -249,8 +249,10 @@ PUNCTUATOR(caretcaret, "^^")
|
|||
// KEYMS - This is a keyword if Microsoft extensions are enabled
|
||||
// KEYNOMS18 - This is a keyword that must never be enabled under
|
||||
// MSVC <= v18.
|
||||
// KEYOPENCL - This is a keyword in OpenCL
|
||||
// KEYNOOPENCL - This is a keyword that is not supported in OpenCL
|
||||
// KEYOPENCLC - This is a keyword in OpenCL C
|
||||
// KEYOPENCLCXX - This is a keyword in OpenCL C++
|
||||
// KEYNOOPENCL - This is a keyword that is not supported in OpenCL C
|
||||
// nor in OpenCL C++.
|
||||
// KEYALTIVEC - This is a keyword in AltiVec
|
||||
// KEYZVECTOR - This is a keyword for the System z vector extensions,
|
||||
// which are heavily based on AltiVec
|
||||
|
@ -525,36 +527,36 @@ KEYWORD(__unaligned , KEYMS)
|
|||
KEYWORD(__super , KEYMS)
|
||||
|
||||
// OpenCL address space qualifiers
|
||||
KEYWORD(__global , KEYOPENCL)
|
||||
KEYWORD(__local , KEYOPENCL)
|
||||
KEYWORD(__constant , KEYOPENCL)
|
||||
KEYWORD(__private , KEYOPENCL)
|
||||
KEYWORD(__generic , KEYOPENCL)
|
||||
ALIAS("global", __global , KEYOPENCL)
|
||||
ALIAS("local", __local , KEYOPENCL)
|
||||
ALIAS("constant", __constant , KEYOPENCL)
|
||||
ALIAS("private", __private , KEYOPENCL)
|
||||
ALIAS("generic", __generic , KEYOPENCL)
|
||||
KEYWORD(__global , KEYOPENCLC | KEYOPENCLCXX)
|
||||
KEYWORD(__local , KEYOPENCLC | KEYOPENCLCXX)
|
||||
KEYWORD(__constant , KEYOPENCLC | KEYOPENCLCXX)
|
||||
KEYWORD(__private , KEYOPENCLC | KEYOPENCLCXX)
|
||||
KEYWORD(__generic , KEYOPENCLC | KEYOPENCLCXX)
|
||||
ALIAS("global", __global , KEYOPENCLC)
|
||||
ALIAS("local", __local , KEYOPENCLC)
|
||||
ALIAS("constant", __constant , KEYOPENCLC)
|
||||
ALIAS("private", __private , KEYOPENCLC)
|
||||
ALIAS("generic", __generic , KEYOPENCLC)
|
||||
// OpenCL function qualifiers
|
||||
KEYWORD(__kernel , KEYOPENCL)
|
||||
ALIAS("kernel", __kernel , KEYOPENCL)
|
||||
KEYWORD(__kernel , KEYOPENCLC | KEYOPENCLCXX)
|
||||
ALIAS("kernel", __kernel , KEYOPENCLC | KEYOPENCLCXX)
|
||||
// OpenCL access qualifiers
|
||||
KEYWORD(__read_only , KEYOPENCL)
|
||||
KEYWORD(__write_only , KEYOPENCL)
|
||||
KEYWORD(__read_write , KEYOPENCL)
|
||||
ALIAS("read_only", __read_only , KEYOPENCL)
|
||||
ALIAS("write_only", __write_only , KEYOPENCL)
|
||||
ALIAS("read_write", __read_write , KEYOPENCL)
|
||||
KEYWORD(__read_only , KEYOPENCLC | KEYOPENCLCXX)
|
||||
KEYWORD(__write_only , KEYOPENCLC | KEYOPENCLCXX)
|
||||
KEYWORD(__read_write , KEYOPENCLC | KEYOPENCLCXX)
|
||||
ALIAS("read_only", __read_only , KEYOPENCLC | KEYOPENCLCXX)
|
||||
ALIAS("write_only", __write_only , KEYOPENCLC | KEYOPENCLCXX)
|
||||
ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX)
|
||||
// OpenCL builtins
|
||||
KEYWORD(__builtin_astype , KEYOPENCL)
|
||||
KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC|KEYZVECTOR)
|
||||
#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCL)
|
||||
KEYWORD(__builtin_astype , KEYOPENCLC)
|
||||
KEYWORD(vec_step , KEYOPENCLC | KEYALTIVEC | KEYZVECTOR)
|
||||
#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC)
|
||||
#include "clang/Basic/OpenCLImageTypes.def"
|
||||
|
||||
// OpenMP Type Traits
|
||||
KEYWORD(__builtin_omp_required_simd_align, KEYALL)
|
||||
|
||||
KEYWORD(pipe , KEYOPENCL)
|
||||
KEYWORD(pipe , KEYOPENCLC)
|
||||
|
||||
// Borland Extensions.
|
||||
KEYWORD(__pascal , KEYALL)
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace {
|
|||
KEYALTIVEC = 0x40,
|
||||
KEYNOCXX = 0x80,
|
||||
KEYBORLAND = 0x100,
|
||||
KEYOPENCL = 0x200,
|
||||
KEYOPENCLC = 0x200,
|
||||
KEYC11 = 0x400,
|
||||
KEYARC = 0x800,
|
||||
KEYNOMS18 = 0x01000,
|
||||
|
@ -122,8 +122,9 @@ namespace {
|
|||
KEYCOROUTINES = 0x100000,
|
||||
KEYMODULES = 0x200000,
|
||||
KEYCXX2A = 0x400000,
|
||||
KEYOPENCLCXX = 0x800000,
|
||||
KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX2A,
|
||||
KEYALL = (0x7fffff & ~KEYNOMS18 &
|
||||
KEYALL = (0xffffff & ~KEYNOMS18 &
|
||||
~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to exclude.
|
||||
};
|
||||
|
||||
|
@ -154,7 +155,9 @@ static KeywordStatus getKeywordStatus(const LangOptions &LangOpts,
|
|||
if (LangOpts.WChar && (Flags & WCHARSUPPORT)) return KS_Enabled;
|
||||
if (LangOpts.Char8 && (Flags & CHAR8SUPPORT)) return KS_Enabled;
|
||||
if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) return KS_Enabled;
|
||||
if (LangOpts.OpenCL && (Flags & KEYOPENCL)) return KS_Enabled;
|
||||
if (LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLC))
|
||||
return KS_Enabled;
|
||||
if (LangOpts.OpenCLCPlusPlus && (Flags & KEYOPENCLCXX)) return KS_Enabled;
|
||||
if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) return KS_Enabled;
|
||||
if (LangOpts.C11 && (Flags & KEYC11)) return KS_Enabled;
|
||||
// We treat bridge casts as objective-C keywords so we can warn on them
|
||||
|
|
|
@ -2596,7 +2596,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
|
|||
// Set the flag to prevent the implementation from emitting device exception
|
||||
// handling code for those requiring so.
|
||||
Opts.OpenMPHostCXXExceptions = Opts.Exceptions && Opts.CXXExceptions;
|
||||
if (Opts.OpenMPIsDevice && T.isNVPTX()) {
|
||||
if ((Opts.OpenMPIsDevice && T.isNVPTX()) || Opts.OpenCLCPlusPlus) {
|
||||
Opts.Exceptions = 0;
|
||||
Opts.CXXExceptions = 0;
|
||||
}
|
||||
|
|
|
@ -3750,11 +3750,25 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
getLangOpts());
|
||||
break;
|
||||
|
||||
// OpenCL qualifiers:
|
||||
// OpenCL access qualifiers:
|
||||
case tok::kw___read_only:
|
||||
case tok::kw___write_only:
|
||||
case tok::kw___read_write:
|
||||
// OpenCL C++ 1.0 s2.2: access qualifiers are reserved keywords.
|
||||
if (Actions.getLangOpts().OpenCLCPlusPlus) {
|
||||
DiagID = diag::err_openclcxx_reserved;
|
||||
PrevSpec = Tok.getIdentifierInfo()->getNameStart();
|
||||
isInvalid = true;
|
||||
}
|
||||
ParseOpenCLQualifiers(DS.getAttributes());
|
||||
break;
|
||||
|
||||
// OpenCL address space qualifiers:
|
||||
case tok::kw___generic:
|
||||
// generic address space is introduced only in OpenCL v2.0
|
||||
// see OpenCL C Spec v2.0 s6.5.5
|
||||
if (Actions.getLangOpts().OpenCLVersion < 200) {
|
||||
if (Actions.getLangOpts().OpenCLVersion < 200 &&
|
||||
!Actions.getLangOpts().OpenCLCPlusPlus) {
|
||||
DiagID = diag::err_opencl_unknown_type_specifier;
|
||||
PrevSpec = Tok.getIdentifierInfo()->getNameStart();
|
||||
isInvalid = true;
|
||||
|
@ -3765,9 +3779,6 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
case tok::kw___global:
|
||||
case tok::kw___local:
|
||||
case tok::kw___constant:
|
||||
case tok::kw___read_only:
|
||||
case tok::kw___write_only:
|
||||
case tok::kw___read_write:
|
||||
ParseOpenCLQualifiers(DS.getAttributes());
|
||||
break;
|
||||
|
||||
|
@ -3805,8 +3816,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
Diag(Tok, DiagID)
|
||||
<< PrevSpec << FixItHint::CreateRemoval(Tok.getLocation());
|
||||
else if (DiagID == diag::err_opencl_unknown_type_specifier) {
|
||||
Diag(Tok, DiagID) << getLangOpts().getOpenCLVersionTuple().getAsString()
|
||||
<< PrevSpec << isStorageClass;
|
||||
Diag(Tok, DiagID) << getLangOpts().OpenCLCPlusPlus
|
||||
<< getLangOpts().getOpenCLVersionTuple().getAsString()
|
||||
<< PrevSpec << isStorageClass;
|
||||
} else
|
||||
Diag(Tok, DiagID) << PrevSpec;
|
||||
}
|
||||
|
|
|
@ -267,6 +267,12 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
|
|||
AngleBrackets));
|
||||
|
||||
case tok::kw_dynamic_cast: {
|
||||
// OpenCL C++ 1.0 s2.9: dynamic_cast is not supported.
|
||||
if (getLangOpts().OpenCLCPlusPlus) {
|
||||
return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported)
|
||||
<< "dynamic_cast");
|
||||
}
|
||||
|
||||
if (!TypeDependent) {
|
||||
Op.CheckDynamicCast();
|
||||
if (Op.SrcExpr.isInvalid())
|
||||
|
|
|
@ -6357,6 +6357,20 @@ NamedDecl *Sema::ActOnVariableDeclarator(
|
|||
D.setInvalidType();
|
||||
}
|
||||
}
|
||||
|
||||
// OpenCL C++ 1.0 s2.9: the thread_local storage qualifier is not
|
||||
// supported. OpenCL C does not support thread_local either, and
|
||||
// also reject all other thread storage class specifiers.
|
||||
DeclSpec::TSCS TSC = D.getDeclSpec().getThreadStorageClassSpec();
|
||||
if (TSC != TSCS_unspecified) {
|
||||
bool IsCXX = getLangOpts().OpenCLCPlusPlus;
|
||||
Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
|
||||
diag::err_opencl_unknown_type_specifier)
|
||||
<< IsCXX << getLangOpts().getOpenCLVersionTuple().getAsString()
|
||||
<< DeclSpec::getSpecifierName(TSC) << 1;
|
||||
D.setInvalidType();
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec();
|
||||
|
|
|
@ -480,6 +480,12 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
|
|||
ExprResult
|
||||
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
|
||||
bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
|
||||
// OpenCL C++ 1.0 s2.9: typeid is not supported.
|
||||
if (getLangOpts().OpenCLCPlusPlus) {
|
||||
return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported)
|
||||
<< "typeid");
|
||||
}
|
||||
|
||||
// Find the std::type_info type.
|
||||
if (!getStdNamespace())
|
||||
return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
|
||||
|
|
|
@ -10,9 +10,9 @@ __generic int * __generic_test(__generic int *arg) {
|
|||
return var;
|
||||
}
|
||||
#ifndef CL20
|
||||
// expected-error@-5 {{OpenCL version 1.0 does not support the '__generic' type qualifier}}
|
||||
// expected-error@-6 {{OpenCL version 1.0 does not support the '__generic' type qualifier}}
|
||||
// expected-error@-6 {{OpenCL version 1.0 does not support the '__generic' type qualifier}}
|
||||
// expected-error@-5 {{OpenCL C version 1.0 does not support the '__generic' type qualifier}}
|
||||
// expected-error@-6 {{OpenCL C version 1.0 does not support the '__generic' type qualifier}}
|
||||
// expected-error@-6 {{OpenCL C version 1.0 does not support the '__generic' type qualifier}}
|
||||
#endif
|
||||
|
||||
generic int * generic_test(generic int *arg) {
|
||||
|
@ -20,7 +20,7 @@ generic int * generic_test(generic int *arg) {
|
|||
return var;
|
||||
}
|
||||
#ifndef CL20
|
||||
// expected-error@-5 {{OpenCL version 1.0 does not support the 'generic' type qualifier}}
|
||||
// expected-error@-6 {{OpenCL version 1.0 does not support the 'generic' type qualifier}}
|
||||
// expected-error@-6 {{OpenCL version 1.0 does not support the 'generic' type qualifier}}
|
||||
// expected-error@-5 {{OpenCL C version 1.0 does not support the 'generic' type qualifier}}
|
||||
// expected-error@-6 {{OpenCL C version 1.0 does not support the 'generic' type qualifier}}
|
||||
// expected-error@-6 {{OpenCL C version 1.0 does not support the 'generic' type qualifier}}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -verify -fsyntax-only
|
||||
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -verify -fsyntax-only -fexceptions -fcxx-exceptions
|
||||
|
||||
// This test checks that various C++ and OpenCL C keywords are not available
|
||||
// in OpenCL C++, according to OpenCL C++ 1.0 Specification Section 2.9.
|
||||
|
||||
// Test that exceptions are disabled despite passing -fcxx-exceptions.
|
||||
kernel void test_exceptions() {
|
||||
int x;
|
||||
try {
|
||||
// expected-error@-1 {{cannot use 'try' with exceptions disabled}}
|
||||
throw 0;
|
||||
// expected-error@-1 {{cannot use 'throw' with exceptions disabled}}
|
||||
} catch (int i) {
|
||||
x = 41;
|
||||
}
|
||||
}
|
||||
|
||||
// Test that only __-prefixed address space qualifiers are accepted.
|
||||
struct test_address_space_qualifiers {
|
||||
global int *g;
|
||||
// expected-error@-1 {{unknown type name 'global'}}
|
||||
// expected-error@-2 {{expected member name or ';' after declaration specifiers}}
|
||||
__global int *uug;
|
||||
int global; // should be fine in OpenCL C++
|
||||
|
||||
local int *l;
|
||||
// expected-error@-1 {{unknown type name 'local'}}
|
||||
// expected-error@-2 {{expected member name or ';' after declaration specifiers}}
|
||||
__local int *uul;
|
||||
int local; // should be fine in OpenCL C++
|
||||
|
||||
private int *p;
|
||||
// expected-error@-1 {{expected ':'}}
|
||||
__private int *uup;
|
||||
int private; // 'private' is a keyword in C++14 and thus in OpenCL C++
|
||||
// expected-error@-1 {{expected member name or ';' after declaration specifiers}}
|
||||
|
||||
constant int *c;
|
||||
// expected-error@-1 {{unknown type name 'constant'}}
|
||||
// expected-error@-2 {{expected member name or ';' after declaration specifiers}}
|
||||
__constant int *uuc;
|
||||
int constant; // should be fine in OpenCL C++
|
||||
|
||||
generic int *ge;
|
||||
// expected-error@-1 {{unknown type name 'generic'}}
|
||||
// expected-error@-2 {{expected member name or ';' after declaration specifiers}}
|
||||
__generic int *uuge;
|
||||
int generic; // should be fine in OpenCL C++
|
||||
};
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
void test_storage_class_specs()
|
||||
{
|
||||
static int a; // expected-error {{OpenCL version 1.0 does not support the 'static' storage class specifier}}
|
||||
register int b; // expected-error {{OpenCL version 1.0 does not support the 'register' storage class specifier}}
|
||||
extern int c; // expected-error {{OpenCL version 1.0 does not support the 'extern' storage class specifier}}
|
||||
auto int d; // expected-error {{OpenCL version 1.0 does not support the 'auto' storage class specifier}}
|
||||
static int a; // expected-error {{OpenCL C version 1.0 does not support the 'static' storage class specifier}}
|
||||
register int b; // expected-error {{OpenCL C version 1.0 does not support the 'register' storage class specifier}}
|
||||
extern int c; // expected-error {{OpenCL C version 1.0 does not support the 'extern' storage class specifier}}
|
||||
auto int d; // expected-error {{OpenCL C version 1.0 does not support the 'auto' storage class specifier}}
|
||||
|
||||
#pragma OPENCL EXTENSION cl_clang_storage_class_specifiers : enable
|
||||
static int e; // expected-error {{static local variable must reside in constant address space}}
|
||||
|
|
|
@ -10,14 +10,14 @@ static constant float g_constant_static_var = 0;
|
|||
static global float g_global_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
|
||||
static local float g_local_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
|
||||
static private float g_private_static_var = 0; // expected-error {{program scope variable must reside in constant address space}}
|
||||
static generic float g_generic_static_var = 0; // expected-error{{OpenCL version 1.2 does not support the 'generic' type qualifier}} // expected-error {{program scope variable must reside in constant address space}}
|
||||
static generic float g_generic_static_var = 0; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{program scope variable must reside in constant address space}}
|
||||
|
||||
extern float g_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern constant float g_constant_extern_var;
|
||||
extern global float g_global_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern local float g_local_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern private float g_private_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern generic float g_generic_extern_var; // expected-error{{OpenCL version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}}
|
||||
extern generic float g_generic_extern_var; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}}
|
||||
|
||||
void kernel foo(int x) {
|
||||
// static is not allowed at local scope before CL2.0
|
||||
|
@ -32,7 +32,7 @@ void kernel foo(int x) {
|
|||
constant int L1 = 42; // expected-error {{variables in the constant address space can only be declared in the outermost scope of a kernel function}}
|
||||
}
|
||||
|
||||
auto int L3 = 7; // expected-error{{OpenCL version 1.2 does not support the 'auto' storage class specifier}}
|
||||
auto int L3 = 7; // expected-error{{OpenCL C version 1.2 does not support the 'auto' storage class specifier}}
|
||||
global int L4; // expected-error{{function scope variable cannot be declared in global address space}}
|
||||
__attribute__((address_space(100))) int L5; // expected-error{{automatic variable qualified with an invalid address space}}
|
||||
|
||||
|
@ -64,12 +64,12 @@ void f() {
|
|||
static global float l_global_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
|
||||
static local float l_local_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
|
||||
static private float l_private_static_var = 0; // expected-error {{variables in function scope cannot be declared static}}
|
||||
static generic float l_generic_static_var = 0; // expected-error{{OpenCL version 1.2 does not support the 'generic' type qualifier}} // expected-error {{variables in function scope cannot be declared static}}
|
||||
static generic float l_generic_static_var = 0; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{variables in function scope cannot be declared static}}
|
||||
|
||||
extern float l_implicit_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern constant float l_constant_extern_var;
|
||||
extern global float l_global_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern local float l_local_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern private float l_private_extern_var; // expected-error {{extern variable must reside in constant address space}}
|
||||
extern generic float l_generic_extern_var; // expected-error{{OpenCL version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}}
|
||||
extern generic float l_generic_extern_var; // expected-error{{OpenCL C version 1.2 does not support the 'generic' type qualifier}} // expected-error {{extern variable must reside in constant address space}}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -pedantic -verify -fsyntax-only
|
||||
|
||||
// This test checks that various C/C++/OpenCL C constructs are not available in
|
||||
// OpenCL C++, according to OpenCL C++ 1.0 Specification Section 2.9.
|
||||
|
||||
// Test that typeid is not available in OpenCL C++.
|
||||
namespace std {
|
||||
// Provide a dummy std::type_info so that we can use typeid.
|
||||
class type_info {
|
||||
int a;
|
||||
};
|
||||
}
|
||||
__constant std::type_info int_ti = typeid(int);
|
||||
// expected-error@-1 {{'typeid' is not supported in OpenCL C++}}
|
||||
|
||||
// Test that dynamic_cast is not available in OpenCL C++.
|
||||
class A {
|
||||
public:
|
||||
int a;
|
||||
};
|
||||
|
||||
class B : public A {
|
||||
int b;
|
||||
};
|
||||
|
||||
B *test_dynamic_cast(B *p) {
|
||||
return dynamic_cast<B *>(p);
|
||||
// expected-error@-1 {{'dynamic_cast' is not supported in OpenCL C++}}
|
||||
}
|
||||
|
||||
// Test storage class qualifiers.
|
||||
__constant _Thread_local int a = 1;
|
||||
// expected-error@-1 {{OpenCL C++ version 1.0 does not support the '_Thread_local' storage class specifier}}
|
||||
__constant __thread int b = 2;
|
||||
// expected-error@-1 {{OpenCL C++ version 1.0 does not support the '__thread' storage class specifier}}
|
||||
kernel void test_storage_classes() {
|
||||
register int x;
|
||||
// expected-error@-1 {{OpenCL C++ version 1.0 does not support the 'register' storage class specifier}}
|
||||
thread_local int y;
|
||||
// expected-error@-1 {{OpenCL C++ version 1.0 does not support the 'thread_local' storage class specifier}}
|
||||
}
|
||||
|
||||
// Test that access qualifiers are reserved keywords.
|
||||
kernel void test_access_qualifiers() {
|
||||
int read_only;
|
||||
// expected-error@-1 {{'read_only' is a reserved keyword in OpenCL C++}}
|
||||
// expected-warning@-2 {{declaration does not declare anything}}
|
||||
int __read_only;
|
||||
// expected-error@-1 {{'__read_only' is a reserved keyword in OpenCL C++}}
|
||||
// expected-warning@-2 {{declaration does not declare anything}}
|
||||
int write_only;
|
||||
// expected-error@-1 {{'write_only' is a reserved keyword in OpenCL C++}}
|
||||
// expected-warning@-2 {{declaration does not declare anything}}
|
||||
int __write_only;
|
||||
// expected-error@-1 {{'__write_only' is a reserved keyword in OpenCL C++}}
|
||||
// expected-warning@-2 {{declaration does not declare anything}}
|
||||
int read_write;
|
||||
// expected-error@-1 {{'read_write' is a reserved keyword in OpenCL C++}}
|
||||
// expected-warning@-2 {{declaration does not declare anything}}
|
||||
int __read_write;
|
||||
// expected-error@-1 {{'__read_write' is a reserved keyword in OpenCL C++}}
|
||||
// expected-warning@-2 {{declaration does not declare anything}}
|
||||
}
|
Loading…
Reference in New Issue