Skip to content

Commit 79c460c

Browse files
authored
[SYCL] Allow __failed_assertion to support libstdc++-11 (#3774)
Signed-off-by: gejin <ge.jin@intel.com>
1 parent 15bbed8 commit 79c460c

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ static constexpr llvm::StringLiteral InitESIMDMethodName = "__init_esimd";
6161
static constexpr llvm::StringLiteral InitSpecConstantsBuffer =
6262
"__init_specialization_constants_buffer";
6363
static constexpr llvm::StringLiteral FinalizeMethodName = "__finalize";
64+
static constexpr llvm::StringLiteral LibstdcxxFailedAssertion =
65+
"__failed_assertion";
6466
constexpr unsigned MaxKernelArgsSize = 2048;
6567

6668
namespace {
@@ -320,6 +322,21 @@ static bool isSYCLKernelBodyFunction(FunctionDecl *FD) {
320322
return FD->getOverloadedOperator() == OO_Call;
321323
}
322324

325+
static bool isSYCLUndefinedAllowed(const FunctionDecl *Callee,
326+
const SourceManager &SrcMgr) {
327+
if (!Callee)
328+
return false;
329+
330+
// libstdc++-11 introduced an undefined function "void __failed_assertion()"
331+
// which may lead to SemaSYCL check failure. However, this undefined function
332+
// is used to trigger some compilation error when the check fails at compile
333+
// time and will be ignored when the check succeeds. We allow calls to this
334+
// function to support some important std functions in SYCL device.
335+
return (Callee->getName() == LibstdcxxFailedAssertion) &&
336+
Callee->getNumParams() == 0 && Callee->getReturnType()->isVoidType() &&
337+
SrcMgr.isInSystemHeader(Callee->getLocation());
338+
}
339+
323340
// Helper function to report conflicting function attributes.
324341
// F - the function, A1 - function attribute, A2 - the attribute it conflicts
325342
// with.
@@ -4034,7 +4051,10 @@ void Sema::finalizeSYCLDelayedAnalysis(const FunctionDecl *Caller,
40344051
return;
40354052

40364053
// Diagnose if this is an undefined function and it is not a builtin.
4037-
if (!Callee->isDefined() && !Callee->getBuiltinID()) {
4054+
// Currently, there is an exception of "__failed_assertion" in libstdc++-11,
4055+
// this undefined function is used to trigger a compiling error.
4056+
if (!Callee->isDefined() && !Callee->getBuiltinID() &&
4057+
!isSYCLUndefinedAllowed(Callee, getSourceManager())) {
40384058
Diag(Loc, diag::err_sycl_restrict) << Sema::KernelCallUndefinedFunction;
40394059
Diag(Callee->getLocation(), diag::note_previous_decl) << Callee;
40404060
Diag(Caller->getLocation(), diag::note_called_by) << Caller;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
void __failed_assertion();
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -sycl-std=2020 -verify -DUSR -fsyntax-only %s
2+
// RUN: %clang_cc1 -fsycl-is-device -internal-isystem %S/Inputs -sycl-std=2020 -verify -fsyntax-only %s
3+
// UNSUPPORTED: system-windows
4+
// This test checks that an undefined "__failed_assertion" without SYCL_EXTERNAL will lead to SYCL sema check
5+
// failure if it is not declared in a system header otherwise no SYCL sema check failure will be triggered.
6+
7+
#include "sycl.hpp"
8+
#ifdef USR
9+
void __failed_assertion();
10+
// expected-note@-1 {{'__failed_assertion' declared here}}
11+
#else
12+
#include <dummy_failed_assert>
13+
#endif
14+
15+
#ifdef USR
16+
SYCL_EXTERNAL
17+
void call_failed_assertion() {
18+
// expected-note@-1 {{called by 'call_failed_assertion'}}
19+
__failed_assertion();
20+
// expected-error@-1 {{SYCL kernel cannot call an undefined function without SYCL_EXTERNAL attribute}}
21+
}
22+
#else
23+
// expected-no-diagnostics
24+
SYCL_EXTERNAL
25+
void call_failed_assertion() {
26+
__failed_assertion();
27+
}
28+
#endif
29+

0 commit comments

Comments
 (0)