1 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra -Wno-c++23-lambda-attributes 2 #include "Inputs/std-coroutine.h" 3 4 using std::suspend_always; 5 using std::suspend_never; 6 7 8 namespace std { 9 struct nothrow_t {}; 10 constexpr nothrow_t nothrow = {}; 11 } 12 13 using SizeT = decltype(sizeof(int)); 14 15 void* operator new(SizeT __sz, const std::nothrow_t&) noexcept; 16 17 template <typename T> struct [[clang::coro_return_type]] Gen { 18 struct promise_type { get_return_objectGen::promise_type19 Gen<T> get_return_object() { 20 return {}; 21 } get_return_object_on_allocation_failureGen::promise_type22 static Gen<T> get_return_object_on_allocation_failure() { 23 return {}; 24 } 25 suspend_always initial_suspend(); 26 suspend_always final_suspend() noexcept; 27 void unhandled_exception(); 28 void return_value(T t); 29 30 template <typename U> await_transformGen::promise_type31 auto await_transform(const Gen<U> &) { 32 struct awaitable { 33 bool await_ready() noexcept { return false; } 34 void await_suspend(std::coroutine_handle<>) noexcept {} 35 U await_resume() noexcept { return {}; } 36 }; 37 return awaitable{}; 38 } 39 }; 40 }; 41 42 Gen<int> foo_coro(int b); foo_coro(int b)43Gen<int> foo_coro(int b) { co_return b; } 44 marked_wrapper1(int b)45[[clang::coro_wrapper]] Gen<int> marked_wrapper1(int b) { return foo_coro(b); } 46 47 // expected-error@+1 {{neither a coroutine nor a coroutine wrapper}} non_marked_wrapper(int b)48Gen<int> non_marked_wrapper(int b) { return foo_coro(b); } 49 50 namespace using_decl { 51 template <typename T> using Co = Gen<T>; 52 marked_wrapper1(int b)53[[clang::coro_wrapper]] Co<int> marked_wrapper1(int b) { return foo_coro(b); } 54 55 // expected-error@+1 {{neither a coroutine nor a coroutine wrapper}} non_marked_wrapper(int b)56Co<int> non_marked_wrapper(int b) { return foo_coro(b); } 57 } // namespace using_decl 58 59 namespace lambdas { 60 foo()61void foo() { 62 auto coro_lambda = []() -> Gen<int> { 63 co_return 1; 64 }; 65 // expected-error@+1 {{neither a coroutine nor a coroutine wrapper}} 66 auto not_allowed_wrapper = []() -> Gen<int> { 67 return foo_coro(1); 68 }; 69 auto allowed_wrapper = [] [[clang::coro_wrapper]] () -> Gen<int> { 70 return foo_coro(1); 71 }; 72 } 73 coro_containing_lambda()74Gen<int> coro_containing_lambda() { 75 // expected-error@+1 {{neither a coroutine nor a coroutine wrapper}} 76 auto wrapper_lambda = []() -> Gen<int> { 77 return foo_coro(1); 78 }; 79 co_return co_await wrapper_lambda(); 80 } 81 } // namespace lambdas 82 83 namespace std_function { 84 namespace std { 85 template <typename> class function; 86 87 template <typename ReturnValue, typename... Args> 88 class function<ReturnValue(Args...)> { 89 public: operator =(T)90 template <typename T> function &operator=(T) {} function(T)91 template <typename T> function(T) {} 92 // expected-error@+1 {{neither a coroutine nor a coroutine wrapper}} operator ()(Args...args) const93 ReturnValue operator()(Args... args) const { 94 return callable_->Invoke(args...); // expected-note {{in instantiation of member}} 95 } 96 97 private: 98 class Callable { 99 public: 100 // expected-error@+1 {{neither a coroutine nor a coroutine wrapper}} Invoke(Args...) const101 ReturnValue Invoke(Args...) const { return {}; } 102 }; 103 Callable* callable_; 104 }; 105 } // namespace std 106 use_std_function()107void use_std_function() { 108 std::function<int(bool)> foo = [](bool b) { return b ? 1 : 2; }; 109 // expected-error@+1 {{neither a coroutine nor a coroutine wrapper}} 110 std::function<Gen<int>(bool)> test1 = [](bool b) { 111 return foo_coro(b); 112 }; 113 std::function<Gen<int>(bool)> test2 = [](bool) -> Gen<int> { 114 co_return 1; 115 }; 116 std::function<Gen<int>(bool)> test3 = foo_coro; 117 118 foo(true); // Fine. 119 test1(true); // expected-note 2 {{in instantiation of member}} 120 test2(true); 121 test3(true); 122 } 123 } // namespace std_function 124 125 // different_promise_type 126 class [[clang::coro_return_type]] Task{}; 127 struct my_promise_type { get_return_objectmy_promise_type128 Task get_return_object() { 129 return {}; 130 } 131 suspend_always initial_suspend(); 132 suspend_always final_suspend() noexcept; 133 void unhandled_exception(); 134 }; 135 namespace std { 136 template<> class coroutine_traits<Task, int> { 137 using promise_type = my_promise_type; 138 }; 139 } // namespace std 140 // expected-error@+1 {{neither a coroutine nor a coroutine wrapper}} foo(int)141Task foo(int) { return Task{}; } 142