Skip to content

Commit c0044ab

Browse files
committed
Fixes to address issues with diagnostics for templated functions, lambdas, and dependent return types.
This change addresses issues with diagnostics generation for various uses of the sycl_kernel_entry_point attribute: - Missing diagnostics for deleted or defaulted functions declared in a dependent context. - Missing diagnostics for lambda expressions. - Spurious diagnostics for functions with a dependent return type; a diagnostic was previously issued complaining of a non-void type. - Missing diagnostics for functions with a deduced return type.
1 parent da651f6 commit c0044ab

File tree

5 files changed

+115
-8
lines changed

5 files changed

+115
-8
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12431,6 +12431,9 @@ def err_sycl_entry_point_after_definition : Error<
1243112431
def err_sycl_entry_point_return_type : Error<
1243212432
"'sycl_kernel_entry_point' attribute only applies to functions with a"
1243312433
" 'void' return type">;
12434+
def err_sycl_entry_point_deduced_return_type : Error<
12435+
"'sycl_kernel_entry_point' attribute only applies to functions with a"
12436+
" non-deduced 'void' return type">;
1243412437

1243512438
def warn_cuda_maxclusterrank_sm_90 : Warning<
1243612439
"maxclusterrank requires sm_90 or higher, CUDA arch provided: %0, ignoring "

clang/lib/Sema/SemaDecl.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12156,7 +12156,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
1215612156
if (LangOpts.OpenMP)
1215712157
OpenMP().ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(NewFD);
1215812158

12159-
if (LangOpts.isSYCL() && NewFD->hasAttr<SYCLKernelEntryPointAttr>())
12159+
if (NewFD->hasAttr<SYCLKernelEntryPointAttr>())
1216012160
SYCL().CheckSYCLEntryPointFunctionDecl(NewFD);
1216112161

1216212162
// Semantic checking for this function declaration (in isolation).
@@ -15990,17 +15990,16 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
1599015990
}
1599115991

1599215992
// Diagnose invalid SYCL kernel entry point function declarations.
15993-
if (FD && !FD->isInvalidDecl() && !FD->isTemplated() &&
15994-
FD->hasAttr<SYCLKernelEntryPointAttr>()) {
15993+
if (FD && !FD->isInvalidDecl() && FD->hasAttr<SYCLKernelEntryPointAttr>()) {
1599515994
SYCLKernelEntryPointAttr *SKEPAttr =
1599615995
FD->getAttr<SYCLKernelEntryPointAttr>();
15997-
if (FD->isDeleted()) {
15996+
if (FD->isDefaulted()) {
1599815997
Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
15999-
<< /*deleted function*/ 2;
15998+
<< /*defaulted function*/ 3;
1600015999
SKEPAttr->setInvalidAttr();
16001-
} else if (FD->isDefaulted()) {
16000+
} else if (FD->isDeleted()) {
1600216001
Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
16003-
<< /*defaulted function*/ 3;
16002+
<< /*deleted function*/ 2;
1600416003
SKEPAttr->setInvalidAttr();
1600516004
} else if (FSI->isCoroutine()) {
1600616005
Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)

clang/lib/Sema/SemaLambda.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "clang/Sema/SemaCUDA.h"
2525
#include "clang/Sema/SemaInternal.h"
2626
#include "clang/Sema/SemaOpenMP.h"
27+
#include "clang/Sema/SemaSYCL.h"
2728
#include "clang/Sema/Template.h"
2829
#include "llvm/ADT/STLExtras.h"
2930
#include <optional>
@@ -1948,6 +1949,10 @@ ExprResult Sema::BuildCaptureInit(const Capture &Cap,
19481949

19491950
ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body) {
19501951
LambdaScopeInfo LSI = *cast<LambdaScopeInfo>(FunctionScopes.back());
1952+
1953+
if (LSI.CallOperator->hasAttr<SYCLKernelEntryPointAttr>())
1954+
SYCL().CheckSYCLEntryPointFunctionDecl(LSI.CallOperator);
1955+
19511956
ActOnFinishFunctionBody(LSI.CallOperator, Body);
19521957

19531958
return BuildLambdaExpr(StartLoc, Body->getEndLoc(), &LSI);

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,23 @@ void SemaSYCL::CheckSYCLEntryPointFunctionDecl(FunctionDecl *FD) {
301301
SKEPAttr->setInvalidAttr();
302302
}
303303
}
304+
304305
if (FD->isVariadic()) {
305306
Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
306307
<< /*variadic function*/ 1;
307308
SKEPAttr->setInvalidAttr();
308309
}
310+
311+
if (FD->isDefaulted()) {
312+
Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
313+
<< /*defaulted function*/ 3;
314+
SKEPAttr->setInvalidAttr();
315+
} else if (FD->isDeleted()) {
316+
Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
317+
<< /*deleted function*/ 2;
318+
SKEPAttr->setInvalidAttr();
319+
}
320+
309321
if (FD->isConsteval()) {
310322
Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
311323
<< /*consteval function*/ 5;
@@ -315,13 +327,19 @@ void SemaSYCL::CheckSYCLEntryPointFunctionDecl(FunctionDecl *FD) {
315327
<< /*constexpr function*/ 4;
316328
SKEPAttr->setInvalidAttr();
317329
}
330+
318331
if (FD->isNoReturn()) {
319332
Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_invalid)
320333
<< /*function declared with the 'noreturn' attribute*/ 6;
321334
SKEPAttr->setInvalidAttr();
322335
}
323336

324-
if (!FD->getReturnType()->isVoidType()) {
337+
if (FD->getReturnType()->isUndeducedType()) {
338+
Diag(SKEPAttr->getLocation(),
339+
diag::err_sycl_entry_point_deduced_return_type);
340+
SKEPAttr->setInvalidAttr();
341+
} else if (!FD->getReturnType()->isDependentType() &&
342+
!FD->getReturnType()->isVoidType()) {
325343
Diag(SKEPAttr->getLocation(), diag::err_sycl_entry_point_return_type);
326344
SKEPAttr->setInvalidAttr();
327345
}

clang/test/SemaSYCL/sycl-kernel-entry-point-attr-appertainment.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
22
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only -fsycl-is-device -verify %s
3+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++23 -fsyntax-only -fsycl-is-device -verify %s
34

45
// These tests validate appertainment for the sycl_kernel_entry_point attribute.
56

@@ -118,6 +119,17 @@ VOID ok12();
118119
[[clang::sycl_kernel_entry_point(KN<13>)]]
119120
const void ok13();
120121

122+
#if __cplusplus >= 202302L
123+
auto ok14 = [] [[clang::sycl_kernel_entry_point(KN<14>)]] static -> void {};
124+
#endif
125+
126+
template<typename KNT, typename T>
127+
struct S15 {
128+
// Don't diagnose a dependent return type as a non-void type.
129+
[[clang::sycl_kernel_entry_point(KNT)]]
130+
static T ok15();
131+
};
132+
121133

122134
////////////////////////////////////////////////////////////////////////////////
123135
// Invalid declarations.
@@ -264,3 +276,73 @@ consteval void bad25() {}
264276
__attribute__((target("avx"))) void bad27();
265277
[[clang::sycl_kernel_entry_point(BADKN<27>)]]
266278
__attribute__((target("sse4.2"))) void bad27();
279+
280+
template<typename KNT>
281+
struct B28 {
282+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute cannot be applied to a deleted function}}
283+
[[clang::sycl_kernel_entry_point(KNT)]]
284+
friend void bad28() = delete;
285+
};
286+
287+
#if __cplusplus >= 202002L
288+
template<typename KNT, typename T>
289+
struct B29 {
290+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute cannot be applied to a defaulted function}}
291+
[[clang::sycl_kernel_entry_point(KNT)]]
292+
friend T operator==(B29, B29) = default;
293+
};
294+
#endif
295+
296+
#if __cplusplus >= 202002L
297+
template<typename KNT>
298+
struct B30 {
299+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute cannot be applied to a coroutine}}
300+
[[clang::sycl_kernel_entry_point(KNT)]]
301+
friend void bad30() { co_return; }
302+
};
303+
#endif
304+
305+
template<typename KNT>
306+
struct B31 {
307+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute cannot be applied to a variadic function}}
308+
[[clang::sycl_kernel_entry_point(KNT)]]
309+
friend void bad31(...) {}
310+
};
311+
312+
template<typename KNT>
313+
struct B32 {
314+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute cannot be applied to a constexpr function}}
315+
[[clang::sycl_kernel_entry_point(KNT)]]
316+
friend constexpr void bad32() {}
317+
};
318+
319+
#if __cplusplus >= 202002L
320+
template<typename KNT>
321+
struct B33 {
322+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute cannot be applied to a consteval function}}
323+
[[clang::sycl_kernel_entry_point(KNT)]]
324+
friend consteval void bad33() {}
325+
};
326+
#endif
327+
328+
template<typename KNT>
329+
struct B34 {
330+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute cannot be applied to a function declared with the 'noreturn' attribute}}
331+
[[clang::sycl_kernel_entry_point(KNT)]]
332+
[[noreturn]] friend void bad34() {}
333+
};
334+
335+
#if __cplusplus >= 202302L
336+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute cannot be applied to a non-static member function}}
337+
auto bad35 = [] [[clang::sycl_kernel_entry_point(BADKN<35>)]] -> void {};
338+
#endif
339+
340+
#if __cplusplus >= 202302L
341+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute only applies to functions with a non-deduced 'void' return type}}
342+
auto bad36 = [] [[clang::sycl_kernel_entry_point(BADKN<36>)]] static {};
343+
#endif
344+
345+
#if __cplusplus >= 202302L
346+
// expected-error@+1 {{'sycl_kernel_entry_point' attribute cannot be applied to a coroutine}}
347+
auto bad37 = [] [[clang::sycl_kernel_entry_point(BADKN<37>)]] static -> void { co_return; };
348+
#endif

0 commit comments

Comments
 (0)