]> granicus.if.org Git - clang/commitdiff
Allow copy/move assignment operator to be coroutine as per N4775
authorVivek Pandya <vivekvpandya@gmail.com>
Wed, 19 Jun 2019 14:12:19 +0000 (14:12 +0000)
committerVivek Pandya <vivekvpandya@gmail.com>
Wed, 19 Jun 2019 14:12:19 +0000 (14:12 +0000)
This change fixes https://bugs.llvm.org/show_bug.cgi?id=40997.

Reviewers: GorNishanov, rsmith
Reviewed by: GorNishanov
Subscribers: cfe-commits, lewissbaker, modocache, llvm-commits

Differential Revision: https://reviews.llvm.org/D63381

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@363804 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaCoroutine.cpp
test/SemaCXX/coroutines.cpp

index 019518204ac30135068e9cdf3fa7dc3f483e9c56..9cb2a769f4f8688522d49a82f08db14824e8c68a 100644 (file)
@@ -9432,9 +9432,9 @@ def err_coroutine_outside_function : Error<
   "'%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 <experimental/coroutine> before defining "
   "a coroutine">;
index fc6470617c057dc2ca7c1d50c80e54bd44722ce9..f0347af6a1bb1ff216413f1c0c26cf910c8d99ae 100644 (file)
@@ -204,8 +204,6 @@ static bool isValidCoroutineContext(Sema &S, SourceLocation Loc,
   enum InvalidFuncDiag {
     DiagCtor = 0,
     DiagDtor,
-    DiagCopyAssign,
-    DiagMoveAssign,
     DiagMain,
     DiagConstexpr,
     DiagAutoRet,
@@ -219,23 +217,15 @@ static bool isValidCoroutineContext(Sema &S, SourceLocation Loc,
     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<CXXMethodDecl>(FD);
-  // [class.ctor]p6: "A constructor shall not be a coroutine."
+  // [class.ctor]p11: "A constructor shall not be a coroutine."
   if (MD && isa<CXXConstructorDecl>(MD))
     return DiagInvalid(DiagCtor);
   // [class.dtor]p17: "A destructor shall not be a coroutine."
   else if (MD && isa<CXXDestructorDecl>(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 1286ca4628b7b6c61fa97fd7813f608e239c4c3d..c8de7b0178593ecda672d255f4ac525561e2be06 100644 (file)
@@ -296,18 +296,17 @@ struct CtorDtor {
   ~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