// Tests that the combination of -fcoro-aligned-allocation and -fsized-deallocation works well.
// Test the compiler will chose sized deallocation correctly.
// This is only enabled with `-fsized-deallocation` which is off by default.
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \
// RUN:   -fcoro-aligned-allocation -S -emit-llvm %s -o - -disable-llvm-passes \
// RUN:   -fsized-deallocation \
// RUN:   | FileCheck %s

#include "Inputs/coroutine.h"

namespace std {
    typedef __SIZE_TYPE__ size_t;
    enum class align_val_t : size_t {};
}

struct task {
  struct promise_type {
    auto initial_suspend() { return std::suspend_always{}; }
    auto final_suspend() noexcept { return std::suspend_always{}; }
    auto get_return_object() { return task{}; }
    void unhandled_exception() {}
    void return_value(int) {}
  };
};

// CHECK: define{{.*}}@_Z1fv
// CHECK: coro.free:
// CHECK: %[[coro_size:.+]] = call{{.*}}@llvm.coro.size
// CHECK: %[[coro_align:.+]] = call{{.*}}@llvm.coro.align
// CHECK: call{{.*}}void @_ZdlPvmSt11align_val_t(ptr{{.*}}, i64{{.*}}%[[coro_size]], i64{{.*}}%[[coro_align]])

task f() {
  co_return 43;
}

struct task2 {
  struct promise_type {
    auto initial_suspend() { return std::suspend_always{}; }
    auto final_suspend() noexcept { return std::suspend_always{}; }
    auto get_return_object() { return task2{}; }
    void unhandled_exception() {}
    void return_value(int) {}
    void operator delete(void *ptr);
  };
};

// CHECK: define{{.*}}@_Z2f2v
// CHECK: %[[FREE_HANDLE:.+]] = call{{.*}}ptr @llvm.coro.free(
// CHECK: coro.free:
// CHECK: call{{.*}}void @_ZN5task212promise_typedlEPv(ptr{{.*}} %[[FREE_HANDLE]])

task2 f2() {
  co_return 43;
}

struct task3 {
  struct promise_type {
    auto initial_suspend() { return std::suspend_always{}; }
    auto final_suspend() noexcept { return std::suspend_always{}; }
    auto get_return_object() { return task3{}; }
    void unhandled_exception() {}
    void return_value(int) {}
    void operator delete(void *ptr, std::size_t);
    void operator delete(void *ptr);
  };
};

// CHECK: define{{.*}}@_Z2f3v
// CHECK: %[[FREE_HANDLE:.+]] = call{{.*}}ptr @llvm.coro.free(
// CHECK: coro.free:
// CHECK: %[[coro_size:.+]] = call{{.*}}@llvm.coro.size
// CHECK: call{{.*}}void @_ZN5task312promise_typedlEPvm(ptr{{.*}} %[[FREE_HANDLE]], i64{{.*}}%[[coro_size]]

task3 f3() {
  co_return 43;
}

struct task4 {
  struct promise_type {
    auto initial_suspend() { return std::suspend_always{}; }
    auto final_suspend() noexcept { return std::suspend_always{}; }
    auto get_return_object() { return task4{}; }
    void unhandled_exception() {}
    void return_value(int) {}
    void operator delete(void *ptr, std::size_t);
    void operator delete(void *ptr, std::align_val_t);
    void operator delete(void *ptr);
  };
};

// CHECK: define{{.*}}@_Z2f4v
// CHECK: %[[FREE_HANDLE:.+]] = call{{.*}}ptr @llvm.coro.free(
// CHECK: coro.free:
// CHECK: %[[coro_align:.+]] = call{{.*}}@llvm.coro.align
// CHECK: call{{.*}}void @_ZN5task412promise_typedlEPvSt11align_val_t(ptr{{.*}} %[[FREE_HANDLE]], i64{{.*}}%[[coro_align]])

task4 f4() {
  co_return 43;
}

struct task5 {
  struct promise_type {
    auto initial_suspend() { return std::suspend_always{}; }
    auto final_suspend() noexcept { return std::suspend_always{}; }
    auto get_return_object() { return task5{}; }
    void unhandled_exception() {}
    void return_value(int) {}
    void operator delete(void *ptr, std::size_t);
    void operator delete(void *ptr, std::size_t, std::align_val_t);
    void operator delete(void *ptr);
  };
};

// CHECK: define{{.*}}@_Z2f5v
// CHECK: %[[FREE_HANDLE:.+]] = call{{.*}}ptr @llvm.coro.free(
// CHECK: coro.free:
// CHECK: %[[coro_size:.+]] = call{{.*}}@llvm.coro.size
// CHECK: %[[coro_align:.+]] = call{{.*}}@llvm.coro.align
// CHECK: call{{.*}}void @_ZN5task512promise_typedlEPvmSt11align_val_t(ptr{{.*}} %[[FREE_HANDLE]], i64{{.*}}%[[coro_size]], i64{{.*}}%[[coro_align]])

task5 f5() {
  co_return 43;
}
