Skip to content

Commit 270bb93

Browse files
authored
[SYCL] Move function pointer diagnostics to BuildResolvedCallExpr (#16987)
The patch moves the function pointer related diagnostics from DiagDeviceFunction::VisitCallExpr class to BuildResolvedCallExpr and use a delayed diagnostic. This allow the compiler to provide the template instantiation trace when emitting the diagnostic.
1 parent 9ad2e87 commit 270bb93

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

clang/lib/Sema/SemaExpr.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -7124,6 +7124,18 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
71247124
return ExprError();
71257125
}
71267126

7127+
// Diagnose function pointers in SYCL.
7128+
if (!FDecl && !getLangOpts().SYCLAllowFuncPtr && getLangOpts().SYCLIsDevice &&
7129+
!isUnevaluatedContext()) {
7130+
bool MaybeConstantExpr = false;
7131+
Expr *NonDirectCallee = TheCall->getCallee();
7132+
if (!NonDirectCallee->isValueDependent())
7133+
MaybeConstantExpr = NonDirectCallee->isCXX11ConstantExpr(getASTContext());
7134+
if (!MaybeConstantExpr)
7135+
SYCL().DiagIfDeviceCode(TheCall->getExprLoc(), diag::err_sycl_restrict)
7136+
<< SemaSYCL::KernelCallFunctionPointer;
7137+
}
7138+
71277139
return CheckForImmediateInvocation(MaybeBindToTemporary(TheCall), FDecl);
71287140
}
71297141

clang/lib/Sema/SemaSYCL.cpp

-11
Original file line numberDiff line numberDiff line change
@@ -687,17 +687,6 @@ class DiagDeviceFunction : public RecursiveASTVisitor<DiagDeviceFunction> {
687687
SemaSYCLRef.Diag(e->getExprLoc(), diag::err_builtin_target_unsupported)
688688
<< Name << "SYCL device";
689689
}
690-
} else if (!SemaSYCLRef.getLangOpts().SYCLAllowFuncPtr &&
691-
!e->isTypeDependent() &&
692-
!isa<CXXPseudoDestructorExpr>(e->getCallee())) {
693-
bool MaybeConstantExpr = false;
694-
Expr *NonDirectCallee = e->getCallee();
695-
if (!NonDirectCallee->isValueDependent())
696-
MaybeConstantExpr =
697-
NonDirectCallee->isCXX11ConstantExpr(SemaSYCLRef.getASTContext());
698-
if (!MaybeConstantExpr)
699-
SemaSYCLRef.Diag(e->getExprLoc(), diag::err_sycl_restrict)
700-
<< SemaSYCL::KernelCallFunctionPointer;
701690
}
702691
return true;
703692
}

clang/test/SemaSYCL/constexpr-function-pointer.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
// RUN: %clang_cc1 -fsycl-is-device -fsyntax-only -verify -sycl-std=2020 -std=c++17 %s
2+
// RUN: %clang_cc1 -fsycl-is-host -fsyntax-only -verify=host -sycl-std=2020 -std=c++17 %s
23

34
// This test checks that the compiler doesn't emit an error when indirect call
45
// was made through a function pointer that is constant expression, and makes
56
// sure that the error is emitted when a function pointer is not a constant
67
// expression.
78

9+
// host-no-diagnostics
10+
811
void t() {}
912

1013
constexpr auto F = t;
@@ -22,6 +25,8 @@ void bar1(const SomeFunc fptr) {
2225

2326
template <auto f> void fooNTTP() { f(); }
2427

28+
template <typename FTy> void templated(FTy f) { f(); } // #call-templated
29+
2530
__attribute__((sycl_device)) void bar() {
2631
// OK
2732
constexpr auto f = t;
@@ -48,4 +53,19 @@ __attribute__((sycl_device)) void bar() {
4853
fff();
4954

5055
fooNTTP<t>();
56+
57+
templated(t);
58+
// expected-error@#call-templated {{SYCL kernel cannot call through a function pointer}}
59+
// expected-note@-2 {{called by 'bar'}}
60+
}
61+
62+
void from_host() {
63+
const auto f1 = t;
64+
f1();
65+
auto f2 = t;
66+
f2();
67+
68+
fooNTTP<t>();
69+
70+
templated(t);
5171
}

0 commit comments

Comments
 (0)