Skip to content

Commit 20e8cde

Browse files
authored
[SYCL] Diagnose implicit declaration of kernel function type (#1450)
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 24f84ab commit 20e8cde

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
@@ -10719,6 +10719,11 @@ def warn_sycl_attibute_function_raw_ptr
1071910719
"to a function with a raw pointer "
1072010720
"%select{return type|parameter type}1">,
1072110721
InGroup<SyclStrict>, DefaultError;
10722+
def warn_sycl_implicit_decl
10723+
: Warning<"SYCL 1.2.1 specification requires an explicit forward "
10724+
"declaration for a kernel type name; your program may not "
10725+
"be portable">,
10726+
InGroup<SyclStrict>, DefaultIgnore;
1072210727
def err_ivdep_duplicate_arg : Error<
1072310728
"duplicate argument to 'ivdep'. attribute requires one or both of a safelen "
1072410729
"and array">;

clang/lib/Sema/SemaSYCL.cpp

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

1506-
if (TD && TD->isCompleteDefinition() && !UnnamedLambdaSupport) {
1506+
if (TD && !UnnamedLambdaSupport) {
15071507
// defined class constituting the kernel name is not globally
15081508
// accessible - contradicts the spec
15091509
const bool KernelNameIsMissing = TD->getName().empty();
@@ -1512,8 +1512,12 @@ void SYCLIntegrationHeader::emitFwdDecl(raw_ostream &O, const Decl *D,
15121512
<< /* kernel name is missing */ 0;
15131513
// Don't emit note if kernel name was completely omitted
15141514
} else {
1515-
Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named)
1516-
<< /* kernel name is not globally-visible */ 1;
1515+
if (TD->isCompleteDefinition())
1516+
Diag.Report(KernelLocation,
1517+
diag::err_sycl_kernel_incorrectly_named)
1518+
<< /* kernel name is not globally-visible */ 1;
1519+
else
1520+
Diag.Report(KernelLocation, diag::warn_sycl_implicit_decl);
15171521
Diag.Report(D->getSourceRange().getBegin(),
15181522
diag::note_previous_decl)
15191523
<< 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)