Skip to content

[SYCL] Error out instead of crash when templated global var used #5195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1679,6 +1679,15 @@ class DeferredDiagnosticsEmitter
}

void visitUsedDecl(SourceLocation Loc, Decl *D) {
if (S.LangOpts.SYCLIsDevice && ShouldEmitRootNode) {
if (auto *VD = dyn_cast<VarDecl>(D)) {
if (!S.checkAllowedSYCLInitializer(VD)) {
S.Diag(Loc, diag::err_sycl_restrict)
<< Sema::KernelConstStaticVariable;
return;
}
}
}
if (isa<VarDecl>(D))
return;
if (auto *FD = dyn_cast<FunctionDecl>(D)) {
Expand Down
10 changes: 4 additions & 6 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18725,16 +18725,14 @@ Sema::FunctionEmissionStatus Sema::getEmissionStatus(FunctionDecl *FD,
bool Final) {
assert(FD && "Expected non-null FunctionDecl");

// SYCL functions can be template, so we check if they have appropriate
// attribute prior to checking if it is a template.
if (LangOpts.SYCLIsDevice &&
(FD->hasAttr<SYCLDeviceAttr>() || FD->hasAttr<SYCLKernelAttr>()))
return FunctionEmissionStatus::Emitted;

// Templates are emitted when they're instantiated.
if (FD->isDependentContext())
return FunctionEmissionStatus::TemplateDiscarded;

if (LangOpts.SYCLIsDevice &&
(FD->hasAttr<SYCLDeviceAttr>() || FD->hasAttr<SYCLKernelAttr>()))
return FunctionEmissionStatus::Emitted;

// Check whether this function is an externally visible definition.
auto IsEmittedForExternalSymbol = [this, FD]() {
// We have to check the GVA linkage of the function's *definition* -- if we
Expand Down
6 changes: 0 additions & 6 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,6 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, ArrayRef<SourceLocation> Locs,
SYCLDiagIfDeviceCode(*Locs.begin(),
diag::err_esimd_global_in_sycl_context,
Sema::DeviceDiagnosticReason::Sycl);
// Disallow const statics and globals that are not zero-initialized
// or constant-initialized.
else if (IsRuntimeEvaluated && IsConst && VD->hasGlobalStorage() &&
!VD->isConstexpr() && !checkAllowedSYCLInitializer(VD))
SYCLDiagIfDeviceCode(*Locs.begin(), diag::err_sycl_restrict)
<< Sema::KernelConstStaticVariable;
} else if (auto *FDecl = dyn_cast<FunctionDecl>(D)) {
// SYCL device function cannot be called from an ESIMD context. However,
// funcitons that start with '__spirv_' or '__sycl_' are exceptions to
Expand Down
5 changes: 0 additions & 5 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4111,11 +4111,6 @@ void Sema::finalizeSYCLDelayedAnalysis(const FunctionDecl *Caller,
const FunctionDecl *Callee,
SourceLocation Loc,
DeviceDiagnosticReason Reason) {
// Somehow an unspecialized template appears to be in callgraph or list of
// device functions. We don't want to emit diagnostic here.
if (Callee->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
return;

Callee = Callee->getMostRecentDecl();

// If the reason for the emission of this diagnostic is not SYCL-specific,
Expand Down
4 changes: 0 additions & 4 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5678,10 +5678,6 @@ void Sema::InstantiateVariableInitializer(

if (getLangOpts().CUDA)
checkAllowedCUDAInitializer(Var);

if (getLangOpts().SYCLIsDevice && !checkAllowedSYCLInitializer(Var))
SYCLDiagIfDeviceCode(Var->getLocation(), diag::err_sycl_restrict)
<< Sema::KernelConstStaticVariable;
}

/// Instantiate the definition of the given variable from its
Expand Down
4 changes: 2 additions & 2 deletions clang/test/SemaSYCL/inline-asm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static __inline unsigned int
asm_func_2(unsigned int __leaf, unsigned long __d[]) {
unsigned int __result;
#ifdef SPIR_CHECK
//expected-error@+2 2{{invalid output constraint '=a' in asm}}
// expected-error@+2 {{invalid output constraint '=a' in asm}}
__asm__("enclu"
: "=a"(__result), "=b"(__d[0]), "=c"(__d[1]), "=d"(__d[2])
: "a"(__leaf), "b"(__d[0]), "c"(__d[1]), "d"(__d[2])
Expand Down Expand Up @@ -58,7 +58,7 @@ __attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
#ifdef SPIR_CHECK
unsigned int i = 3;
unsigned long d[4];
//expected-note@+1 2{{called by 'kernel_single_task}}
// expected-note@+1 {{called by 'kernel_single_task}}
asm_func_2(i, d);
#endif // SPIR_CHECK
#else
Expand Down
14 changes: 13 additions & 1 deletion clang/test/SemaSYCL/sycl-device-const-static.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ template struct U<Base>;

const S s5;

template <typename T>
class randomType {
public:
randomType() {}
T val;
};

template <typename T>
const randomType<T> Var;

void usage() {
// expected-error@+1{{SYCL kernel cannot use a non-const static data variable}}
static int s1;
Expand All @@ -34,11 +44,13 @@ void usage() {
(void)s5;
// expected-error@+1{{SYCL kernel cannot use a const static or global variable that is neither zero-initialized nor constant-initialized}}
(void)s6;

// expected-error@+1{{SYCL kernel cannot use a const static or global variable that is neither zero-initialized nor constant-initialized}}
(void)Var<int>;
}

template <typename Name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
// expected-error@+1{{SYCL kernel cannot use a non-const static data variable}}
static int z;
// expected-note-re@+3{{called by 'kernel_single_task<fake_kernel, (lambda at {{.*}})>}}
// expected-note-re@+2{{called by 'kernel_single_task<fake_kernel, (lambda at {{.*}})>}}
Expand Down