diff options
author | Gor Nishanov <GorNishanov@gmail.com> | 2017-05-22 22:33:17 +0000 |
---|---|---|
committer | Gor Nishanov <GorNishanov@gmail.com> | 2017-05-22 22:33:17 +0000 |
commit | a882e8619ffb19dd808e62f8c0f82ed73d0bff00 (patch) | |
tree | 7ec2c1f9b615020ed90f617faf6e121643d4135a /test/CodeGenCoroutines | |
parent | ecac99cbb4fc1411a821718d6c254333641c1198 (diff) | |
download | clang-a882e8619ffb19dd808e62f8c0f82ed73d0bff00.tar.gz |
[coroutines] Wrap the body of the coroutine in try-catch
Summary:
If unhandled_exception member function is present in the coroutine promise,
wrap the body of the coroutine in:
```
try {
body
} catch(...) { promise.unhandled_exception(); }
```
Reviewers: EricWF, rnk, rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D31692
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303583 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCoroutines')
-rw-r--r-- | test/CodeGenCoroutines/coro-cleanup.cpp | 59 | ||||
-rw-r--r-- | test/CodeGenCoroutines/coro-eh-cleanup.cpp | 16 |
2 files changed, 55 insertions, 20 deletions
diff --git a/test/CodeGenCoroutines/coro-cleanup.cpp b/test/CodeGenCoroutines/coro-cleanup.cpp index 7f6f35cfe2..519282e2b6 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 @@ -52,19 +52,34 @@ void f() { // 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: [[PromDtorPad]]: - // CHECK-NEXT: landingpad - // CHECK-NEXT: cleanup - // CHECK: call void @_ZN7CleanupD1Ev(%struct.Cleanup* + // CHECK: [[CatchPad]]: + // CHECK-NEXT: landingpad + // CHECK-NEXT: catch i8* null + // CHECK: call void @_ZN7CleanupD1Ev( + // CHECK: br label %[[Catch:.+]] + + // 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 +} diff --git a/test/CodeGenCoroutines/coro-eh-cleanup.cpp b/test/CodeGenCoroutines/coro-eh-cleanup.cpp index 578d57fbab..901ed54923 100644 --- a/test/CodeGenCoroutines/coro-eh-cleanup.cpp +++ b/test/CodeGenCoroutines/coro-eh-cleanup.cpp @@ -51,7 +51,13 @@ coro_t f() { // CHECK: [[EHCLEANUP]]: // CHECK: %[[INNERPAD:.+]] = cleanuppad within none [] // CHECK: call void @"\01??_DCleanup@@QEAAXXZ"( -// CHECK: cleanupret from %[[INNERPAD]] unwind label %[[COROENDBB:.+]] +// CHECK: cleanupret from %4 unwind label %[[CATCHDISPATCH:.+]] + +// CHECK: [[CATCHDISPATCH]]: +// CHECK: catchswitch within none [label %[[CATCHPAD:.+]]] unwind label %[[COROENDBB:.+]] +// CHECK: [[CATCHPAD]]: +// CHECK: call void @"\01?unhandled_exception@promise_type@coro_t@@QEAAXXZ" + // CHECK: [[COROENDBB]]: // CHECK-NEXT: %[[CLPAD:.+]] = cleanuppad within none // CHECK-NEXT: call i1 @llvm.coro.end(i8* null, i1 true) [ "funclet"(token %[[CLPAD]]) ] @@ -62,8 +68,14 @@ coro_t f() { // CHECK-LPAD: to label %[[CONT:.+]] unwind label %[[EHCLEANUP:.+]] // CHECK-LPAD: [[EHCLEANUP]]: // CHECK-LPAD: landingpad { i8*, i32 } -// CHECK-LPAD: cleanup +// CHECK-LPAD: catch // CHECK-LPAD: call void @_ZN7CleanupD1Ev( +// CHECK-LPAD: call i8* @__cxa_begin_catch +// CHECK-LPAD: call void @_ZN6coro_t12promise_type19unhandled_exceptionEv +// CHECK-LPAD: invoke void @__cxa_end_catch() +// CHECK-LPAD: to label %{{.+}} unwind label %[[UNWINDBB:.+]] + +// CHECK-LPAD: [[UNWINDBB]]: // CHECK-LPAD: %[[I1RESUME:.+]] = call i1 @llvm.coro.end(i8* null, i1 true) // CHECK-LPAD: br i1 %[[I1RESUME]], label %[[EHRESUME:.+]], label // CHECK-LPAD: [[EHRESUME]]: |