noexcept functions push an EHTerminateScope onto the cleanup stack. The musttail codegen did not know how to skip this scope, causing a "cannot compile this tail call skipping over cleanups yet" error even when both caller and callee are noexcept. Skip the EHTerminateScope when the callee is nounwind (noexcept). The callee's own noexcept handler prevents any exception from propagating, so the caller's terminate handler is unnecessary. Fixes #53087.
35 lines
1.2 KiB
C++
35 lines
1.2 KiB
C++
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s
|
|
|
|
// musttail in noexcept functions should work when the callee is also noexcept.
|
|
|
|
int NoexceptCallee(int) noexcept;
|
|
int ThrowingFunc(int);
|
|
|
|
// CHECK-LABEL: define {{.*}} @_Z12TestNoexcepti(
|
|
// CHECK: musttail call {{.*}} @_Z14NoexceptCalleei(
|
|
// CHECK-NEXT: ret i32
|
|
int TestNoexcept(int x) noexcept {
|
|
[[clang::musttail]] return NoexceptCallee(x);
|
|
}
|
|
|
|
// Noexcept caller with regular call to non-noexcept, then musttail to noexcept.
|
|
// CHECK-LABEL: define {{.*}} @_Z21TestMixedCallNoexcepti(
|
|
// CHECK: invoke {{.*}} @_Z12ThrowingFunci(
|
|
// CHECK-NEXT: to label %{{.*}} unwind label %terminate.lpad
|
|
// CHECK: musttail call {{.*}} @_Z14NoexceptCalleei(
|
|
// CHECK-NEXT: ret i32
|
|
// CHECK: terminate.lpad:
|
|
// CHECK: call void @__clang_call_terminate(
|
|
int TestMixedCallNoexcept(int x) noexcept {
|
|
int y = ThrowingFunc(x);
|
|
[[clang::musttail]] return NoexceptCallee(y);
|
|
}
|
|
|
|
// Noexcept caller musttails to itself (recursive).
|
|
// CHECK-LABEL: define {{.*}} @_Z13TestRecursivei(
|
|
// CHECK: musttail call {{.*}} @_Z13TestRecursivei(
|
|
// CHECK-NEXT: ret i32
|
|
int TestRecursive(int x) noexcept {
|
|
[[clang::musttail]] return TestRecursive(x);
|
|
}
|