diff options
Diffstat (limited to 'test/CodeGenCoroutines/coro-cleanup.cpp')
-rw-r--r-- | test/CodeGenCoroutines/coro-cleanup.cpp | 67 |
1 files changed, 45 insertions, 22 deletions
diff --git a/test/CodeGenCoroutines/coro-cleanup.cpp b/test/CodeGenCoroutines/coro-cleanup.cpp index 7f6f35cfe26c4..ba1246979e522 100644 --- a/test/CodeGenCoroutines/coro-cleanup.cpp +++ b/test/CodeGenCoroutines/coro-cleanup.cpp @@ -6,38 +6,38 @@ template <typename... T> struct coroutine_traits; template <class Promise = void> struct coroutine_handle { coroutine_handle() = default; - static coroutine_handle from_address(void *) { return {}; } + static coroutine_handle from_address(void *) noexcept; }; template <> struct coroutine_handle<void> { - static coroutine_handle from_address(void *) { return {}; } + static coroutine_handle from_address(void *) noexcept; coroutine_handle() = default; template <class PromiseType> - coroutine_handle(coroutine_handle<PromiseType>) {} + coroutine_handle(coroutine_handle<PromiseType>) noexcept; }; } struct suspend_always { - bool await_ready(); - void await_suspend(std::experimental::coroutine_handle<>); - void await_resume(); + bool await_ready() noexcept; + void await_suspend(std::experimental::coroutine_handle<>) noexcept; + void await_resume() noexcept; }; template <> struct std::experimental::coroutine_traits<void> { struct promise_type { - void get_return_object(); - suspend_always initial_suspend(); - suspend_always final_suspend(); - void return_void(); + void get_return_object() noexcept; + suspend_always initial_suspend() noexcept; + suspend_always final_suspend() noexcept; + void return_void() noexcept; promise_type(); ~promise_type(); - void unhandled_exception(); + void unhandled_exception() noexcept; }; }; struct Cleanup { ~Cleanup(); }; void may_throw(); -// CHECK: define void @_Z1fv( +// CHECK-LABEL: define void @_Z1fv( void f() { // CHECK: call i8* @_Znwm(i64 @@ -46,25 +46,40 @@ void f() { // CHECK: invoke void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_typeC1Ev( // CHECK-NEXT: to label %{{.+}} unwind label %[[DeallocPad:.+]] + // CHECK: [[DeallocPad]]: + // CHECK-NEXT: landingpad + // CHECK-NEXT: cleanup + // CHECK: br label %[[Dealloc:.+]] + Cleanup cleanup; may_throw(); // if may_throw throws, check that we destroy the promise and free the memory. // CHECK: invoke void @_Z9may_throwv( - // CHECK-NEXT: to label %{{.+}} unwind label %[[PromDtorPad:.+]] + // CHECK-NEXT: to label %{{.+}} unwind label %[[CatchPad:.+]] - // CHECK: [[DeallocPad]]: - // CHECK-NEXT: landingpad - // CHECK-NEXT: cleanup - // CHECK: br label %[[Dealloc:.+]] + // CHECK: [[CatchPad]]: + // CHECK-NEXT: landingpad + // CHECK-NEXT: catch i8* null + // CHECK: call void @_ZN7CleanupD1Ev( + // CHECK: br label %[[Catch:.+]] - // CHECK: [[PromDtorPad]]: - // CHECK-NEXT: landingpad - // CHECK-NEXT: cleanup - // CHECK: call void @_ZN7CleanupD1Ev(%struct.Cleanup* + // CHECK: [[Catch]]: + // CHECK: call i8* @__cxa_begin_catch( + // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_type19unhandled_exceptionEv( + // CHECK: invoke void @__cxa_end_catch() + // CHECK-NEXT: to label %[[Cont:.+]] unwind + + // CHECK: [[Cont]]: + // CHECK-NEXT: br label %[[Cont2:.+]] + // CHECK: [[Cont2]]: + // CHECK-NEXT: br label %[[Cleanup:.+]] + + // CHECK: [[Cleanup]]: // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_typeD1Ev( - // CHECK: br label %[[Dealloc]] + // CHECK: %[[Mem0:.+]] = call i8* @llvm.coro.free( + // CHECK: call void @_ZdlPv(i8* %[[Mem0]] // CHECK: [[Dealloc]]: // CHECK: %[[Mem:.+]] = call i8* @llvm.coro.free( @@ -72,3 +87,11 @@ void f() { co_return; } + +// CHECK-LABEL: define void @_Z1gv( +void g() { + for (;;) + co_await suspend_always{}; + // Since this is the endless loop there should be no fallthrough handler (call to 'return_void'). + // CHECK-NOT: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_type11return_voidEv +} |