diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 4 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 17 | ||||
-rw-r--r-- | test/SemaOpenCL/storageclass.cl | 12 |
5 files changed, 58 insertions, 6 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index d27acf7b99..1ed2006894 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -5622,6 +5622,10 @@ def err_filter_expression_integral : Error< // OpenCL warnings and errors. def err_invalid_astype_of_different_size : Error< "invalid reinterpretation: sizes of %0 and %1 must match">; +def err_static_kernel : Error< + "kernel functions cannot be declared static">; +def err_static_function_scope : Error< + "variables in function scope cannot be declared static">; } // end of sema category diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 674299223f..6f55a02550 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1848,13 +1848,24 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, } } + // -cl-std only applies for OpenCL language standards. + // Override the -std option in this case. if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) { - if (strcmp(A->getValue(Args), "CL1.1") != 0) { + LangStandard::Kind OpenCLLangStd + = llvm::StringSwitch<LangStandard::Kind>(A->getValue(Args)) + .Case("CL", LangStandard::lang_opencl) + .Case("CL1.1", LangStandard::lang_opencl11) + .Case("CL1.2", LangStandard::lang_opencl12) + .Default(LangStandard::lang_unspecified); + + if (OpenCLLangStd == LangStandard::lang_unspecified) { Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << A->getValue(Args); + << A->getAsString(Args) << A->getValue(Args); } + else + LangStd = OpenCLLangStd; } - + CompilerInvocation::setLangDefaults(Opts, IK, LangStd); // We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index f6764c2999..966fee3158 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -420,19 +420,27 @@ const char *DeclSpec::getSpecifierName(TQ T) { bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID) { - // OpenCL 1.1 6.8g: "The extern, static, auto and register storage-class - // specifiers are not supported." + // OpenCL v1.1 s6.8g: "The extern, static, auto and register storage-class + // specifiers are not supported. // It seems sensible to prohibit private_extern too // The cl_clang_storage_class_specifiers extension enables support for // these storage-class specifiers. + // OpenCL v1.2 s6.8 changes this to "The auto and register storage-class + // specifiers are not supported." if (S.getLangOpts().OpenCL && !S.getOpenCLOptions().cl_clang_storage_class_specifiers) { switch (SC) { case SCS_extern: case SCS_private_extern: + case SCS_static: + if (S.getLangOpts().OpenCLVersion < 120) { + DiagID = diag::err_not_opencl_storage_class_specifier; + PrevSpec = getSpecifierName(SC); + return true; + } + break; case SCS_auto: case SCS_register: - case SCS_static: DiagID = diag::err_not_opencl_storage_class_specifier; PrevSpec = getSpecifierName(SC); return true; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 63385ccd19..81b22141e1 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -4456,6 +4456,15 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, return false; } + // OpenCL v1.2 s6.8 -- The static qualifier is valid only in program + // scope. + if ((getLangOpts().OpenCLVersion >= 120) + && NewVD->isStaticLocal()) { + Diag(NewVD->getLocation(), diag::err_static_function_scope); + NewVD->setInvalidDecl(); + return false; + } + if (NewVD->hasLocalStorage() && T.isObjCGCWeak() && !NewVD->hasAttr<BlocksAttr>()) { if (getLangOpts().getGC() != LangOptions::NonGC) @@ -5775,6 +5784,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } + // OpenCL v1.2 s6.8 static is invalid for kernel functions. + if ((getLangOpts().OpenCLVersion >= 120) + && NewFD->hasAttr<OpenCLKernelAttr>() + && (SC == SC_Static)) { + Diag(D.getIdentifierLoc(), diag::err_static_kernel); + D.setInvalidType(); + } + MarkUnusedFileScopedDecl(NewFD); if (getLangOpts().CUDA) diff --git a/test/SemaOpenCL/storageclass.cl b/test/SemaOpenCL/storageclass.cl new file mode 100644 index 0000000000..c78e7cd436 --- /dev/null +++ b/test/SemaOpenCL/storageclass.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL1.2 + +static int A; + +// static is not allowed at local scope. +void kernel foo() { + static int X = 5; // expected-error{{variables in function scope cannot be declared static}} + auto int Y = 7; // expected-error{{OpenCL does not support the 'auto' storage class specifier}} +} + +static void kernel bar() { // expected-error{{kernel functions cannot be declared static}} +} |