summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGor Nishanov <GorNishanov@gmail.com>2017-09-05 19:31:52 +0000
committerGor Nishanov <GorNishanov@gmail.com>2017-09-05 19:31:52 +0000
commitdb419a6f7c13393c2f1b2ed4b6ed4148839263d1 (patch)
treea2a15344c458e74d9fc8e89a32be6e9e0265bbbe
parent784fa8a4e30a6a70a09a1d8008515b43e00104d7 (diff)
downloadbcm5719-llvm-db419a6f7c13393c2f1b2ed4b6ed4148839263d1.tar.gz
bcm5719-llvm-db419a6f7c13393c2f1b2ed4b6ed4148839263d1.zip
[coroutines] Make sure auto return type of await_resume is properly handled
Reviewers: rsmith, EricWF Reviewed By: rsmith Subscribers: javed.absar, cfe-commits Differential Revision: https://reviews.llvm.org/D37454 llvm-svn: 312565
-rw-r--r--clang/lib/Sema/SemaCoroutine.cpp4
-rw-r--r--clang/test/SemaCXX/coroutines.cpp10
2 files changed, 12 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index ae8744c07ba..e6b640f878c 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -438,14 +438,14 @@ static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise,
// - await-suspend is the expression e.await_suspend(h), which shall be
// a prvalue of type void or bool.
QualType RetType = AwaitSuspend->getCallReturnType(S.Context);
+
// Experimental support for coroutine_handle returning await_suspend.
if (Expr *TailCallSuspend = maybeTailCall(S, RetType, AwaitSuspend, Loc))
Calls.Results[ACT::ACT_Suspend] = TailCallSuspend;
else {
// non-class prvalues always have cv-unqualified types
- QualType AdjRetType = RetType.getUnqualifiedType();
if (RetType->isReferenceType() ||
- (AdjRetType != S.Context.BoolTy && AdjRetType != S.Context.VoidTy)) {
+ (!RetType->isBooleanType() && !RetType->isVoidType())) {
S.Diag(AwaitSuspend->getCalleeDecl()->getLocation(),
diag::err_await_suspend_invalid_return_type)
<< RetType;
diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp
index 6394829f356..65e17abb11f 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -66,6 +66,12 @@ struct suspend_never {
void await_resume() {}
};
+struct auto_await_suspend {
+ bool await_ready();
+ template <typename F> auto await_suspend(F) {}
+ void await_resume();
+};
+
struct DummyVoidTag {};
DummyVoidTag no_specialization() { // expected-error {{this function cannot be a coroutine: 'std::experimental::coroutine_traits<DummyVoidTag>' has no member named 'promise_type'}}
co_await a;
@@ -159,6 +165,10 @@ void yield() {
co_yield yield; // expected-error {{no member named 'await_ready' in 'not_awaitable'}}
}
+void check_auto_await_suspend() {
+ co_await auto_await_suspend{}; // Should compile successfully.
+}
+
void coreturn(int n) {
co_await a;
if (n == 0)
OpenPOWER on IntegriCloud