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 @@ -4692,6 +4692,11 @@ fn->setDoesNotThrow(); fn->setDoesNotReturn(); + // Ensure stack traces can progress past this frame (e.g. for debuggers). + const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts(); + if (CodeGenOpts.UnwindTables) + fn->setUWTableKind(llvm::UWTableKind(CodeGenOpts.UnwindTables)); + // What we really want is to massively penalize inlining without // forbidding it completely. The difference between that and // 'noinline' is negligible. diff --git a/clang/test/CodeGenCXX/clang-call-terminate.uwtable.cpp b/clang/test/CodeGenCXX/clang-call-terminate.uwtable.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenCXX/clang-call-terminate.uwtable.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fexceptions -fcxx-exceptions -emit-llvm -o - %s | \ +// RUN: FileCheck --check-prefixes=CHECK,NOUNWIND %s +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fexceptions -fcxx-exceptions -funwind-tables=1 -emit-llvm -o - %s | \ +// RUN: FileCheck --check-prefixes=CHECK,SYNCUNWIND %s +// RUN: %clang_cc1 -triple=x86_64-linux-gnu -fexceptions -fcxx-exceptions -funwind-tables=2 -emit-llvm -o - %s | \ +// RUN: FileCheck --check-prefixes=CHECK,ASYNCUNWIND %s + +void caller(void callback()) noexcept { callback(); } + +// CHECK: define {{.*}}void @__clang_call_terminate({{[^)]*}}) #[[#ATTRNUM:]] +// CHECK: attributes #[[#ATTRNUM]] = { +// NOUNWIND-NOT: uwtable +// NOUNWIND-SAME: } +// SYNCUNWIND-SAME: uwtable(sync) +// ASYNCUNWIND-SAME: uwtable{{ }}