[clang] 53c2e10 - [Coroutines] Do not evaluate InitListExpr of a co_return

Jun Ma via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 15 21:42:59 PDT 2020


Author: Jun Ma
Date: 2020-03-16T12:42:44+08:00
New Revision: 53c2e10fb8a606aa0cb092dda1219603cc3017cd

URL: https://github.com/llvm/llvm-project/commit/53c2e10fb8a606aa0cb092dda1219603cc3017cd
DIFF: https://github.com/llvm/llvm-project/commit/53c2e10fb8a606aa0cb092dda1219603cc3017cd.diff

LOG: [Coroutines] Do not evaluate InitListExpr of a co_return

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

Added: 
    clang/test/CodeGenCoroutines/coro-return-voidtype-initlist.cpp

Modified: 
    clang/lib/CodeGen/CGCoroutine.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp
index aee5a927a055..5c57ad0685d5 100644
--- a/clang/lib/CodeGen/CGCoroutine.cpp
+++ b/clang/lib/CodeGen/CGCoroutine.cpp
@@ -275,9 +275,9 @@ RValue CodeGenFunction::EmitCoyieldExpr(const CoyieldExpr &E,
 void CodeGenFunction::EmitCoreturnStmt(CoreturnStmt const &S) {
   ++CurCoro.Data->CoreturnCount;
   const Expr *RV = S.getOperand();
-  if (RV && RV->getType()->isVoidType()) {
-    // Make sure to evaluate the expression of a co_return with a void
-    // expression for side effects.
+  if (RV && RV->getType()->isVoidType() && !isa<InitListExpr>(RV)) {
+    // Make sure to evaluate the non initlist expression of a co_return
+    // with a void expression for side effects.
     RunCleanupsScope cleanupScope(*this);
     EmitIgnoredExpr(RV);
   }

diff  --git a/clang/test/CodeGenCoroutines/coro-return-voidtype-initlist.cpp b/clang/test/CodeGenCoroutines/coro-return-voidtype-initlist.cpp
new file mode 100644
index 000000000000..8526b6f8a8da
--- /dev/null
+++ b/clang/test/CodeGenCoroutines/coro-return-voidtype-initlist.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++1z -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s
+
+namespace std {
+template <typename a>
+struct b { b(int, a); };
+template <typename, typename = int>
+struct c {};
+namespace experimental {
+template <typename d>
+struct coroutine_traits : d {};
+template <typename = void>
+struct coroutine_handle;
+template <>
+struct coroutine_handle<> {};
+template <typename>
+struct coroutine_handle : coroutine_handle<> {
+  static coroutine_handle from_address(void *);
+};
+struct e {
+  int await_ready();
+  void await_suspend(coroutine_handle<>);
+  void await_resume();
+};
+} // namespace experimental
+} // namespace std
+template <typename ag>
+auto ah(ag) { return ag().ah(0); }
+template <typename>
+struct f;
+struct g {
+  struct h {
+    int await_ready();
+    template <typename al>
+    void await_suspend(std::experimental::coroutine_handle<al>);
+    void await_resume();
+  };
+  std::experimental::e initial_suspend();
+  h final_suspend();
+  template <typename ag>
+  auto await_transform(ag) { return ah(ag()); }
+};
+struct j : g {
+  f<std::b<std::c<int, int>>> get_return_object();
+  void return_value(std::b<std::c<int, int>>);
+  void unhandled_exception();
+};
+struct k {
+  k(std::experimental::coroutine_handle<>);
+  int await_ready();
+};
+template <typename am>
+struct f {
+  using promise_type = j;
+  std::experimental::coroutine_handle<> ar;
+  struct l : k {
+    using at = k;
+    l(std::experimental::coroutine_handle<> m) : at(m) {}
+    void await_suspend(std::experimental::coroutine_handle<>);
+  };
+  struct n : l {
+    n(std::experimental::coroutine_handle<> m) : l(m) {}
+    am await_resume();
+  };
+  auto ah(int) { return n(ar); }
+};
+template <typename am, typename av, typename aw>
+auto ax(std::c<am, av>, aw) -> f<std::c<int, aw>>;
+template <typename>
+struct J { static f<std::b<std::c<int, int>>> bo(); };
+// CHECK-LABEL: _ZN1JIiE2boEv(
+template <typename bc>
+f<std::b<std::c<int, int>>> J<bc>::bo() {
+  std::c<int> bu;
+  int bw(0);
+  // CHECK: void @_ZN1j12return_valueESt1bISt1cIiiEE(%struct.j* %__promise)
+  co_return{0, co_await ax(bu, bw)};
+}
+void bh() {
+  auto cn = [] { J<int>::bo; };
+  cn();
+}


        


More information about the cfe-commits mailing list