Skip to content

Commit 2085978

Browse files
authored
[SYCL] Fix crash during search for undefined functions (#5342)
There was a crash if operator `new` was used inside recursive function or if undefined overloaded operator `new` was used inside random device code. The reason for crash is that `FunctionDecl` that represents operator `new` doesn't have a valid name in AST and `isSYCLUndefinedAllowed` checks it.
1 parent 652417b commit 2085978

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,10 @@ static bool isSYCLUndefinedAllowed(const FunctionDecl *Callee,
516516
if (!Callee)
517517
return false;
518518

519+
// The check below requires declaration name, make sure we have it.
520+
if (!Callee->getIdentifier())
521+
return false;
522+
519523
// libstdc++-11 introduced an undefined function "void __failed_assertion()"
520524
// which may lead to SemaSYCL check failure. However, this undefined function
521525
// is used to trigger some compilation error when the check fails at compile
@@ -4154,6 +4158,7 @@ void Sema::finalizeSYCLDelayedAnalysis(const FunctionDecl *Caller,
41544158
// Currently, there is an exception of "__failed_assertion" in libstdc++-11,
41554159
// this undefined function is used to trigger a compiling error.
41564160
if (!Callee->isDefined() && !Callee->getBuiltinID() &&
4161+
!Callee->isReplaceableGlobalAllocationFunction() &&
41574162
!isSYCLUndefinedAllowed(Callee, getSourceManager())) {
41584163
Diag(Loc, diag::err_sycl_restrict) << Sema::KernelCallUndefinedFunction;
41594164
Diag(Callee->getLocation(), diag::note_previous_decl) << Callee;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -sycl-std=2020 -verify -fsyntax-only %s
2+
3+
// This test makes sure that SemaSYCL doesn't crash and emits correct error
4+
// messages if operator new was used inside recursive function.
5+
6+
typedef __typeof__(sizeof(int)) size_t;
7+
8+
struct S {
9+
// expected-note@+1 {{'operator new' declared here}}
10+
void *operator new(size_t);
11+
};
12+
13+
// expected-note@+2 {{function implemented using recursion declared here}}
14+
// expected-note@+1 {{called by 'foo'}}
15+
__attribute__((sycl_device)) bool foo() {
16+
// expected-error@+1 {{SYCL kernel cannot call an undefined function without SYCL_EXTERNAL attribute}}
17+
S *P = new S();
18+
// expected-error@+1 {{SYCL kernel cannot allocate storage}}
19+
int *IP = new int;
20+
// expected-error@+1 {{SYCL kernel cannot call a recursive function}}
21+
foo();
22+
return true;
23+
}

0 commit comments

Comments
 (0)