// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts \ // RUN: -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify \ // RUN: -fblocks #include "Inputs/std-coroutine.h" using namespace std::experimental; template struct Awaiter { bool await_ready(); void await_suspend(coroutine_handle<>); Begin await_resume(); }; template struct BeginTag { BeginTag() = delete; }; template struct IncTag { IncTag() = delete; }; template struct CoawaitTag { CoawaitTag() = delete; }; template struct Iter { using value_type = T; using reference = T &; using pointer = T *; IncTag operator++(); reference operator*(); pointer operator->(); }; template bool operator==(Iter, Iter); template bool operator!=(Iter, Iter); template struct Range { BeginTag> begin(); Iter end(); }; struct MyForLoopArrayAwaiter { struct promise_type { MyForLoopArrayAwaiter get_return_object() { return {}; } void return_void(); void unhandled_exception(); suspend_never initial_suspend(); suspend_never final_suspend(); template Awaiter await_transform(T *) = delete; // expected-note {{explicitly deleted}} }; }; MyForLoopArrayAwaiter g() { int arr[10] = {0}; for co_await(auto i : arr) {} // expected-error@-1 {{call to deleted member function 'await_transform'}} // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} } struct ForLoopAwaiterBadBeginTransform { struct promise_type { ForLoopAwaiterBadBeginTransform get_return_object(); void return_void(); void unhandled_exception(); suspend_never initial_suspend(); suspend_never final_suspend(); template Awaiter await_transform(BeginTag) = delete; // expected-note 1+ {{explicitly deleted}} template CoawaitTag await_transform(IncTag); // expected-note 1+ {{candidate}} }; }; ForLoopAwaiterBadBeginTransform bad_begin() { Range R; for co_await(auto i : R) {} // expected-error@-1 {{call to deleted member function 'await_transform'}} // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} } template ForLoopAwaiterBadBeginTransform bad_begin_template(Dummy) { Range R; for co_await(auto i : R) {} // expected-error@-1 {{call to deleted member function 'await_transform'}} // expected-note@-2 {{'await_transform' implicitly required by 'co_await' here}} } template ForLoopAwaiterBadBeginTransform bad_begin_template(int); // expected-note {{requested here}} template Awaiter operator co_await(CoawaitTag) = delete; // expected-note@-1 1+ {{explicitly deleted}} struct ForLoopAwaiterBadIncTransform { struct promise_type { ForLoopAwaiterBadIncTransform get_return_object(); void return_void(); void unhandled_exception(); suspend_never initial_suspend(); suspend_never final_suspend(); template Awaiter await_transform(BeginTag e); template CoawaitTag await_transform(IncTag); }; }; ForLoopAwaiterBadIncTransform bad_inc_transform() { Range R; for co_await(auto i : R) {} // expected-error@-1 {{overload resolution selected deleted operator 'co_await'}} // expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range'}} } template ForLoopAwaiterBadIncTransform bad_inc_transform_template(Dummy) { Range R; for co_await(auto i : R) {} // expected-error@-1 {{overload resolution selected deleted operator 'co_await'}} // expected-note@-2 {{in implicit call to 'operator++' for iterator of type 'Range'}} } template ForLoopAwaiterBadIncTransform bad_inc_transform_template(long); // expected-note {{requested here}} // Ensure we mark and check the function as a coroutine even if it's // never instantiated. template constexpr void never_instant(T) { static_assert(sizeof(T) != sizeof(T), "function should not be instantiated"); for co_await(auto i : foo(T{})) {} // expected-error@-1 {{'co_await' cannot be used in a constexpr function}} } namespace NS { struct ForLoopAwaiterCoawaitLookup { struct promise_type { ForLoopAwaiterCoawaitLookup get_return_object(); void return_void(); void unhandled_exception(); suspend_never initial_suspend(); suspend_never final_suspend(); template CoawaitTag await_transform(BeginTag e); template Awaiter await_transform(IncTag); }; }; } // namespace NS using NS::ForLoopAwaiterCoawaitLookup; template ForLoopAwaiterCoawaitLookup test_coawait_lookup(T) { Range R; for co_await(auto i : R) {} // expected-error@-1 {{no member named 'await_ready' in 'CoawaitTag, false>'}} } template ForLoopAwaiterCoawaitLookup test_coawait_lookup(int); // expected-note {{requested here}} // FIXME: This test should fail as well since the newly declared operator co_await // should not be found by lookup. namespace NS2 { template Awaiter operator co_await(CoawaitTag); } using NS2::operator co_await; template ForLoopAwaiterCoawaitLookup test_coawait_lookup(long);