Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td @@ -9432,9 +9432,9 @@ "'%0' cannot be used outside a function">; def err_coroutine_invalid_func_context : Error< "'%1' cannot be used in %select{a constructor|a destructor" - "|a copy assignment operator|a move assignment operator|the 'main' function" - "|a constexpr function|a function with a deduced return type" - "|a varargs function|a consteval function}0">; + "|the 'main' function|a constexpr function" + "|a function with a deduced return type|a varargs function" + "|a consteval function}0">; def err_implied_coroutine_type_not_found : Error< "%0 type was not found; include before defining " "a coroutine">; Index: cfe/trunk/lib/Sema/SemaCoroutine.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaCoroutine.cpp +++ cfe/trunk/lib/Sema/SemaCoroutine.cpp @@ -204,8 +204,6 @@ enum InvalidFuncDiag { DiagCtor = 0, DiagDtor, - DiagCopyAssign, - DiagMoveAssign, DiagMain, DiagConstexpr, DiagAutoRet, @@ -219,23 +217,15 @@ return false; }; - // Diagnose when a constructor, destructor, copy/move assignment operator, + // Diagnose when a constructor, destructor // or the function 'main' are declared as a coroutine. auto *MD = dyn_cast(FD); - // [class.ctor]p6: "A constructor shall not be a coroutine." + // [class.ctor]p11: "A constructor shall not be a coroutine." if (MD && isa(MD)) return DiagInvalid(DiagCtor); // [class.dtor]p17: "A destructor shall not be a coroutine." else if (MD && isa(MD)) return DiagInvalid(DiagDtor); - // N4499 [special]p6: "A special member function shall not be a coroutine." - // Per C++ [special]p1, special member functions are the "default constructor, - // copy constructor and copy assignment operator, move constructor and move - // assignment operator, and destructor." - else if (MD && MD->isCopyAssignmentOperator()) - return DiagInvalid(DiagCopyAssign); - else if (MD && MD->isMoveAssignmentOperator()) - return DiagInvalid(DiagMoveAssign); // [basic.start.main]p3: "The function main shall not be a coroutine." else if (FD->isMain()) return DiagInvalid(DiagMain); Index: cfe/trunk/test/SemaCXX/coroutines.cpp =================================================================== --- cfe/trunk/test/SemaCXX/coroutines.cpp +++ cfe/trunk/test/SemaCXX/coroutines.cpp @@ -296,18 +296,17 @@ ~CtorDtor() { co_return 0; // expected-error {{'co_return' cannot be used in a destructor}} } - // FIXME: The spec says this is ill-formed. void operator=(CtorDtor&) { - co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}} + co_yield 0; // OK. } void operator=(CtorDtor const &) { - co_yield 0; // expected-error {{'co_yield' cannot be used in a copy assignment operator}} + co_yield 0; // OK. } void operator=(CtorDtor &&) { - co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}} + co_await a; // OK. } void operator=(CtorDtor const &&) { - co_await a; // expected-error {{'co_await' cannot be used in a move assignment operator}} + co_await a; // OK. } void operator=(int) { co_await a; // OK. Not a special member