| // 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); |
| } |