Skip to content

Commit a3d8b78

Browse files
authored
[Clang][CodeGen] Mark __dynamic_cast as willreturn (#80409)
According to the C++ standard, `dynamic_cast` of pointers either returns a pointer (7.6.1.7) or results in undefined behavior (11.9.5). This patch marks `__dynamic_cast` as `willreturn` to remove unused calls. Fixes #77606.
1 parent f2cf8da commit a3d8b78

File tree

4 files changed

+12
-3
lines changed

4 files changed

+12
-3
lines changed

clang/lib/CodeGen/ItaniumCXXABI.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1347,9 +1347,10 @@ static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF) {
13471347

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

1350-
// Mark the function as nounwind readonly.
1350+
// Mark the function as nounwind willreturn readonly.
13511351
llvm::AttrBuilder FuncAttrs(CGF.getLLVMContext());
13521352
FuncAttrs.addAttribute(llvm::Attribute::NoUnwind);
1353+
FuncAttrs.addAttribute(llvm::Attribute::WillReturn);
13531354
FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly());
13541355
llvm::AttributeList Attrs = llvm::AttributeList::get(
13551356
CGF.getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs);

clang/test/CodeGenCXX/dynamic-cast-address-space.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ const B& f(A *a) {
2020

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

23-
// CHECK: attributes [[NUW_RO]] = { nounwind memory(read) }
23+
// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read) }
2424
// CHECK: attributes [[NR]] = { noreturn }
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang_cc1 -I%S %s -O3 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s
2+
struct A { virtual ~A(); };
3+
struct B : A { };
4+
5+
void foo(A* a) {
6+
// CHECK-NOT: call {{.*}} @__dynamic_cast
7+
B* b = dynamic_cast<B*>(a);
8+
}

clang/test/CodeGenCXX/dynamic-cast.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ const B& f(A *a) {
2020

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

23-
// CHECK: attributes [[NUW_RO]] = { nounwind memory(read) }
23+
// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read) }
2424
// CHECK: attributes [[NR]] = { noreturn }

0 commit comments

Comments
 (0)