Skip to content

Commit 45c33e9

Browse files
[SYCL] Don't emit @__cxa_pure_virtual into device code (#16231)
This special symbol is used to handling calls to pure virtual functions in regular C++ program. However, for SYCL device code we do not have a guarantee that this symbol will be provided by SYCL backend compilers. Considering that pure virtual function call is an undefined behavior anyway, this PR replaces `@__cxa_pure_virtual` uses with `null` during SYCL device compilation to avoid issues with unresolved symbols.
1 parent 773915f commit 45c33e9

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

clang/lib/CodeGen/CGVTables.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,12 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
803803
}
804804

805805
auto getSpecialVirtualFn = [&](StringRef name) -> llvm::Constant * {
806+
// There is no guarantee that special function for handling pure virtual
807+
// calls will be provided by a SYCL backend compiler and therefore we
808+
// simply emit nullptr here.
809+
if (CGM.getLangOpts().SYCLIsDevice)
810+
return llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy);
811+
806812
// FIXME(PR43094): When merging comdat groups, lld can select a local
807813
// symbol as the signature symbol even though it cannot be accessed
808814
// outside that symbol's TU. The relative vtables ABI would make
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// There is no guarantee that special symbol @__cxa_pure_virtual is supported
2+
// by SYCL backend compiler, so we need to make sure that we don't emit it
3+
// during SYCL device compilation.
4+
//
5+
// RUN: %clang_cc1 -triple spir64 -fsycl-is-device -emit-llvm %s -o - | FileCheck %s
6+
//
7+
// CHECK-NOT: @__cxa_pure_virtual
8+
9+
SYCL_EXTERNAL bool rand();
10+
11+
class Base {
12+
public:
13+
[[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "a")]]
14+
virtual void display() {}
15+
16+
virtual void pure_host() = 0;
17+
18+
[[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "a")]]
19+
virtual void pure_device() = 0;
20+
};
21+
22+
class Derived1 : public Base {
23+
public:
24+
[[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "a")]]
25+
void display() override {}
26+
27+
void pure_host() override {}
28+
29+
[[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "a")]]
30+
void pure_device() override {}
31+
};
32+
33+
SYCL_EXTERNAL void test() {
34+
Derived1 d1;
35+
Base *b = nullptr;
36+
if (rand())
37+
b = &d1;
38+
b->display();
39+
}
40+

0 commit comments

Comments
 (0)