diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp index 045fc27101357..6310349c469da 100644 --- a/clang/lib/CodeGen/CGVTables.cpp +++ b/clang/lib/CodeGen/CGVTables.cpp @@ -803,6 +803,12 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder, } auto getSpecialVirtualFn = [&](StringRef name) -> llvm::Constant * { + // There is no guarantee that special function for handling pure virtual + // calls will be provided by a SYCL backend compiler and therefore we + // simply emit nullptr here. + if (CGM.getLangOpts().SYCLIsDevice) + return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy); + // FIXME(PR43094): When merging comdat groups, lld can select a local // symbol as the signature symbol even though it cannot be accessed // outside that symbol's TU. The relative vtables ABI would make diff --git a/clang/test/CodeGenSYCL/dont-emit-cxx-pure-virtual.cpp b/clang/test/CodeGenSYCL/dont-emit-cxx-pure-virtual.cpp new file mode 100644 index 0000000000000..4bb19598b07a5 --- /dev/null +++ b/clang/test/CodeGenSYCL/dont-emit-cxx-pure-virtual.cpp @@ -0,0 +1,40 @@ +// There is no guarantee that special symbol @__cxa_pure_virtual is supported +// by SYCL backend compiler, so we need to make sure that we don't emit it +// during SYCL device compilation. +// +// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -emit-llvm %s -o - | FileCheck %s +// +// CHECK-NOT: @__cxa_pure_virtual + +SYCL_EXTERNAL bool rand(); + +class Base { +public: + [[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "a")]] + virtual void display() {} + + virtual void pure_host() = 0; + + [[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "a")]] + virtual void pure_device() = 0; +}; + +class Derived1 : public Base { +public: + [[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "a")]] + void display() override {} + + void pure_host() override {} + + [[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "a")]] + void pure_device() override {} +}; + +SYCL_EXTERNAL void test() { + Derived1 d1; + Base *b = nullptr; + if (rand()) + b = &d1; + b->display(); +} +