diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 491d77c7dc502..e59200cfdd657 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1457,6 +1457,11 @@ static ExprResult TransformUniqueStableName(TemplateInstantiator &TI, TI.getSema(), Sema::ExpressionEvaluationContext::Unevaluated); ExprResult SubExpr = TI.getDerived().TransformExpr(E->getExpr()); + if (SubExpr.isInvalid()) + return ExprError(); + + SubExpr = TI.getSema().CheckPlaceholderExpr(SubExpr.get()); + if (SubExpr.isInvalid()) return ExprError(); diff --git a/clang/test/CodeGenSYCL/unique-stable-name-placeholder-crash.cpp b/clang/test/CodeGenSYCL/unique-stable-name-placeholder-crash.cpp new file mode 100644 index 0000000000000..ba28e35ae00af --- /dev/null +++ b/clang/test/CodeGenSYCL/unique-stable-name-placeholder-crash.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple spir64-unknown-unknown-sycldevice -internal-isystem %S/Inputs -std=c++17 -sycl-std=2020 -fsycl -fsycl-is-device -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s + +#include + +using namespace cl::sycl; + +struct A { + int a = 0; + A() = default; +}; +constexpr A THE_NAME; + +template void temp() {} +template void foo(const char *out) { + out = __builtin_unique_stable_name(temp); +} + +int main() { + kernel_single_task( + []() { + const char *c; + foo(c); + }); +} + +// Note: the mangling here is actually the 'typeinfo name for void ()'. That is +// because the type of temp is actually the function type (which is void()). +// CHECK: @__builtin_unique_stable_name._Z3fooIL_ZL8THE_NAMEEEvPKc = private unnamed_addr addrspace(1) constant [9 x i8] c"_ZTSFvvE\00", align 1