Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SYCL] Emit a warning on constexprs captured in SYCL kernels #2824

Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -1252,3 +1252,7 @@ in addition with the pragmas or -fmax-tokens flag to get any warnings.
def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">;

def RTTI : DiagGroup<"rtti">;

// A warning group for warnings related to constexprs captured as
// kernel args.
def ConstExprKernelArg : DiagGroup<"constexpr-kernel-arg">;
srividya-sundaram marked this conversation as resolved.
Show resolved Hide resolved
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -7449,6 +7449,8 @@ let CategoryName = "Lambda Issue" in {
"%select{| explicitly}1 captured here">;
def err_implicit_this_capture : Error<
"implicit capture of 'this' is not allowed for kernel functions">;
def warn_constexpr_kernel_arg : Warning<
"constexpr is captured and is not a compile-time constant">, InGroup<ConstExprKernelArg>;

// C++14 lambda init-captures.
def warn_cxx11_compat_init_capture : Warning<
Expand Down
11 changes: 8 additions & 3 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3039,12 +3039,17 @@ void Sema::CheckSYCLKernelCall(FunctionDecl *KernelFunc, SourceRange CallLoc,
}

if (KernelObj->isLambda()) {
for (const LambdaCapture &LC : KernelObj->captures())
if (LC.capturesThis() && LC.isImplicit()) {
Diag(LC.getLocation(), diag::err_implicit_this_capture);
for (const LambdaCapture &Capture : KernelObj->captures())
if (Capture.capturesThis() && Capture.isImplicit()) {
Diag(Capture.getLocation(), diag::err_implicit_this_capture);
Diag(CallLoc.getBegin(), diag::note_used_here);
KernelFunc->setInvalidDecl();
}
// Emit a warning on constexprs captured in SYCL kernels
else if (Capture.isImplicit() && Capture.capturesVariable()) {
if (Capture.getCapturedVar()->isConstexpr())
Diag(Capture.getLocation(), diag::warn_constexpr_kernel_arg);
}
}

// check that calling kernel conforms to spec
Expand Down
3 changes: 2 additions & 1 deletion clang/test/Misc/warning-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This test serves two purposes:

The list of warnings below should NEVER grow. It should gradually shrink to 0.

CHECK: Warnings without flags (68):
CHECK: Warnings without flags (69):
srividya-sundaram marked this conversation as resolved.
Show resolved Hide resolved

CHECK-NEXT: ext_expected_semi_decl_list
CHECK-NEXT: ext_explicit_specialization_storage_class
Expand All @@ -42,6 +42,7 @@ CHECK-NEXT: warn_case_empty_range
CHECK-NEXT: warn_char_constant_too_large
CHECK-NEXT: warn_collection_expr_type
CHECK-NEXT: warn_conflicting_variadic
CHECK-NEXT: warn_constexpr_kernel_arg
CHECK-NEXT: warn_delete_array_type
CHECK-NEXT: warn_double_const_requires_fp64
CHECK-NEXT: warn_drv_assuming_mfloat_abi_is
Expand Down
38 changes: 38 additions & 0 deletions clang/test/SemaSYCL/warn-constexpr-kernel-arg.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// RUN: %clang_cc1 -fsycl -fsycl-is-device -internal-isystem %S/Inputs -fsyntax-only -Wsycl-strict -sycl-std=2020 -verify %s
srividya-sundaram marked this conversation as resolved.
Show resolved Hide resolved

#include "sycl.hpp"

using namespace cl::sycl;

queue q;

class LambdaKernel;

int main() {

constexpr unsigned V = 16;
struct Id {
int x;

Id(int x) : x(x) {}

Id operator*(const unsigned &val) const {
return Id(x * val);
}

operator int() const {
return x;
}
};

Id i{5};

q.submit([&](handler &h) {
// expected-note@+1 {{in instantiation of function template specialization}}
h.single_task<LambdaKernel>(
[=]() {
int A = i * V; // expected-warning {{constexpr is captured and is not a compile-time constant}}
srividya-sundaram marked this conversation as resolved.
Show resolved Hide resolved
});
});
return 0;
}