Skip to content

Commit c0eb128

Browse files
committed
[SYCL] Don't emit @__cxa_pure_virtual into device code
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 814290d commit c0eb128

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

clang/lib/CodeGen/CGVTables.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -831,9 +831,16 @@ void CodeGenVTables::addVTableComponent(ConstantArrayBuilder &builder,
831831

832832
// Pure virtual member functions.
833833
if (cast<CXXMethodDecl>(GD.getDecl())->isPureVirtual()) {
834-
if (!PureVirtualFn)
835-
PureVirtualFn =
836-
getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName());
834+
if (!PureVirtualFn) {
835+
// There is no guarantee that special function for handling pure virtual
836+
// calls will be provided by a SYCL backend compiler and therefore we
837+
// simply emit nullptr here.
838+
if (CGM.getLangOpts().SYCLIsDevice)
839+
PureVirtualFn = llvm::ConstantPointerNull::get(CGM.GlobalsInt8PtrTy);
840+
else
841+
PureVirtualFn =
842+
getSpecialVirtualFn(CGM.getCXXABI().GetPureVirtualCallName());
843+
}
837844
fnPtr = PureVirtualFn;
838845

839846
// Deleted virtual member functions.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// There ios no guarantee that special symbol @__cxa_pure_virtual is suppored
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)