From 7cac129f2a6c0a1a3d77b17fed98e3a5f5603010 Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Tue, 18 Feb 2020 15:03:10 -0800 Subject: [PATCH 1/2] [SYCL] Update the kernel parameter rule to is-trivially-copy-constructible. Since we really just want to be able to memcpy the type to the device, 'is-trivially-copyable' is not the correct trait. Since CWG1734, If we want to support trivially copyable types, we would be required to create 1 of 4 different mechanisms for having a type on the device (depending on the way the type is structured). Additionally, 2 of these ways require us to ALSO have the type be default constructible. This patch transitions to trivially-copy-constructible , so that we can simply memcpy from the existing one into new memory. Signed-off-by: Erich Keane --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Sema/SemaSYCL.cpp | 5 ++++- .../SemaSYCL/non-trivially-copyable-kernel-param.cpp | 9 ++++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 02cad98277ddc..56b95ff734dd6 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10491,7 +10491,7 @@ def err_sycl_virtual_types : Error< def note_sycl_used_here : Note<"used here">; def note_sycl_recursive_function_declared_here: Note<"function implemented using recursion declared here">; def err_sycl_non_trivially_copyable_type : Error< - "kernel parameter has non-trivially copyable class/struct type %0">; + "kernel parameter has non-trivially copy constructible class/struct type %0">; def err_sycl_non_std_layout_type : Error< "kernel parameter has non-standard layout class/struct type %0">; def err_conflicting_sycl_kernel_attributes : Error< diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index dee3ede03370b..7aa6e091cfc67 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -1069,7 +1069,10 @@ static bool buildArgTys(ASTContext &Context, CXXRecordDecl *KernelObj, continue; } } - if (!ArgTy.isTriviallyCopyableType(Context)) { + + CXXRecordDecl *RD = + cast(ArgTy->getAs()->getDecl()); + if (!RD->hasTrivialCopyConstructor()) { Context.getDiagnostics().Report( Fld->getLocation(), diag::err_sycl_non_trivially_copyable_type) << ArgTy; diff --git a/clang/test/SemaSYCL/non-trivially-copyable-kernel-param.cpp b/clang/test/SemaSYCL/non-trivially-copyable-kernel-param.cpp index 70f4ba9f66808..14ee390c89df8 100644 --- a/clang/test/SemaSYCL/non-trivially-copyable-kernel-param.cpp +++ b/clang/test/SemaSYCL/non-trivially-copyable-kernel-param.cpp @@ -11,6 +11,11 @@ struct B { B (const B& x) : i(x.i) {} }; +struct C : A { + const A C2; + C() : A{0}, C2{2}{} +}; + template __attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { kernelFunc(); @@ -20,9 +25,11 @@ void test() { A IamGood; IamGood.i = 0; B IamBad(1); + C IamAlsoGood; kernel_single_task([=] { int a = IamGood.i; - // expected-error@+1 {{kernel parameter has non-trivially copyable class/struct type}} + // expected-error@+1 {{kernel parameter has non-trivially copy constructible class/struct type}} int b = IamBad.i; + int C = IamAlsoGood.i; }); } From 86dd11c378e858eb203460876aa93f9587fa7727 Mon Sep 17 00:00:00 2001 From: Erich Keane Date: Wed, 19 Feb 2020 06:25:39 -0800 Subject: [PATCH 2/2] [SYCL] Change error message name, add trivially dtor-able as a requirement. Signed-off-by: Erich Keane --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++-- clang/lib/Sema/SemaSYCL.cpp | 13 +++++++++++-- .../non-trivially-copyable-kernel-param.cpp | 10 +++++++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 56b95ff734dd6..308e5f3a457ef 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10490,8 +10490,9 @@ def err_sycl_virtual_types : Error< "No class with a vtable can be used in a SYCL kernel or any code included in the kernel">; def note_sycl_used_here : Note<"used here">; def note_sycl_recursive_function_declared_here: Note<"function implemented using recursion declared here">; -def err_sycl_non_trivially_copyable_type : Error< - "kernel parameter has non-trivially copy constructible class/struct type %0">; +def err_sycl_non_trivially_copy_ctor_dtor_type + : Error<"kernel parameter has non-trivially %select{copy " + "constructible|destructible}0 class/struct type %1">; def err_sycl_non_std_layout_type : Error< "kernel parameter has non-standard layout class/struct type %0">; def err_conflicting_sycl_kernel_attributes : Error< diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index 7aa6e091cfc67..af257347d8823 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -1074,8 +1074,17 @@ static bool buildArgTys(ASTContext &Context, CXXRecordDecl *KernelObj, cast(ArgTy->getAs()->getDecl()); if (!RD->hasTrivialCopyConstructor()) { Context.getDiagnostics().Report( - Fld->getLocation(), diag::err_sycl_non_trivially_copyable_type) - << ArgTy; + Fld->getLocation(), + diag::err_sycl_non_trivially_copy_ctor_dtor_type) + << 0 << ArgTy; + AllArgsAreValid = false; + continue; + } + if (!RD->hasTrivialDestructor()) { + Context.getDiagnostics().Report( + Fld->getLocation(), + diag::err_sycl_non_trivially_copy_ctor_dtor_type) + << 1 << ArgTy; AllArgsAreValid = false; continue; } diff --git a/clang/test/SemaSYCL/non-trivially-copyable-kernel-param.cpp b/clang/test/SemaSYCL/non-trivially-copyable-kernel-param.cpp index 14ee390c89df8..58cfe0c1eba4a 100644 --- a/clang/test/SemaSYCL/non-trivially-copyable-kernel-param.cpp +++ b/clang/test/SemaSYCL/non-trivially-copyable-kernel-param.cpp @@ -16,6 +16,11 @@ struct C : A { C() : A{0}, C2{2}{} }; +struct D { + int i; + ~D(); +}; + template __attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { kernelFunc(); @@ -26,10 +31,13 @@ void test() { IamGood.i = 0; B IamBad(1); C IamAlsoGood; + D IamAlsoBad{0}; kernel_single_task([=] { int a = IamGood.i; // expected-error@+1 {{kernel parameter has non-trivially copy constructible class/struct type}} int b = IamBad.i; - int C = IamAlsoGood.i; + int c = IamAlsoGood.i; + // expected-error@+1 {{kernel parameter has non-trivially destructible class/struct type}} + int d = IamAlsoBad.i; }); }