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@+1 {{the return type of 'await_suspend' is required to be 'void' or 'bool' (have 'char')}} + // expected-error@+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@+1 {{the return type of 'await_ready' is required to be contextually convertible to 'bool'}} + // expected-note@+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@+2 {{return type of 'await_suspend' is required to be 'void' or 'bool' (have 'bool &')}} + // expected-error@+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 + } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits