================
@@ -0,0 +1,440 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefixes=CIR,CIR-NOEH
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu 
-fcxx-exceptions -fexceptions -fclangir -emit-cir %s -o %t-eh.cir
+// RUN: FileCheck --input-file=%t-eh.cir %s -check-prefixes=CIR,CIR-EH
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -O1 -fclangir 
-emit-cir %s -o %t-O1.cir
+// RUN: FileCheck --input-file=%t-O1.cir %s -check-prefix=CIR-O1
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm 
-disable-llvm-passes %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+// Ensure coroutine parameter copies, promises and the body are destroyed in 
the correct order.
+
+#include "Inputs/coroutine.h"
+
+struct Dtor {
+  ~Dtor();
+  int x;
+};
+
+struct Task {
+  struct promise_type {
+    ~promise_type();
+    Task get_return_object() noexcept;
+    std::suspend_always initial_suspend() noexcept;
+    std::suspend_always final_suspend() noexcept;
+    void return_void() noexcept;
+    void unhandled_exception() noexcept;
+  };
+};
+
+struct TrivialTask {
+  struct promise_type {
+    TrivialTask get_return_object() noexcept;
+    std::suspend_always initial_suspend() noexcept;
+    std::suspend_always final_suspend() noexcept;
+    void return_void() noexcept;
+    void unhandled_exception() noexcept;
+  };
+};
+
+Task promise_dtor() { co_return; }
+
+// The promise's destructor is not scoped to initial_suspend, where the promise
+// is constructed, and runs only in destroy.
+
+// CIR-LABEL: cir.func coroutine {{.*}} @_Z12promise_dtorv(
+// CIR:         %[[PROMISE:.*]] = cir.alloca "__promise"
+// CIR-NOT:     cir.cleanup.scope
+// CIR:         cir.coroutine initialSuspend : {
+// CIR-NOT:       {{cir.cleanup.scope|cir.call @_ZN4Task12promise_typeD1Ev}}
+// CIR:           cir.await(init,
+// CIR-NOT:       cir.call @_ZN4Task12promise_typeD1Ev
+// CIR:         }, body : {
+// CIR-NOT:       cir.call @_ZN4Task12promise_typeD1Ev
+// CIR:         }, destroy : {
+// CIR-NEXT:      cir.call @_ZN4Task12promise_typeD1Ev(%[[PROMISE]])
----------------
mmha wrote:

I was looking at how much it takes to get rid of the problem and it wasn't that 
much extra code after all. I now emit nested cleanup scopes for this.

https://github.com/llvm/llvm-project/pull/230574
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to