2022-04-07 18:03:55 +08:00
|
|
|
// RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++20 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s
|
2018-02-02 07:47:54 +08:00
|
|
|
|
|
|
|
#include "Inputs/coroutine.h"
|
|
|
|
|
2021-11-04 11:50:30 +08:00
|
|
|
using namespace std;
|
2018-02-02 07:47:54 +08:00
|
|
|
|
|
|
|
namespace std {
|
|
|
|
|
|
|
|
struct nothrow_t {};
|
|
|
|
constexpr nothrow_t nothrow = {};
|
|
|
|
|
|
|
|
} // end namespace std
|
|
|
|
|
|
|
|
// Required when get_return_object_on_allocation_failure() is defined by
|
|
|
|
// the promise.
|
|
|
|
void* operator new(__SIZE_TYPE__ __sz, const std::nothrow_t&) noexcept;
|
|
|
|
void operator delete(void* __p, const std::nothrow_t&) noexcept;
|
|
|
|
|
|
|
|
|
|
|
|
template <class RetObject>
|
|
|
|
struct promise_type {
|
|
|
|
RetObject get_return_object();
|
|
|
|
suspend_always initial_suspend();
|
[Coroutines] Ensure co_await promise.final_suspend() does not throw
Summary:
This patch addresses https://bugs.llvm.org/show_bug.cgi?id=46256
The spec of coroutine requires that the expression co_await promise.final_suspend() shall not be potentially-throwing.
To check this, we recursively look at every call (including Call, MemberCall, OperatorCall and Constructor) in all code
generated by the final suspend, and ensure that the callees are declared with noexcept. We also look at any returned data
type that requires explicit destruction, and check their destructors for noexcept.
This patch does not check declarations with dependent types yet, which will be done in future patches.
Updated all tests to add noexcept to the required functions, and added a dedicated test for this patch.
This patch might start to cause existing codebase fail to compile because most people may not have been strict in tagging
all the related functions noexcept.
Reviewers: lewissbaker, modocache, junparser
Reviewed By: modocache
Subscribers: arphaman, junparser, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82029
2020-06-16 07:27:41 +08:00
|
|
|
suspend_never final_suspend() noexcept;
|
2018-02-02 07:47:54 +08:00
|
|
|
void return_void();
|
|
|
|
static void unhandled_exception();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct coro {
|
|
|
|
using promise_type = promise_type<coro>;
|
|
|
|
coro(coro const&);
|
|
|
|
struct Impl;
|
|
|
|
Impl *impl;
|
|
|
|
};
|
|
|
|
|
2022-01-10 19:18:33 +08:00
|
|
|
// Verify that the RVO is applied.
|
2022-01-16 17:53:11 +08:00
|
|
|
// CHECK-LABEL: define{{.*}} void @_Z1fi(%struct.coro* noalias sret(%struct.coro) align 8 %agg.result, i32 noundef %0)
|
2018-02-02 07:47:54 +08:00
|
|
|
coro f(int) {
|
2022-01-16 17:53:11 +08:00
|
|
|
// CHECK: %call = call noalias noundef nonnull i8* @_Znwm(
|
2018-02-02 07:47:54 +08:00
|
|
|
// CHECK-NEXT: br label %[[CoroInit:.*]]
|
|
|
|
|
|
|
|
// CHECK: {{.*}}[[CoroInit]]:
|
2020-09-29 21:33:55 +08:00
|
|
|
// CHECK: call void @{{.*get_return_objectEv}}(%struct.coro* sret(%struct.coro) align 8 %agg.result
|
2022-01-10 19:18:33 +08:00
|
|
|
co_return;
|
2018-02-02 07:47:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <class RetObject>
|
|
|
|
struct promise_type_with_on_alloc_failure {
|
|
|
|
static RetObject get_return_object_on_allocation_failure();
|
|
|
|
RetObject get_return_object();
|
|
|
|
suspend_always initial_suspend();
|
[Coroutines] Ensure co_await promise.final_suspend() does not throw
Summary:
This patch addresses https://bugs.llvm.org/show_bug.cgi?id=46256
The spec of coroutine requires that the expression co_await promise.final_suspend() shall not be potentially-throwing.
To check this, we recursively look at every call (including Call, MemberCall, OperatorCall and Constructor) in all code
generated by the final suspend, and ensure that the callees are declared with noexcept. We also look at any returned data
type that requires explicit destruction, and check their destructors for noexcept.
This patch does not check declarations with dependent types yet, which will be done in future patches.
Updated all tests to add noexcept to the required functions, and added a dedicated test for this patch.
This patch might start to cause existing codebase fail to compile because most people may not have been strict in tagging
all the related functions noexcept.
Reviewers: lewissbaker, modocache, junparser
Reviewed By: modocache
Subscribers: arphaman, junparser, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D82029
2020-06-16 07:27:41 +08:00
|
|
|
suspend_never final_suspend() noexcept;
|
2018-02-02 07:47:54 +08:00
|
|
|
void return_void();
|
|
|
|
static void unhandled_exception();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct coro_two {
|
|
|
|
using promise_type = promise_type_with_on_alloc_failure<coro_two>;
|
|
|
|
coro_two(coro_two const&);
|
|
|
|
struct Impl;
|
|
|
|
Impl *impl;
|
|
|
|
};
|
|
|
|
|
2022-01-10 19:18:33 +08:00
|
|
|
// Verify that the RVO is applied.
|
2022-01-16 17:53:11 +08:00
|
|
|
// CHECK-LABEL: define{{.*}} void @_Z1hi(%struct.coro_two* noalias sret(%struct.coro_two) align 8 %agg.result, i32 noundef %0)
|
2022-01-10 19:18:33 +08:00
|
|
|
coro_two h(int) {
|
2018-02-02 07:47:54 +08:00
|
|
|
|
2022-01-10 19:18:33 +08:00
|
|
|
// CHECK: %call = call noalias noundef i8* @_ZnwmRKSt9nothrow_t
|
|
|
|
// CHECK-NEXT: %[[CheckNull:.*]] = icmp ne i8* %call, null
|
|
|
|
// CHECK-NEXT: br i1 %[[CheckNull]], label %[[InitOnSuccess:.*]], label %[[InitOnFailure:.*]]
|
2018-02-02 07:47:54 +08:00
|
|
|
|
2022-01-10 19:18:33 +08:00
|
|
|
// CHECK: {{.*}}[[InitOnFailure]]:
|
|
|
|
// CHECK-NEXT: call void @{{.*get_return_object_on_allocation_failureEv}}(%struct.coro_two* sret(%struct.coro_two) align 8 %agg.result
|
|
|
|
// CHECK-NEXT: br label %[[RetLabel:.*]]
|
2018-02-02 07:47:54 +08:00
|
|
|
|
2022-01-10 19:18:33 +08:00
|
|
|
// CHECK: {{.*}}[[InitOnSuccess]]:
|
|
|
|
// CHECK: call void @{{.*get_return_objectEv}}(%struct.coro_two* sret(%struct.coro_two) align 8 %agg.result
|
2018-02-02 07:47:54 +08:00
|
|
|
|
2022-01-10 19:18:33 +08:00
|
|
|
// CHECK: [[RetLabel]]:
|
|
|
|
// CHECK-NEXT: ret void
|
2018-02-02 07:47:54 +08:00
|
|
|
co_return;
|
|
|
|
}
|