// Test for PR56919. Tests the we won't contain the resumption of final suspend point.
//
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %s -O3 -emit-llvm -o - | FileCheck %s
// This test is expected to fail on PowerPC.
// XFAIL: target=powerpc{{.*}}

#include "Inputs/coroutine.h"

void _exit(int status) __attribute__ ((__noreturn__));

class Promise;

// An object that can be co_awaited, but we always resume immediately from
// await_suspend.
struct ResumeFromAwaitSuspend{};

struct Task {
  using promise_type = Promise;
  Promise& promise;
};

struct Promise {
  static std::coroutine_handle<Promise> GetHandle(Promise& promise) {
    return std::coroutine_handle<Promise>::from_promise(promise);
  }

  void unhandled_exception() {}
  Task get_return_object() { return Task{*this}; }
  void return_void() {}

  // Always suspend before starting the coroutine body. We actually run the body
  // when we are co_awaited.
  std::suspend_always initial_suspend() { return {}; }

  // We support awaiting tasks. We do so by configuring them to resume us when
  // they are finished, and then resuming them from their initial suspend.
  auto await_transform(Task&& task) {
    struct Awaiter {
      bool await_ready() { return false; }

      std::coroutine_handle<> await_suspend(
          const std::coroutine_handle<> handle) {
        // Tell the child to resume the parent once it finishes.
        child.resume_at_final_suspend = GetHandle(parent);

        // Run the child.
        return GetHandle(child);
      }

      void await_resume() {
        // The child is now at its final suspend point, and can be destroyed.
        return GetHandle(child).destroy();
      }

      Promise& parent;
      Promise& child;
    };

    return Awaiter{
        .parent = *this,
        .child = task.promise,
    };
  }

  // Make evaluation of `co_await ResumeFromAwaitSuspend{}` go through the
  // await_suspend path, but cause it to resume immediately by returning our own
  // handle to resume.
  auto await_transform(ResumeFromAwaitSuspend) {
    struct Awaiter {
      bool await_ready() { return false; }

      std::coroutine_handle<> await_suspend(const std::coroutine_handle<> h) {
        return h;
      }

      void await_resume() {}
    };

    return Awaiter{};
  }

  // Always suspend at the final suspend point, transferring control back to our
  // caller. We expect never to be resumed from the final suspend.
  auto final_suspend() noexcept {
    struct FinalSuspendAwaitable final {
      bool await_ready() noexcept { return false; }

      std::coroutine_handle<> await_suspend(std::coroutine_handle<>) noexcept {
        return promise.resume_at_final_suspend;
      }

      void await_resume() noexcept {
        _exit(1);
      }

      Promise& promise;
    };

    return FinalSuspendAwaitable{.promise = *this};
  }

  // The handle we will resume once we hit final suspend.
  std::coroutine_handle<> resume_at_final_suspend;
};

Task Inner();

Task Outer() {
  co_await ResumeFromAwaitSuspend();
  co_await Inner();
}

// CHECK: define{{.*}}@_Z5Outerv.resume(
// CHECK-NOT: }
// CHECK-NOT: _exit
// CHECK: musttail call
// CHECK: musttail call
// CHECK: musttail call
// CHECK-NEXT: ret void
// CHECK-EMPTY:
// CHECK-NEXT: unreachable:
// CHECK-NEXT: unreachable
// CHECK-NEXT: }
