Skip to content

Commit 4f6ae91

Browse files
[SYCL] Move diagnostic from integration header emission (#2644)
This patch moves the diagnostic for the kernel name (kernel name cannot be a type in the "std" namespace) to the point in which the kernel is called, rather than during integration header emission.
1 parent 2ae49f5 commit 4f6ae91

File tree

5 files changed

+96
-84
lines changed

5 files changed

+96
-84
lines changed

clang/lib/Sema/SemaSYCL.cpp

+36-23
Original file line numberDiff line numberDiff line change
@@ -2834,10 +2834,15 @@ class SYCLKernelNameTypeVisitor
28342834
Sema &S;
28352835
SourceLocation KernelInvocationFuncLoc;
28362836
using InnerTypeVisitor = TypeVisitor<SYCLKernelNameTypeVisitor>;
2837-
using InnerTAVisitor =
2837+
using InnerTemplArgVisitor =
28382838
ConstTemplateArgumentVisitor<SYCLKernelNameTypeVisitor>;
28392839
bool IsInvalid = false;
28402840

2841+
void VisitTemplateArgs(ArrayRef<TemplateArgument> Args) {
2842+
for (auto &A : Args)
2843+
Visit(A);
2844+
}
2845+
28412846
public:
28422847
SYCLKernelNameTypeVisitor(Sema &S, SourceLocation KernelInvocationFuncLoc)
28432848
: S(S), KernelInvocationFuncLoc(KernelInvocationFuncLoc) {}
@@ -2848,15 +2853,19 @@ class SYCLKernelNameTypeVisitor
28482853
if (T.isNull())
28492854
return;
28502855
const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
2851-
if (!RD)
2856+
if (!RD) {
2857+
if (T->isNullPtrType()) {
2858+
S.Diag(KernelInvocationFuncLoc, diag::err_sycl_kernel_incorrectly_named)
2859+
<< /* kernel name cannot be a type in the std namespace */ 3;
2860+
IsInvalid = true;
2861+
}
28522862
return;
2863+
}
28532864
// If KernelNameType has template args visit each template arg via
28542865
// ConstTemplateArgumentVisitor
28552866
if (const auto *TSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
2856-
const TemplateArgumentList &Args = TSD->getTemplateArgs();
2857-
for (unsigned I = 0; I < Args.size(); I++) {
2858-
Visit(Args[I]);
2859-
}
2867+
ArrayRef<TemplateArgument> Args = TSD->getTemplateArgs().asArray();
2868+
VisitTemplateArgs(Args);
28602869
} else {
28612870
InnerTypeVisitor::Visit(T.getTypePtr());
28622871
}
@@ -2865,7 +2874,7 @@ class SYCLKernelNameTypeVisitor
28652874
void Visit(const TemplateArgument &TA) {
28662875
if (TA.isNull())
28672876
return;
2868-
InnerTAVisitor::Visit(TA);
2877+
InnerTemplArgVisitor::Visit(TA);
28692878
}
28702879

28712880
void VisitEnumType(const EnumType *T) {
@@ -2886,22 +2895,31 @@ class SYCLKernelNameTypeVisitor
28862895
void VisitTagDecl(const TagDecl *Tag) {
28872896
bool UnnamedLambdaEnabled =
28882897
S.getASTContext().getLangOpts().SYCLUnnamedLambda;
2889-
if (!Tag->getDeclContext()->isTranslationUnit() &&
2890-
!isa<NamespaceDecl>(Tag->getDeclContext()) && !UnnamedLambdaEnabled) {
2891-
const bool KernelNameIsMissing = Tag->getName().empty();
2892-
if (KernelNameIsMissing) {
2898+
const DeclContext *DeclCtx = Tag->getDeclContext();
2899+
if (DeclCtx && !UnnamedLambdaEnabled) {
2900+
auto *NameSpace = dyn_cast_or_null<NamespaceDecl>(DeclCtx);
2901+
if (NameSpace && NameSpace->isStdNamespace()) {
28932902
S.Diag(KernelInvocationFuncLoc, diag::err_sycl_kernel_incorrectly_named)
2894-
<< /* kernel name is missing */ 0;
2903+
<< /* kernel name cannot be a type in the std namespace */ 3;
28952904
IsInvalid = true;
2896-
} else {
2905+
return;
2906+
}
2907+
if (!DeclCtx->isTranslationUnit() && !isa<NamespaceDecl>(DeclCtx)) {
2908+
const bool KernelNameIsMissing = Tag->getName().empty();
2909+
if (KernelNameIsMissing) {
2910+
S.Diag(KernelInvocationFuncLoc,
2911+
diag::err_sycl_kernel_incorrectly_named)
2912+
<< /* kernel name is missing */ 0;
2913+
IsInvalid = true;
2914+
return;
2915+
}
28972916
if (Tag->isCompleteDefinition()) {
28982917
S.Diag(KernelInvocationFuncLoc,
28992918
diag::err_sycl_kernel_incorrectly_named)
29002919
<< /* kernel name is not globally-visible */ 1;
29012920
IsInvalid = true;
29022921
} else
29032922
S.Diag(KernelInvocationFuncLoc, diag::warn_sycl_implicit_decl);
2904-
29052923
S.Diag(Tag->getSourceRange().getBegin(), diag::note_previous_decl)
29062924
<< Tag->getName();
29072925
}
@@ -2932,6 +2950,10 @@ class SYCLKernelNameTypeVisitor
29322950
VisitEnumType(ET);
29332951
}
29342952
}
2953+
2954+
void VisitPackTemplateArgument(const TemplateArgument &TA) {
2955+
VisitTemplateArgs(TA.getPackAsArray());
2956+
}
29352957
};
29362958

29372959
void Sema::CheckSYCLKernelCall(FunctionDecl *KernelFunc, SourceRange CallLoc,
@@ -3337,12 +3359,6 @@ void SYCLIntegrationHeader::emitFwdDecl(raw_ostream &O, const Decl *D,
33373359
break;
33383360
}
33393361

3340-
if (NS->isStdNamespace()) {
3341-
Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named)
3342-
<< /* name cannot be a type in the std namespace */ 3;
3343-
return;
3344-
}
3345-
33463362
++NamespaceCnt;
33473363
const StringRef NSInlinePrefix = NS->isInline() ? "inline " : "";
33483364
NSStr.insert(
@@ -3426,9 +3442,6 @@ void SYCLIntegrationHeader::emitForwardClassDecls(
34263442
const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
34273443

34283444
if (!RD) {
3429-
if (T->isNullPtrType())
3430-
Diag.Report(KernelLocation, diag::err_sycl_kernel_incorrectly_named)
3431-
<< /* name cannot be a type in the std namespace */ 3;
34323445

34333446
return;
34343447
}

clang/test/CodeGenSYCL/stdtypes_kernel_type.cpp

-57
This file was deleted.

clang/test/CodeGenSYCL/template-template-parameter.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-int-header=%t.h %s
1+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-int-header=%t.h -sycl-std=2020 %s
22
// RUN: FileCheck -input-file=%t.h %s
33

44
#include "Inputs/sycl.hpp"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -sycl-std=2020 -DCHECK_ERROR -verify %s
2+
3+
#include "Inputs/sycl.hpp"
4+
5+
namespace std {
6+
typedef long unsigned int size_t;
7+
typedef long int ptrdiff_t;
8+
typedef decltype(nullptr) nullptr_t;
9+
class T;
10+
class U;
11+
} // namespace std
12+
13+
template <typename T>
14+
struct Templated_kernel_name;
15+
16+
template <typename T, typename... Args> class TemplParamPack;
17+
18+
using namespace cl::sycl;
19+
queue q;
20+
21+
int main() {
22+
#ifdef CHECK_ERROR
23+
// expected-error@Inputs/sycl.hpp:220 5 {{kernel name cannot be a type in the "std" namespace}}
24+
q.submit([&](handler &h) {
25+
// expected-note@+1{{in instantiation of function template specialization}}
26+
h.single_task<std::nullptr_t>([=] {});
27+
});
28+
q.submit([&](handler &h) {
29+
// expected-note@+1{{in instantiation of function template specialization}}
30+
h.single_task<std::T>([=] {});
31+
});
32+
q.submit([&](handler &h) {
33+
// expected-note@+1{{in instantiation of function template specialization}}
34+
h.single_task<Templated_kernel_name<std::nullptr_t>>([=] {});
35+
});
36+
q.submit([&](handler &h) {
37+
// expected-note@+1{{in instantiation of function template specialization}}
38+
h.single_task<Templated_kernel_name<std::U>>([=] {});
39+
});
40+
q.submit([&](handler &cgh) {
41+
// expected-note@+1{{in instantiation of function template specialization}}
42+
cgh.single_task<TemplParamPack<int, float, std::nullptr_t, double>>([]() {});
43+
});
44+
#endif
45+
46+
// Although in the std namespace, these resolve to builtins such as `int` that are allowed in kernel names
47+
q.submit([&](handler &h) {
48+
h.single_task<std::size_t>([=] {});
49+
});
50+
q.submit([&](handler &h) {
51+
h.single_task<std::ptrdiff_t>([=] {});
52+
});
53+
54+
return 0;
55+
}

clang/test/SemaSYCL/unnamed-kernel.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-int-header=%t.h -fsyntax-only -Wno-sycl-2017-compat -verify %s
2-
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-int-header=%t.h -fsycl-unnamed-lambda -fsyntax-only -Wno-sycl-2017-compat -verify %s
1+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsyntax-only -Wno-sycl-2017-compat -verify %s
2+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -fsycl-unnamed-lambda -fsyntax-only -Wno-sycl-2017-compat -verify %s
33
#include "Inputs/sycl.hpp"
44

55
#ifdef __SYCL_UNNAMED_LAMBDA__
@@ -70,7 +70,8 @@ struct MyWrapper {
7070
});
7171

7272
#ifndef __SYCL_UNNAMED_LAMBDA__
73-
// expected-error@+3 {{kernel name cannot be a type in the "std" namespace}}
73+
// expected-error@Inputs/sycl.hpp:220 {{kernel name cannot be a type in the "std" namespace}}
74+
// expected-note@+3{{in instantiation of function template specialization}}
7475
#endif
7576
q.submit([&](cl::sycl::handler &h) {
7677
h.single_task<std::max_align_t>([] {});

0 commit comments

Comments
 (0)