Skip to content

Commit 5eae571

Browse files
author
Ilya Stepykin
authored
[SYCL] Skip device diagnostics for unevaluated functions (#1093)
Do not produce an error if some restricted feature (e.g. exceptions) is used by a function only referenced in unevaluated context(e.g. in decltype expression) In order to do that, skip such functions when extracting device part of the code. Signed-off-by: Ilya Stepykin <[email protected]>
1 parent 47a9411 commit 5eae571

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,6 +1425,12 @@ Sema::DeviceDiagBuilder Sema::SYCLDiagIfDeviceCode(SourceLocation Loc,
14251425

14261426
void Sema::checkSYCLDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) {
14271427
assert(Callee && "Callee may not be null.");
1428+
1429+
// Errors in unevaluated context don't need to be generated,
1430+
// so we can safely skip them.
1431+
if (isUnevaluatedContext())
1432+
return;
1433+
14281434
FunctionDecl *Caller = dyn_cast<FunctionDecl>(getCurLexicalContext());
14291435

14301436
// If the caller is known-emitted, mark the callee as known-emitted.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %clang_cc1 -fcxx-exceptions -fsycl-is-device -verify -fsyntax-only %s
2+
3+
// Check that a function used in an unevaluated context is not subject
4+
// to delayed device diagnostics.
5+
6+
bool foo1() {
7+
// Throw exception which is not allowed on device. Error is expected
8+
// only when the function is called in evaluated context.
9+
// expected-error@+1 1{{SYCL kernel cannot use exceptions}}
10+
throw 10;
11+
12+
return false;
13+
}
14+
15+
template <typename T>
16+
T foo2(T t) {
17+
throw t;
18+
return t;
19+
}
20+
21+
bool foo3() {
22+
__float128 a;
23+
return false;
24+
}
25+
26+
template <typename Name, typename Func>
27+
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
28+
// expected-note@+1 1{{called by}}
29+
kernelFunc();
30+
}
31+
32+
int main() {
33+
using T1 = decltype(foo1());
34+
kernel_single_task<class fake_kernel>([]() {
35+
using T2 = decltype(foo1());
36+
37+
// expected-note@+1 1{{called by}}
38+
auto S1 = foo1();
39+
auto S2 = sizeof(foo1());
40+
41+
using T3 = decltype(foo2(decltype(foo1()){}));
42+
using T4 = decltype(foo3());
43+
44+
T1 f1;
45+
T2 f2;
46+
T3 f3;
47+
T4 f4;
48+
});
49+
return 0;
50+
}

0 commit comments

Comments
 (0)