Skip to content

Commit 321c733

Browse files
[SYCL] Add diagnostic for annotated_pointers and annotated_args (#7053)
Types cannot be nested. Signed-off-by: Elizabeth Andrews <elizabeth.andrews@intel.com>
1 parent 4a67f2a commit 321c733

File tree

6 files changed

+127
-7
lines changed

6 files changed

+127
-7
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,11 +1302,11 @@ def SYCLType: InheritableAttr {
13021302
["accessor", "local_accessor", "spec_constant",
13031303
"specialization_id", "kernel_handler", "buffer_location",
13041304
"no_alias", "accessor_property_list", "group",
1305-
"private_memory", "aspect"],
1305+
"private_memory", "aspect", "annotated_ptr", "annotated_arg"],
13061306
["accessor", "local_accessor", "spec_constant",
13071307
"specialization_id", "kernel_handler", "buffer_location",
13081308
"no_alias", "accessor_property_list", "group",
1309-
"private_memory", "aspect"]>];
1309+
"private_memory", "aspect", "annotated_ptr", "annotated_arg"]>];
13101310
// Only used internally by SYCL implementation
13111311
let Documentation = [InternalOnly];
13121312
}

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10390,8 +10390,8 @@ def warn_opencl_generic_address_space_arg : Warning<
1039010390
"passing non-generic address space pointer to %0"
1039110391
" may cause dynamic conversion affecting performance">,
1039210392
InGroup<Conversion>, DefaultIgnore;
10393-
def err_bad_union_kernel_param_members : Error<
10394-
"%0 cannot be used inside a union kernel parameter">;
10393+
def err_bad_kernel_param_data_members : Error<
10394+
"%0 cannot be a data member of a %select{union|struct}1 kernel parameter">;
1039510395

1039610396
// OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions
1039710397
def err_opencl_builtin_pipe_first_arg : Error<

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1549,6 +1549,14 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler {
15491549
bool IsInvalid = false;
15501550
DiagnosticsEngine &Diag;
15511551
bool IsSIMD = false;
1552+
// Keeps track of whether we are currently handling fields inside a struct.
1553+
// Fields of kernel functor or direct kernel captures will have a depth 0.
1554+
int StructFieldDepth = 0;
1555+
// Initialize with -1 so that fields of a base class of the kernel functor
1556+
// has depth 0. Visitor method enterStruct increments this to 0 when the base
1557+
// class is entered.
1558+
int StructBaseDepth = -1;
1559+
15521560
// Check whether the object should be disallowed from being copied to kernel.
15531561
// Return true if not copyable, false if copyable.
15541562
bool checkNotCopyableToKernel(const FieldDecl *FD, QualType FieldTy) {
@@ -1633,6 +1641,16 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler {
16331641
bool checkSyclSpecialType(QualType Ty, SourceRange Loc) {
16341642
assert(isSyclSpecialType(Ty, SemaRef) &&
16351643
"Should only be called on sycl special class types.");
1644+
1645+
// Annotated pointers and annotated arguments must be captured
1646+
// directly by the SYCL kernel.
1647+
if ((isSyclType(Ty, SYCLTypeAttr::annotated_ptr) ||
1648+
isSyclType(Ty, SYCLTypeAttr::annotated_arg)) &&
1649+
(StructFieldDepth > 0 || StructBaseDepth > 0))
1650+
return SemaRef.Diag(Loc.getBegin(),
1651+
diag::err_bad_kernel_param_data_members)
1652+
<< Ty << /*Struct*/ 1;
1653+
16361654
const RecordDecl *RecD = Ty->getAsRecordDecl();
16371655
if (IsSIMD && !isSyclAccessorType(Ty))
16381656
return SemaRef.Diag(Loc.getBegin(),
@@ -1715,6 +1733,28 @@ class SyclKernelFieldChecker : public SyclKernelFieldHandler {
17151733
IsInvalid = true;
17161734
return isValid();
17171735
}
1736+
1737+
bool enterStruct(const CXXRecordDecl *, FieldDecl *, QualType) final {
1738+
++StructFieldDepth;
1739+
return true;
1740+
}
1741+
1742+
bool leaveStruct(const CXXRecordDecl *, FieldDecl *, QualType) final {
1743+
--StructFieldDepth;
1744+
return true;
1745+
}
1746+
1747+
bool enterStruct(const CXXRecordDecl *, const CXXBaseSpecifier &BS,
1748+
QualType FieldTy) final {
1749+
++StructBaseDepth;
1750+
return true;
1751+
}
1752+
1753+
bool leaveStruct(const CXXRecordDecl *, const CXXBaseSpecifier &BS,
1754+
QualType FieldTy) final {
1755+
--StructBaseDepth;
1756+
return true;
1757+
}
17181758
};
17191759

17201760
// A type to check the validity of accessing accessor/sampler/stream
@@ -1734,7 +1774,8 @@ class SyclKernelUnionChecker : public SyclKernelFieldHandler {
17341774
bool checkType(SourceLocation Loc, QualType Ty) {
17351775
if (UnionCount) {
17361776
IsInvalid = true;
1737-
Diag.Report(Loc, diag::err_bad_union_kernel_param_members) << Ty;
1777+
Diag.Report(Loc, diag::err_bad_kernel_param_data_members)
1778+
<< Ty << /*Union*/ 0;
17381779
}
17391780
return isValid();
17401781
}

clang/test/SemaSYCL/Inputs/sycl.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,23 @@ class __SYCL_TYPE(spec_constant) spec_constant {
403403
private:
404404
T DefaultValue;
405405
};
406+
407+
template <typename T, typename... Props>
408+
class __attribute__((sycl_special_class)) __SYCL_TYPE(annotated_arg) annotated_arg {
409+
T obj;
410+
#ifdef __SYCL_DEVICE_ONLY__
411+
void __init(T _obj) {}
412+
#endif
413+
};
414+
415+
template <typename T, typename... Props>
416+
class __attribute__((sycl_special_class)) __SYCL_TYPE(annotated_ptr) annotated_ptr {
417+
T* obj;
418+
#ifdef __SYCL_DEVICE_ONLY__
419+
void __init(T* _obj) {}
420+
#endif
421+
};
422+
406423
} // namespace experimental
407424
} // namespace oneapi
408425
} // namespace ext
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: %clang_cc1 -fsyntax-only -fsycl-is-device -internal-isystem %S/Inputs -verify %s
2+
3+
// Test diagnostic for nested annotated_arg and annotated_ptr type.
4+
5+
#include "sycl.hpp"
6+
7+
sycl::queue myQueue;
8+
9+
struct MockProperty {};
10+
11+
struct WrappedAnnotatedTypes {
12+
// expected-error@+1 3{{'sycl::ext::oneapi::experimental::annotated_arg<int, MockProperty>' cannot be a data member of a struct kernel parameter}}
13+
sycl::ext::oneapi::experimental::annotated_arg<int, MockProperty> AA;
14+
// expected-error@+1 3{{'sycl::ext::oneapi::experimental::annotated_ptr<int, MockProperty>' cannot be a data member of a struct kernel parameter}}
15+
sycl::ext::oneapi::experimental::annotated_ptr<int, MockProperty> AP;
16+
sycl::accessor<int, 1, sycl::access::mode::read_write> Acc;
17+
};
18+
19+
struct KernelBase {
20+
sycl::ext::oneapi::experimental::annotated_arg<int, MockProperty> BaseAA; // OK
21+
sycl::ext::oneapi::experimental::annotated_ptr<int, MockProperty> BaseAP; // OK
22+
WrappedAnnotatedTypes NestedInBase; // Error
23+
};
24+
25+
struct KernelFunctor : KernelBase {
26+
sycl::ext::oneapi::experimental::annotated_arg<int, MockProperty> AA; // OK
27+
sycl::ext::oneapi::experimental::annotated_ptr<int, MockProperty> AP; // OK
28+
void operator()() const {}
29+
};
30+
31+
struct KernelFunctor2 {
32+
WrappedAnnotatedTypes NestedInField; // Error
33+
void operator()() const {}
34+
};
35+
36+
int main() {
37+
sycl::ext::oneapi::experimental::annotated_arg<int, MockProperty> AA;
38+
sycl::ext::oneapi::experimental::annotated_ptr<int, MockProperty> AP;
39+
WrappedAnnotatedTypes Obj;
40+
myQueue.submit([&](sycl::handler &h) {
41+
// expected-note@+1 {{in instantiation of}}
42+
h.single_task<class kernel_half>(
43+
[=]() {
44+
(void)AA; // OK
45+
(void)AP; // OK
46+
(void)Obj; // Error
47+
});
48+
});
49+
50+
myQueue.submit([&](sycl::handler &h) {
51+
KernelFunctor f;
52+
// expected-note@+1 {{in instantiation of}}
53+
h.single_task(f);
54+
});
55+
56+
myQueue.submit([&](sycl::handler &h) {
57+
KernelFunctor2 f2;
58+
// expected-note@+1 {{in instantiation of}}
59+
h.single_task(f2);
60+
});
61+
}
62+

clang/test/SemaSYCL/union-kernel-param-neg.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ using namespace sycl;
88

99
union union_with_sampler {
1010
sycl::sampler smpl;
11-
// expected-error@-1 {{'sycl::sampler' cannot be used inside a union kernel parameter}}
11+
// expected-error@-1 {{'sycl::sampler' cannot be a data member of a union kernel parameter}}
1212
};
1313

1414
template <typename name, typename Func>
@@ -23,7 +23,7 @@ int main() {
2323

2424
union union_with_accessor {
2525
Accessor member_acc[1];
26-
// expected-error@-1 {{'Accessor' (aka 'accessor<int, 1, access::mode::read_write, access::target::global_buffer>') cannot be used inside a union kernel parameter}}
26+
// expected-error@-1 {{'Accessor' (aka 'accessor<int, 1, access::mode::read_write, access::target::global_buffer>') cannot be a data member of a union kernel parameter}}
2727
} union_acc;
2828

2929
union_with_sampler Sampler;

0 commit comments

Comments
 (0)