r304373 - [coroutines] Fix checking for prvalue-ness of `await_suspend` return type
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Wed May 31 16:41:11 PDT 2017
Author: ericwf
Date: Wed May 31 18:41:11 2017
New Revision: 304373
URL: http://llvm.org/viewvc/llvm-project?rev=304373&view=rev
Log:
[coroutines] Fix checking for prvalue-ness of `await_suspend` return type
Summary:
@rsmith Does this correctly address the issues mentioned in https://reviews.llvm.org/D33625#inline-292971 ?
Reviewers: rsmith, EricWF
Reviewed By: EricWF
Subscribers: cfe-commits, rsmith
Differential Revision: https://reviews.llvm.org/D33636
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaCoroutine.cpp
cfe/trunk/test/SemaCXX/coroutines.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=304373&r1=304372&r2=304373&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed May 31 18:41:11 2017
@@ -8979,10 +8979,10 @@ def err_coroutine_promise_new_requires_n
def note_coroutine_promise_call_implicitly_required : Note<
"call to %0 implicitly required by coroutine function here">;
def err_await_suspend_invalid_return_type : Error<
- "the return type of 'await_suspend' is required to be 'void' or 'bool' (have %0)"
+ "return type of 'await_suspend' is required to be 'void' or 'bool' (have %0)"
>;
def note_await_ready_no_bool_conversion : Note<
- "the return type of 'await_ready' is required to be contextually convertible to 'bool'"
+ "return type of 'await_ready' is required to be contextually convertible to 'bool'"
>;
}
Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=304373&r1=304372&r2=304373&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Wed May 31 18:41:11 2017
@@ -391,8 +391,11 @@ static ReadySuspendResumeResult buildCoa
// [expr.await]p3 [...]
// - await-suspend is the expression e.await_suspend(h), which shall be
// a prvalue of type void or bool.
- QualType RetType = AwaitSuspend->getType();
- if (RetType != S.Context.BoolTy && RetType != S.Context.VoidTy) {
+ QualType RetType = AwaitSuspend->getCallReturnType(S.Context);
+ // non-class prvalues always have cv-unqualified types
+ QualType AdjRetType = RetType.getUnqualifiedType();
+ if (RetType->isReferenceType() ||
+ (AdjRetType != S.Context.BoolTy && AdjRetType != S.Context.VoidTy)) {
S.Diag(AwaitSuspend->getCalleeDecl()->getLocation(),
diag::err_await_suspend_invalid_return_type)
<< RetType;
Modified: cfe/trunk/test/SemaCXX/coroutines.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/coroutines.cpp?rev=304373&r1=304372&r2=304373&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/coroutines.cpp (original)
+++ cfe/trunk/test/SemaCXX/coroutines.cpp Wed May 31 18:41:11 2017
@@ -840,12 +840,12 @@ coro<bad_promise_no_return_func> no_retu
struct bad_await_suspend_return {
bool await_ready();
- // expected-error at +1 {{the return type of 'await_suspend' is required to be 'void' or 'bool' (have 'char')}}
+ // expected-error at +1 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'char')}}
char await_suspend(std::experimental::coroutine_handle<>);
void await_resume();
};
struct bad_await_ready_return {
- // expected-note at +1 {{the return type of 'await_ready' is required to be contextually convertible to 'bool'}}
+ // expected-note at +1 {{return type of 'await_ready' is required to be contextually convertible to 'bool'}}
void await_ready();
bool await_suspend(std::experimental::coroutine_handle<>);
void await_resume();
@@ -858,6 +858,14 @@ struct await_ready_explicit_bool {
void await_suspend(std::experimental::coroutine_handle<>);
void await_resume();
};
+template <class SuspendTy>
+struct await_suspend_type_test {
+ bool await_ready();
+ // expected-error at +2 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'bool &')}}
+ // expected-error at +1 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'bool &&')}}
+ SuspendTy await_suspend(std::experimental::coroutine_handle<>);
+ void await_resume();
+};
void test_bad_suspend() {
{
// FIXME: The actual error emitted here is terrible, and no number of notes can save it.
@@ -873,4 +881,14 @@ void test_bad_suspend() {
await_ready_explicit_bool c;
co_await c; // OK
}
+ {
+ await_suspend_type_test<bool &&> a;
+ await_suspend_type_test<bool &> b;
+ await_suspend_type_test<const void> c;
+ await_suspend_type_test<const volatile bool> d;
+ co_await a; // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
+ co_await b; // expected-note {{call to 'await_suspend' implicitly required by coroutine function here}}
+ co_await c; // OK
+ co_await d; // OK
+ }
}
More information about the cfe-commits
mailing list