Skip to content

Commit bd74453

Browse files
authored
[SYCL] Allow __glibcxx_assert_fail in SemaSYCL (#18856)
GCC-15 introduced __glibcxx_assert_fail function used in -O0 for many STL functions' runtime check. Its behavior is similar to normal 'assert', so we have supported it in libdevice in the same way as 'assert'. However, compfail will happen in some scenario reporting "undefined function without SYCL_EXTERNAL" error for "__glibcxx_assert_fail" declared in c++config.h, we have to allow this as exception in SemaSYCL. --------- Signed-off-by: jinge90 <[email protected]>
1 parent 906f598 commit bd74453

File tree

3 files changed

+58
-3
lines changed

3 files changed

+58
-3
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ static constexpr llvm::StringLiteral InitSpecConstantsBuffer =
7373
static constexpr llvm::StringLiteral FinalizeMethodName = "__finalize";
7474
static constexpr llvm::StringLiteral LibstdcxxFailedAssertion =
7575
"__failed_assertion";
76+
static constexpr llvm::StringLiteral GlibcxxAssertFail =
77+
"__glibcxx_assert_fail";
7678
constexpr unsigned MaxKernelArgsSize = 2048;
7779

7880
bool SemaSYCL::isSyclType(QualType Ty, SYCLTypeAttr::SYCLType TypeName) {
@@ -599,14 +601,33 @@ static bool isSYCLUndefinedAllowed(const FunctionDecl *Callee,
599601
if (!Callee->getIdentifier())
600602
return false;
601603

604+
bool IsAllowed = false;
602605
// libstdc++-11 introduced an undefined function "void __failed_assertion()"
603606
// which may lead to SemaSYCL check failure. However, this undefined function
604607
// is used to trigger some compilation error when the check fails at compile
605608
// time and will be ignored when the check succeeds. We allow calls to this
606609
// function to support some important std functions in SYCL device.
607-
return (Callee->getName() == LibstdcxxFailedAssertion) &&
608-
Callee->getNumParams() == 0 && Callee->getReturnType()->isVoidType() &&
609-
SrcMgr.isInSystemHeader(Callee->getLocation());
610+
IsAllowed = (Callee->getName() == LibstdcxxFailedAssertion) &&
611+
Callee->getNumParams() == 0 &&
612+
Callee->getReturnType()->isVoidType() &&
613+
SrcMgr.isInSystemHeader(Callee->getLocation());
614+
615+
if (IsAllowed)
616+
return true;
617+
618+
// GCC-15 introduced "std::__glibcxx_assert_fail" declared c++config.h and
619+
// extensively used in STL to do runtime check in debug mode. The behavior
620+
// is similar to "assert", we have supported it in libdevice in the same way
621+
// as "assert". However, Sema check will report "undefined function without
622+
// SYCL_EXTERNAL attribute" error in some cases. We have to allow it just as
623+
// what we did to "__failed_assertion". The prototype is following:
624+
// void __glibcxx_assert_fail(const char *, int, const char *, const char*);
625+
IsAllowed = (Callee->getName() == GlibcxxAssertFail) &&
626+
Callee->getNumParams() == 4 &&
627+
Callee->getReturnType()->isVoidType() &&
628+
SrcMgr.isInSystemHeader(Callee->getLocation());
629+
630+
return IsAllowed;
610631
}
611632

612633
// Helper function to report conflicting function attributes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
void __failed_assertion();
2+
namespace std {
3+
void __glibcxx_assert_fail(const char*, int, const char*, const char*) noexcept;
4+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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 "__glibcxx_assert_fail" 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+
namespace std {
10+
void __glibcxx_assert_fail(const char*, int, const char*, const char*) noexcept;
11+
// expected-note@-1 {{'__glibcxx_assert_fail' declared here}}
12+
}
13+
#else
14+
#include <dummy_failed_assert>
15+
#endif
16+
17+
#ifdef USR
18+
SYCL_EXTERNAL
19+
void call_glibcxx_assert_fail() {
20+
// expected-note@-1 {{called by 'call_glibcxx_assert_fail'}}
21+
std::__glibcxx_assert_fail("file1", 10, "func1", "dummy test");
22+
// expected-error@-1 {{SYCL kernel cannot call an undefined function without SYCL_EXTERNAL attribute}}
23+
}
24+
#else
25+
// expected-no-diagnostics
26+
SYCL_EXTERNAL
27+
void call_glibcxx_assert_fail() {
28+
std::__glibcxx_assert_fail("file1", 10, "func1", "dummy test");
29+
}
30+
#endif
31+

0 commit comments

Comments
 (0)