diff options
Diffstat (limited to 'test/CodeGenCoroutines/coro-await.cpp')
-rw-r--r-- | test/CodeGenCoroutines/coro-await.cpp | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/test/CodeGenCoroutines/coro-await.cpp b/test/CodeGenCoroutines/coro-await.cpp index b0fd0129de34a..1e2deaa8f59a7 100644 --- a/test/CodeGenCoroutines/coro-await.cpp +++ b/test/CodeGenCoroutines/coro-await.cpp @@ -21,6 +21,17 @@ struct coroutine_handle : coroutine_handle<> { } } +struct init_susp { + bool await_ready(); + void await_suspend(std::experimental::coroutine_handle<>); + void await_resume(); +}; +struct final_susp { + bool await_ready(); + void await_suspend(std::experimental::coroutine_handle<>); + void await_resume(); +}; + struct suspend_always { int stuff; bool await_ready(); @@ -32,14 +43,22 @@ template<> struct std::experimental::coroutine_traits<void> { struct promise_type { void get_return_object(); - suspend_always initial_suspend(); - suspend_always final_suspend(); + init_susp initial_suspend(); + final_susp final_suspend(); void return_void(); }; }; // CHECK-LABEL: f0( extern "C" void f0() { + // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin( + + // See if initial_suspend was issued: + // ---------------------------------- + // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_type15initial_suspendEv( + // CHECK-NEXT: call zeroext i1 @_ZN9init_susp11await_readyEv(%struct.init_susp* + // CHECK: %[[INITSP_ID:.+]] = call token @llvm.coro.save( + // CHECK: call i8 @llvm.coro.suspend(token %[[INITSP_ID]], i1 false) co_await suspend_always{}; // See if we need to suspend: @@ -54,7 +73,6 @@ extern "C" void f0() { // --------------------------- // Build the coroutine handle and pass it to await_suspend // --------------------------- - // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame() // CHECK: call i8* @_ZNSt12experimental16coroutine_handleINS_16coroutine_traitsIJvEE12promise_typeEE12from_addressEPv(i8* %[[FRAME]]) // ... many lines of code to coerce coroutine_handle into an i8* scalar // CHECK: %[[CH:.+]] = load i8*, i8** %{{.+}} @@ -76,6 +94,13 @@ extern "C" void f0() { // -------------------------- // CHECK: [[READY_BB]]: // CHECK: call void @_ZN14suspend_always12await_resumeEv(%struct.suspend_always* %[[AWAITABLE]]) + + // See if final_suspend was issued: + // ---------------------------------- + // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_type13final_suspendEv( + // CHECK-NEXT: call zeroext i1 @_ZN10final_susp11await_readyEv(%struct.final_susp* + // CHECK: %[[FINALSP_ID:.+]] = call token @llvm.coro.save( + // CHECK: call i8 @llvm.coro.suspend(token %[[FINALSP_ID]], i1 true) } struct suspend_maybe { @@ -91,8 +116,8 @@ template<> struct std::experimental::coroutine_traits<void,int> { struct promise_type { void get_return_object(); - suspend_always initial_suspend(); - suspend_always final_suspend(); + init_susp initial_suspend(); + final_susp final_suspend(); void return_void(); suspend_maybe yield_value(int); }; @@ -100,8 +125,9 @@ struct std::experimental::coroutine_traits<void,int> { // CHECK-LABEL: f1( extern "C" void f1(int) { - co_yield 42; // CHECK: %[[PROMISE:.+]] = alloca %"struct.std::experimental::coroutine_traits<void, int>::promise_type" + // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin( + co_yield 42; // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJviEE12promise_type11yield_valueEi(%struct.suspend_maybe* sret %[[AWAITER:.+]], %"struct.std::experimental::coroutine_traits<void, int>::promise_type"* %[[PROMISE]], i32 42) // See if we need to suspend: @@ -116,7 +142,6 @@ extern "C" void f1(int) { // --------------------------- // Build the coroutine handle and pass it to await_suspend // --------------------------- - // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.frame() // CHECK: call i8* @_ZNSt12experimental16coroutine_handleINS_16coroutine_traitsIJviEE12promise_typeEE12from_addressEPv(i8* %[[FRAME]]) // ... many lines of code to coerce coroutine_handle into an i8* scalar // CHECK: %[[CH:.+]] = load i8*, i8** %{{.+}} @@ -228,3 +253,28 @@ extern "C" void TestOpAwait() { // CHECK: call void @_ZN5MyAggawEv(%struct.MyAgg* % // CHECK: call void @_ZN11AggrAwaiter12await_resumeEv(%struct.Aggr* sret % } + +// CHECK-LABEL: EndlessLoop( +extern "C" void EndlessLoop() { + // CHECK: %[[FRAME:.+]] = call i8* @llvm.coro.begin( + + // See if initial_suspend was issued: + // ---------------------------------- + // CHECK: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_type15initial_suspendEv( + // CHECK-NEXT: call zeroext i1 @_ZN9init_susp11await_readyEv(%struct.init_susp* + + for (;;) + co_await suspend_always{}; + + // Verify that final_suspend was NOT issued: + // ---------------------------------- + // CHECK-NOT: call void @_ZNSt12experimental16coroutine_traitsIJvEE12promise_type13final_suspendEv( + // CHECK-NOT: call zeroext i1 @_ZN10final_susp11await_readyEv(%struct.final_susp* +} + +// Verifies that we don't crash when awaiting on an lvalue. +// CHECK-LABEL: @_Z11AwaitLValuev( +void AwaitLValue() { + suspend_always lval; + co_await lval; +} |