Skip to content

Commit 7240008

Browse files
committed
[Clang][CodeGen] __dynamic_cast should care about type_info's address space
`__dynamic_cast` relies on `type_info`, which its signature assumed to be in the generic / default address space. This patch corrects the oversight (we know that `type_info` resides in the GlobalVar address space) and adds an associated test. Reviewed By: yaxunl Differential Revision: https://reviews.llvm.org/D155870
1 parent 3ef766a commit 7240008

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,15 +1338,16 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
13381338

13391339
static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF) {
13401340
// void *__dynamic_cast(const void *sub,
1341-
// const abi::__class_type_info *src,
1342-
// const abi::__class_type_info *dst,
1341+
// global_as const abi::__class_type_info *src,
1342+
// global_as const abi::__class_type_info *dst,
13431343
// std::ptrdiff_t src2dst_offset);
13441344

13451345
llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
1346+
llvm::Type *GlobInt8PtrTy = CGF.GlobalsInt8PtrTy;
13461347
llvm::Type *PtrDiffTy =
13471348
CGF.ConvertType(CGF.getContext().getPointerDiffType());
13481349

1349-
llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
1350+
llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };
13501351

13511352
llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false);
13521353

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
2+
struct A { virtual void f(); };
3+
struct B : A { };
4+
5+
// CHECK: {{define.*@_Z1fP1A}}
6+
// CHECK-SAME: personality ptr @__gxx_personality_v0
7+
B fail;
8+
const B& f(A *a) {
9+
try {
10+
// CHECK: call ptr @__dynamic_cast
11+
// CHECK: br i1
12+
// CHECK: invoke void @__cxa_bad_cast() [[NR:#[0-9]+]]
13+
dynamic_cast<const B&>(*a);
14+
} catch (...) {
15+
// CHECK: landingpad { ptr, i32 }
16+
// CHECK-NEXT: catch ptr null
17+
}
18+
return fail;
19+
}
20+
21+
// CHECK: declare ptr @__dynamic_cast(ptr, ptr addrspace(1), ptr addrspace(1), i64) [[NUW_RO:#[0-9]+]]
22+
23+
// CHECK: attributes [[NUW_RO]] = { nounwind memory(read) }
24+
// CHECK: attributes [[NR]] = { noreturn }

0 commit comments

Comments
 (0)