diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -4393,7 +4393,12 @@ llvm::FunctionType *FTy = llvm::FunctionType::get( CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false); - return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch"); + // Set nounwind so that a function with all non-nounwind callees surrounded by + // catch (...) can infer nounwind, which can avoid unneded call site records. + llvm::FunctionCallee Ret = + CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch"); + cast(Ret.getCallee())->addFnAttr(llvm::Attribute::NoUnwind); + return Ret; } static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) { @@ -4401,7 +4406,9 @@ llvm::FunctionType *FTy = llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false); - return CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch"); + llvm::FunctionCallee Ret = CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch"); + cast(Ret.getCallee())->addFnAttr(llvm::Attribute::NoUnwind); + return Ret; } static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM) { diff --git a/clang/test/CodeGenCXX/exceptions.cpp b/clang/test/CodeGenCXX/exceptions.cpp --- a/clang/test/CodeGenCXX/exceptions.cpp +++ b/clang/test/CodeGenCXX/exceptions.cpp @@ -326,9 +326,12 @@ } } +// CHECK11-LABEL: declare{{.*}} i8* @__cxa_begin_catch(i8*) #[[#NOUNWIND:]] + // PR9303: invalid assert on this namespace test6 { bool cond(); + // CHECK11-LABEL: define{{.*}} void @_ZN5test64testEv() #[[#TEST6:]] void test() { try { lbl: @@ -634,3 +637,6 @@ } // CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind } + +// CHECK11: attributes #[[#NOUNWIND]] = { nounwind } +// CHECK11: attributes #[[#TEST6]] = {{.*}} nounwind diff --git a/clang/test/CodeGenCXX/stack-reuse-exceptions.cpp b/clang/test/CodeGenCXX/stack-reuse-exceptions.cpp --- a/clang/test/CodeGenCXX/stack-reuse-exceptions.cpp +++ b/clang/test/CodeGenCXX/stack-reuse-exceptions.cpp @@ -86,8 +86,8 @@ // // CHECK: [[CATCH]]: // CHECK-NOT: call void @llvm.lifetime -// CHECK: invoke void -// CHECK-NEXT: to label %[[TRY_CONT]] unwind label %[[OUTER_LPAD:.+]] +// CHECK: call void @__cxa_end_catch +// CHECK-NEXT: br label %[[TRY_CONT]] // // CHECK: [[TRY_CONT]]: // CHECK: %[[T_OUTER:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8* @@ -100,15 +100,7 @@ // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]]) // CHECK: ret void // -// CHECK: [[OUTER_LPAD]]: -// CHECK-NOT: call void @llvm.lifetime -// CHECK: br label %[[EHCLEANUP:.+]] -// -// CHECK: [[OUTER_LPAD2]]: -// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T_OUTER]]) -// CHECK: br label %[[EHCLEANUP]] -// -// CHECK: [[EHCLEANUP]]: +// CHECK: lpad[[#]]: // CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]]) NontrivialDtor clean;