Skip to content

Commit 9b77b35

Browse files
committed
[SYCL] Diagnose implicit declaration of kernel function type.
SYCL 1.2.1 specification requires an explicit forward declaration of a kernel type name. The current implementation implicitly forward declares the name if the user fails to do so. Diagnose this in strict sycl modes, as such user code is not portable. Signed-off-by: Premanand M Rao <premanand.m.rao@intel.com>
1 parent f43883b commit 9b77b35

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10696,6 +10696,11 @@ def warn_sycl_attibute_function_raw_ptr
1069610696
"to a function with a raw pointer "
1069710697
"%select{return type|parameter type}1">,
1069810698
InGroup<SyclStrict>, DefaultError;
10699+
def warn_sycl_implicit_decl
10700+
: Warning<"SYCL 1.2.1 specification requires an explicit forward "
10701+
"declaration for a kernel type name; your program may not "
10702+
"be portable">,
10703+
InGroup<SyclStrict>, DefaultIgnore;
1069910704
def err_ivdep_duplicate_arg : Error<
1070010705
"duplicate argument to 'ivdep'. attribute requires one or both of a safelen "
1070110706
"and array">;

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,7 +1534,7 @@ void SYCLIntegrationHeader::emitFwdDecl(raw_ostream &O, const Decl *D,
15341534
? cast<ClassTemplateDecl>(D)->getTemplatedDecl()
15351535
: dyn_cast<TagDecl>(D);
15361536

1537-
if (TD && TD->isCompleteDefinition() && !UnnamedLambdaSupport) {
1537+
if (TD && !UnnamedLambdaSupport) {
15381538
// defined class constituting the kernel name is not globally
15391539
// accessible - contradicts the spec
15401540
const bool KernelNameIsMissing = TD->getName().empty();
@@ -1543,8 +1543,12 @@ void SYCLIntegrationHeader::emitFwdDecl(raw_ostream &O, const Decl *D,
15431543
<< /* kernel name is missing */ 0;
15441544
// Don't emit note if kernel name was completely omitted
15451545
} else {
1546-
Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named)
1547-
<< /* kernel name is not globally-visible */ 1;
1546+
if (TD->isCompleteDefinition())
1547+
Diag.Report(KernelLocation,
1548+
diag::err_sycl_kernel_incorrectly_named)
1549+
<< /* kernel name is not globally-visible */ 1;
1550+
else
1551+
Diag.Report(KernelLocation, diag::warn_sycl_implicit_decl);
15481552
Diag.Report(D->getSourceRange().getBegin(),
15491553
diag::note_previous_decl)
15501554
<< TD->getName();
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// RUN: %clang_cc1 -I %S/Inputs -fsycl -fsycl-is-device -fsycl-int-header=%t.h -fsyntax-only -verify %s -Werror=sycl-strict -DERROR
2+
// RUN: %clang_cc1 -I %S/Inputs -fsycl -fsycl-is-device -fsycl-int-header=%t.h -fsyntax-only -verify %s -Wsycl-strict -DWARN
3+
// RUN: %clang_cc1 -I %S/Inputs -fsycl -fsycl-is-device -fsycl-int-header=%t.h -fsycl-unnamed-lambda -fsyntax-only -verify %s -Werror=sycl-strict
4+
#include <sycl.hpp>
5+
6+
#ifdef __SYCL_UNNAMED_LAMBDA__
7+
// expected-no-diagnostics
8+
#endif
9+
10+
using namespace cl::sycl;
11+
12+
void function() {
13+
}
14+
15+
// user-defined class
16+
struct myWrapper {
17+
};
18+
19+
// user-declared class
20+
class myWrapper2;
21+
22+
int main() {
23+
cl::sycl::queue q;
24+
#ifndef __SYCL_UNNAMED_LAMBDA__
25+
// expected-note@+1 {{InvalidKernelName1 declared here}}
26+
class InvalidKernelName1 {};
27+
q.submit([&](cl::sycl::handler &h) {
28+
// expected-error@+1 {{kernel needs to have a globally-visible name}}
29+
h.single_task<InvalidKernelName1>([]() {});
30+
});
31+
#endif
32+
#if defined(WARN)
33+
// expected-warning@+6 {{SYCL 1.2.1 specification requires an explicit forward declaration for a kernel type name; your program may not be portable}}
34+
// expected-note@+5 {{fake_kernel declared here}}
35+
#elif defined(ERROR)
36+
// expected-error@+3 {{SYCL 1.2.1 specification requires an explicit forward declaration for a kernel type name; your program may not be portable}}
37+
// expected-note@+2 {{fake_kernel declared here}}
38+
#endif
39+
cl::sycl::kernel_single_task<class fake_kernel>([]() { function(); });
40+
#if defined(WARN)
41+
// expected-warning@+6 {{SYCL 1.2.1 specification requires an explicit forward declaration for a kernel type name; your program may not be portable}}
42+
// expected-note@+5 {{fake_kernel2 declared here}}
43+
#elif defined(ERROR)
44+
// expected-error@+3 {{SYCL 1.2.1 specification requires an explicit forward declaration for a kernel type name; your program may not be portable}}
45+
// expected-note@+2 {{fake_kernel2 declared here}}
46+
#endif
47+
cl::sycl::kernel_single_task<class fake_kernel2>([]() {
48+
auto l = [](auto f) { f(); };
49+
});
50+
cl::sycl::kernel_single_task<class myWrapper>([]() { function(); });
51+
cl::sycl::kernel_single_task<class myWrapper2>([]() { function(); });
52+
return 0;
53+
}

0 commit comments

Comments
 (0)