1452fac95SChuanqi Xu // RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -verify 2452fac95SChuanqi Xu #include "Inputs/std-coroutine.h" 3452fac95SChuanqi Xu 4452fac95SChuanqi Xu namespace std { 5452fac95SChuanqi Xu typedef decltype(sizeof(int)) size_t; 6452fac95SChuanqi Xu } 7452fac95SChuanqi Xu 8452fac95SChuanqi Xu struct Allocator {}; 9452fac95SChuanqi Xu 10452fac95SChuanqi Xu struct resumable { 11452fac95SChuanqi Xu struct promise_type { 12452fac95SChuanqi Xu void *operator new(std::size_t sz, Allocator &); 13452fac95SChuanqi Xu get_return_objectresumable::promise_type14452fac95SChuanqi Xu resumable get_return_object() { return {}; } initial_suspendresumable::promise_type15452fac95SChuanqi Xu auto initial_suspend() { return std::suspend_always(); } final_suspendresumable::promise_type16452fac95SChuanqi Xu auto final_suspend() noexcept { return std::suspend_always(); } unhandled_exceptionresumable::promise_type17452fac95SChuanqi Xu void unhandled_exception() {} return_voidresumable::promise_type18452fac95SChuanqi Xu void return_void(){}; 19452fac95SChuanqi Xu }; 20452fac95SChuanqi Xu }; 21452fac95SChuanqi Xu f1()22*448995c5SChuanqi Xuresumable f1() { // expected-error {{'operator new' provided by 'std::coroutine_traits<resumable>::promise_type' (aka 'resumable::promise_type') is not usable with the function signature of 'f1'}} 23452fac95SChuanqi Xu co_return; 24452fac95SChuanqi Xu } 25452fac95SChuanqi Xu 26452fac95SChuanqi Xu // NOTE: Although the argument here is a rvalue reference and the corresponding 27452fac95SChuanqi Xu // allocation function in resumable::promise_type have lvalue references, it looks 28452fac95SChuanqi Xu // the signature of f2 is invalid. But according to [dcl.fct.def.coroutine]p4: 29452fac95SChuanqi Xu // 30452fac95SChuanqi Xu // In the following, pi is an lvalue of type Pi, where p1 denotes the object 31452fac95SChuanqi Xu // parameter and pi+1 denotes the ith non-object function parameter for a 32452fac95SChuanqi Xu // non-static member function. 33452fac95SChuanqi Xu // 34452fac95SChuanqi Xu // And [dcl.fct.def.coroutine]p9.1 35452fac95SChuanqi Xu // 36452fac95SChuanqi Xu // overload resolution is performed on a function call created by assembling an argument list. 37452fac95SChuanqi Xu // The first argument is the amount of space requested, and has type std::size_t. 38452fac95SChuanqi Xu // The lvalues p1…pn are the succeeding arguments. 39452fac95SChuanqi Xu // 40*448995c5SChuanqi Xu // So the actual type passed to resumable::promise_type::operator new is lvalue 41452fac95SChuanqi Xu // Allocator. It is allowed to convert a lvalue to a lvalue reference. So the 42452fac95SChuanqi Xu // following one is valid. f2(Allocator &&)43452fac95SChuanqi Xuresumable f2(Allocator &&) { 44452fac95SChuanqi Xu co_return; 45452fac95SChuanqi Xu } 46452fac95SChuanqi Xu f3(Allocator &)47452fac95SChuanqi Xuresumable f3(Allocator &) { 48452fac95SChuanqi Xu co_return; 49452fac95SChuanqi Xu } 50452fac95SChuanqi Xu f4(Allocator)51452fac95SChuanqi Xuresumable f4(Allocator) { 52452fac95SChuanqi Xu co_return; 53452fac95SChuanqi Xu } 54452fac95SChuanqi Xu f5(const Allocator)55452fac95SChuanqi Xuresumable f5(const Allocator) { // expected-error {{operator new' provided by 'std::coroutine_traits<resumable, const Allocator>::promise_type' (aka 'resumable::promise_type') is not usable}} 56452fac95SChuanqi Xu co_return; 57452fac95SChuanqi Xu } 58452fac95SChuanqi Xu f6(const Allocator &)59452fac95SChuanqi Xuresumable f6(const Allocator &) { // expected-error {{operator new' provided by 'std::coroutine_traits<resumable, const Allocator &>::promise_type' (aka 'resumable::promise_type') is not usable}} 60452fac95SChuanqi Xu co_return; 61452fac95SChuanqi Xu } 62*448995c5SChuanqi Xu 63*448995c5SChuanqi Xu struct promise_base1 { 64*448995c5SChuanqi Xu void *operator new(std::size_t sz); // expected-note {{member found by ambiguous name lookup}} 65*448995c5SChuanqi Xu }; 66*448995c5SChuanqi Xu 67*448995c5SChuanqi Xu struct promise_base2 { 68*448995c5SChuanqi Xu void *operator new(std::size_t sz); // expected-note {{member found by ambiguous name lookup}} 69*448995c5SChuanqi Xu }; 70*448995c5SChuanqi Xu 71*448995c5SChuanqi Xu struct resumable2 { 72*448995c5SChuanqi Xu struct promise_type : public promise_base1, public promise_base2 { get_return_objectresumable2::promise_type73*448995c5SChuanqi Xu resumable2 get_return_object() { return {}; } initial_suspendresumable2::promise_type74*448995c5SChuanqi Xu auto initial_suspend() { return std::suspend_always(); } final_suspendresumable2::promise_type75*448995c5SChuanqi Xu auto final_suspend() noexcept { return std::suspend_always(); } unhandled_exceptionresumable2::promise_type76*448995c5SChuanqi Xu void unhandled_exception() {} return_voidresumable2::promise_type77*448995c5SChuanqi Xu void return_void(){}; 78*448995c5SChuanqi Xu }; 79*448995c5SChuanqi Xu }; 80*448995c5SChuanqi Xu f7()81*448995c5SChuanqi Xuresumable2 f7() { // expected-error {{member 'operator new' found in multiple base classes of different types}} 82*448995c5SChuanqi Xu co_return; 83*448995c5SChuanqi Xu } 84