// 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
}
}
+ // -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
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;
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)
}
}
+ // 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)
--- /dev/null
+// 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}}
+}