Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
6 changes: 6 additions & 0 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2340,6 +2340,12 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
<< ArraySize->getSourceRange();
ASM = ArrayType::Normal;
}

// SYCL kernels reject zero length arrays
if (getLangOpts().SYCLIsDevice)
SYCLDiagIfDeviceCode(ArraySize->getBeginLoc(),
diag::err_typecheck_zero_array_size)
<< ArraySize->getSourceRange();
} else if (!T->isDependentType() && !T->isVariablyModifiedType() &&
!T->isIncompleteType() && !T->isUndeducedType()) {
// Is the array too large?
Expand Down
108 changes: 108 additions & 0 deletions clang/test/SemaSYCL/deferred-diagnostics-emit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// RUN: %clang_cc1 -fcxx-exceptions -triple spir64 -fsycl-is-device -Wno-return-type -verify -fsyntax-only -std=c++17 %s

/*
ensuring that the SYCL diagnostics that are typically deferred, correctly emit
*/

struct S {
virtual void foo() {}
};

int calledFromKernel(int a){
// expected-error@+1 {{zero-length arrays are not permitted in C++}}
int MalArray[0];

// expected-error@+1 {{__float128 is not supported on this target}}
__float128 malFloat = 40;

// not sure if 'no virtual function' is a _deferred_ diagnostic, testing anyway
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly do you mean here?
BTW, we diagnose only usages of virtual functions, as SYCL spec requires. Using of classes with virtual functions is not prohibited.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this particular violation ( a virtual function in SYCL context ) results in a deferred diagnostic, as opposed to an immediate diagnostic. @erichkeane added it to one of the files when he was working on reducing the problem. So I kept it in the test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK we diagnose virtual functions usage through SemaSYCL callgraph traversing. See

<< Sema::KernelCallVirtualFunction;
. But, I suppose, we will move this to Sema and deferred diagnostics.

But we already diagnose variadic function calls through deferred diagnostic, I remember patch from Erich doing this #998 .
So If here you are trying to check only deferred diagnostics, I suggest switch from virtual functions to variadic functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I switched to variadic.

S mal;
// expected-error@+1 {{SYCL kernel cannot call a virtual function}}
mal.foo();

return a + 20;
}

inline namespace cl {
namespace sycl {
class queue {
public:
template <typename T> void submit(T CGF) {}
};

template <int I> class id {};

template <int I> class range {};

class handler {
public:
template <typename KernelName, typename KernelType, int Dims>
__attribute__((sycl_kernel)) void kernel_parallel_for(KernelType kernelFunc) {
kernelFunc(id<1>{});
}
template <typename KernelName, typename KernelType, int Dims>
void parallel_for(range<Dims> NWI, KernelType kernelFunc) {
kernel_parallel_for<KernelName, KernelType, Dims>(kernelFunc);
}
};
}
}

/*
template used to specialize a function that contains a lambda that should
result in a deferred diagnostic being emitted.
HOWEVER, this is not working presently.
TODO: re-test after new deferred diagnostic system is merged.
restore the "FIX!!" tests below
*/
template <typename T>
void setup_sycl_operation(const T VA[]) {

cl::sycl::range<1> numOfItems;
cl::sycl::queue deviceQueue;

deviceQueue.submit([&](cl::sycl::handler &cgh) {
cgh.parallel_for<class AName>(numOfItems, [=](cl::sycl::id<1> wiID) {
// FIX!! expected-error@+1 {{zero-length arrays are not permitted in C++}}
int OverlookedBadArray[0];

// FIX!! expected-error@+1 {{__float128 is not supported on this target}}
__float128 overlookedBadFloat = 40;

});
});
}

int main(int argc, char **argv) {

// --- direct lambda testing ---
cl::sycl::range<1> numOfItems;
cl::sycl::queue deviceQueue;

deviceQueue.submit([&](cl::sycl::handler &cgh) {
cgh.parallel_for<class AName>(numOfItems, [=](cl::sycl::id<1> wiID) {
// expected-error@+1 {{zero-length arrays are not permitted in C++}}
int BadArray[0];

// expected-error@+1 {{__float128 is not supported on this target}}
__float128 badFloat = 40; // this SHOULD trigger a diagnostic

// not sure if 'no virtual function' is a _deferred_ diagnostic, but testing anyway.
S s;
// expected-error@+1 {{SYCL kernel cannot call a virtual function}}
s.foo();

calledFromKernel(10);
});
});


// --- lambda in specialized function testing ---

//array A is only used to feed the template
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this array A is needed at all?
The problem with diagnostics appears only if single_task function is called from a template function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. The diagnostics do not emit if the lambda that contains the violations appears in a templated function. So I'm just using the array to specialize the template.

const int array_size = 4;
int A[array_size] = {1, 2, 3, 4};
setup_sycl_operation(A);

return 0;
}
3 changes: 3 additions & 0 deletions clang/test/SemaSYCL/sycl-restrict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ void usage(myFuncDef functionPtr) {

// expected-error@+1 {{__float128 is not supported on this target}}
__float128 A;

// expected-error@+1 {{zero-length arrays are not permitted in C++}}
int BadArray[0];
}

namespace ns {
Expand Down