Author: Yingwei Zheng Date: 2024-02-04T11:31:50+08:00 New Revision: a3d8b78333b80b47209ad0dc8f8159d70c7fcb39
URL: https://github.com/llvm/llvm-project/commit/a3d8b78333b80b47209ad0dc8f8159d70c7fcb39 DIFF: https://github.com/llvm/llvm-project/commit/a3d8b78333b80b47209ad0dc8f8159d70c7fcb39.diff LOG: [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. Added: clang/test/CodeGenCXX/dynamic-cast-dead.cpp Modified: clang/lib/CodeGen/ItaniumCXXABI.cpp clang/test/CodeGenCXX/dynamic-cast-address-space.cpp clang/test/CodeGenCXX/dynamic-cast.cpp Removed: ################################################################################ diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index d173806ec8ce5..60b45ee78d931 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1347,9 +1347,10 @@ static llvm::FunctionCallee getItaniumDynamicCastFn(CodeGenFunction &CGF) { llvm::FunctionType *FTy = llvm::FunctionType::get(Int8PtrTy, Args, false); - // Mark the function as nounwind readonly. + // Mark the function as nounwind willreturn readonly. llvm::AttrBuilder FuncAttrs(CGF.getLLVMContext()); FuncAttrs.addAttribute(llvm::Attribute::NoUnwind); + FuncAttrs.addAttribute(llvm::Attribute::WillReturn); FuncAttrs.addMemoryAttr(llvm::MemoryEffects::readOnly()); llvm::AttributeList Attrs = llvm::AttributeList::get( CGF.getLLVMContext(), llvm::AttributeList::FunctionIndex, FuncAttrs); diff --git a/clang/test/CodeGenCXX/dynamic-cast-address-space.cpp b/clang/test/CodeGenCXX/dynamic-cast-address-space.cpp index c278988c9647b..83a408984b760 100644 --- a/clang/test/CodeGenCXX/dynamic-cast-address-space.cpp +++ b/clang/test/CodeGenCXX/dynamic-cast-address-space.cpp @@ -20,5 +20,5 @@ const B& f(A *a) { // 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 [[NUW_RO]] = { nounwind willreturn memory(read) } // CHECK: attributes [[NR]] = { noreturn } diff --git a/clang/test/CodeGenCXX/dynamic-cast-dead.cpp b/clang/test/CodeGenCXX/dynamic-cast-dead.cpp new file mode 100644 index 0000000000000..8154cc1ba123a --- /dev/null +++ b/clang/test/CodeGenCXX/dynamic-cast-dead.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -I%S %s -O3 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s +struct A { virtual ~A(); }; +struct B : A { }; + +void foo(A* a) { + // CHECK-NOT: call {{.*}} @__dynamic_cast + B* b = dynamic_cast<B*>(a); +} diff --git a/clang/test/CodeGenCXX/dynamic-cast.cpp b/clang/test/CodeGenCXX/dynamic-cast.cpp index 1d36376a55bc7..b39186c85b60a 100644 --- a/clang/test/CodeGenCXX/dynamic-cast.cpp +++ b/clang/test/CodeGenCXX/dynamic-cast.cpp @@ -20,5 +20,5 @@ const B& f(A *a) { // CHECK: declare ptr @__dynamic_cast(ptr, ptr, ptr, i64) [[NUW_RO:#[0-9]+]] -// CHECK: attributes [[NUW_RO]] = { nounwind memory(read) } +// CHECK: attributes [[NUW_RO]] = { nounwind willreturn memory(read) } // CHECK: attributes [[NR]] = { noreturn } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits