Skip to content

Commit

Permalink
[Clang][CodeGen] __dynamic_cast should care about type_info's add…
Browse files Browse the repository at this point in the history
…ress 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
  • Loading branch information
AlexVlx committed Aug 3, 2023
1 parent 3ef766a commit 7240008
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
7 changes: 4 additions & 3 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1338,15 +1338,16 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {

static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF) {
// void *__dynamic_cast(const void *sub,
// const abi::__class_type_info *src,
// const abi::__class_type_info *dst,
// global_as const abi::__class_type_info *src,
// global_as const abi::__class_type_info *dst,
// std::ptrdiff_t src2dst_offset);

llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
llvm::Type *GlobInt8PtrTy = CGF.GlobalsInt8PtrTy;
llvm::Type *PtrDiffTy =
CGF.ConvertType(CGF.getContext().getPointerDiffType());

llvm::Type *Args[4] = { Int8PtrTy, Int8PtrTy, Int8PtrTy, PtrDiffTy };
llvm::Type *Args[4] = { Int8PtrTy, GlobInt8PtrTy, GlobInt8PtrTy, PtrDiffTy };

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

Expand Down
24 changes: 24 additions & 0 deletions clang/test/CodeGenCXX/dynamic-cast-address-space.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// RUN: %clang_cc1 -I%S %s -triple amdgcn-amd-amdhsa -emit-llvm -fcxx-exceptions -fexceptions -o - | FileCheck %s
struct A { virtual void f(); };
struct B : A { };

// CHECK: {{define.*@_Z1fP1A}}
// CHECK-SAME: personality ptr @__gxx_personality_v0
B fail;
const B& f(A *a) {
try {
// CHECK: call ptr @__dynamic_cast
// CHECK: br i1
// CHECK: invoke void @__cxa_bad_cast() [[NR:#[0-9]+]]
dynamic_cast<const B&>(*a);
} catch (...) {
// CHECK: landingpad { ptr, i32 }
// CHECK-NEXT: catch ptr null
}
return fail;
}

// CHECK: declare ptr @__dynamic_cast(ptr, ptr addrspace(1), ptr addrspace(1), i64) [[NUW_RO:#[0-9]+]]

// CHECK: attributes [[NUW_RO]] = { nounwind memory(read) }
// CHECK: attributes [[NR]] = { noreturn }

0 comments on commit 7240008

Please sign in to comment.