This is an archive of the discontinued LLVM Phabricator instance.

[coroutines] Diagnose invalid result types for `await_resume` and `await_suspend` and add missing conversions.
ClosedPublic

Authored by EricWF on May 27 2017, 10:54 PM.

Details

Summary

The expression await_ready is required to be contextually convertible to bool and await_suspend must be a prvalue of either void or bool.
This patch adds diagnostics for when those requirements are violated.

It also correctly performs the contextual conversion to bool on the result of await_ready

Diff Detail

Event Timeline

EricWF created this revision.May 27 2017, 10:54 PM
EricWF updated this revision to Diff 100541.May 27 2017, 10:56 PM
  • Format changes
GorNishanov accepted this revision.May 28 2017, 6:42 AM

LGTM

test/SemaCXX/coroutines.cpp
842

For test completeness, I would have a positive case for something like a std::true_type returning await_ready

This revision is now accepted and ready to land.May 28 2017, 6:42 AM
GorNishanov added inline comments.May 28 2017, 6:42 AM
lib/Sema/SemaCoroutine.cpp
324

enum class?

EricWF marked an inline comment as done.May 28 2017, 11:17 AM
EricWF added inline comments.
lib/Sema/SemaCoroutine.cpp
324

We want the explicit conversion to integers so we can use them as indexes to Results.

EricWF updated this revision to Diff 100557.May 28 2017, 11:20 AM
  • Add requested test case.
EricWF closed this revision.May 28 2017, 11:21 AM
rsmith added inline comments.May 28 2017, 12:44 PM
include/clang/Basic/DiagnosticSemaKinds.td
8977–8980

I would drop the leading 'the' from both of these diagnostics for consistency with our normal terse sentence fragment style.

lib/Sema/SemaCoroutine.cpp
393

It looks like you're not checking the 'prvalue' part of this.

EricWF marked an inline comment as done.May 28 2017, 12:53 PM
EricWF added inline comments.
lib/Sema/SemaCoroutine.cpp
393

I thought so too. I'll add tests to make sure it's being handled correctly.
The following test should expose a lack of checking for prvalues, right?

template <class BoolTy>
struct TestAwait {
  bool await_ready();
  template <class F> BoolTy await_suspend(F); // expected-error
  void await_resume();
};
void test() {
  co_await TestAwait<bool&&>{};
  co_await TestAwait<bool&>{}; 
}