1 // Tests that the combination of -fcoro-aligned-allocation and -fsized-deallocation works well.
2 // Test the compiler will chose sized deallocation correctly.
3 // This is only enabled with `-fsized-deallocation` which is off by default.
4 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \
5 // RUN: -fcoro-aligned-allocation -S -emit-llvm %s -o - -disable-llvm-passes \
6 // RUN: -fsized-deallocation \
9 #include "Inputs/coroutine.h"
12 typedef __SIZE_TYPE__
size_t;
13 enum class align_val_t
: size_t {};
18 auto initial_suspend() { return std::suspend_always
{}; }
19 auto final_suspend() noexcept
{ return std::suspend_always
{}; }
20 auto get_return_object() { return task
{}; }
21 void unhandled_exception() {}
22 void return_value(int) {}
26 // CHECK: define{{.*}}@_Z1fv
28 // CHECK: %[[coro_size:.+]] = call{{.*}}@llvm.coro.size
29 // CHECK: %[[coro_align:.+]] = call{{.*}}@llvm.coro.align
30 // CHECK: call{{.*}}void @_ZdlPvmSt11align_val_t(ptr{{.*}}, i64{{.*}}%[[coro_size]], i64{{.*}}%[[coro_align]])
38 auto initial_suspend() { return std::suspend_always
{}; }
39 auto final_suspend() noexcept
{ return std::suspend_always
{}; }
40 auto get_return_object() { return task2
{}; }
41 void unhandled_exception() {}
42 void return_value(int) {}
43 void operator delete(void *ptr
);
47 // CHECK: define{{.*}}@_Z2f2v
48 // CHECK: %[[FREE_HANDLE:.+]] = call{{.*}}ptr @llvm.coro.free(
50 // CHECK: call{{.*}}void @_ZN5task212promise_typedlEPv(ptr{{.*}} %[[FREE_HANDLE]])
58 auto initial_suspend() { return std::suspend_always
{}; }
59 auto final_suspend() noexcept
{ return std::suspend_always
{}; }
60 auto get_return_object() { return task3
{}; }
61 void unhandled_exception() {}
62 void return_value(int) {}
63 void operator delete(void *ptr
, std::size_t);
64 void operator delete(void *ptr
);
68 // CHECK: define{{.*}}@_Z2f3v
69 // CHECK: %[[FREE_HANDLE:.+]] = call{{.*}}ptr @llvm.coro.free(
71 // CHECK: %[[coro_size:.+]] = call{{.*}}@llvm.coro.size
72 // CHECK: call{{.*}}void @_ZN5task312promise_typedlEPvm(ptr{{.*}} %[[FREE_HANDLE]], i64{{.*}}%[[coro_size]]
80 auto initial_suspend() { return std::suspend_always
{}; }
81 auto final_suspend() noexcept
{ return std::suspend_always
{}; }
82 auto get_return_object() { return task4
{}; }
83 void unhandled_exception() {}
84 void return_value(int) {}
85 void operator delete(void *ptr
, std::size_t);
86 void operator delete(void *ptr
, std::align_val_t
);
87 void operator delete(void *ptr
);
91 // CHECK: define{{.*}}@_Z2f4v
92 // CHECK: %[[FREE_HANDLE:.+]] = call{{.*}}ptr @llvm.coro.free(
94 // CHECK: %[[coro_align:.+]] = call{{.*}}@llvm.coro.align
95 // CHECK: call{{.*}}void @_ZN5task412promise_typedlEPvSt11align_val_t(ptr{{.*}} %[[FREE_HANDLE]], i64{{.*}}%[[coro_align]])
102 struct promise_type
{
103 auto initial_suspend() { return std::suspend_always
{}; }
104 auto final_suspend() noexcept
{ return std::suspend_always
{}; }
105 auto get_return_object() { return task5
{}; }
106 void unhandled_exception() {}
107 void return_value(int) {}
108 void operator delete(void *ptr
, std::size_t);
109 void operator delete(void *ptr
, std::size_t, std::align_val_t
);
110 void operator delete(void *ptr
);
114 // CHECK: define{{.*}}@_Z2f5v
115 // CHECK: %[[FREE_HANDLE:.+]] = call{{.*}}ptr @llvm.coro.free(
117 // CHECK: %[[coro_size:.+]] = call{{.*}}@llvm.coro.size
118 // CHECK: %[[coro_align:.+]] = call{{.*}}@llvm.coro.align
119 // CHECK: call{{.*}}void @_ZN5task512promise_typedlEPvmSt11align_val_t(ptr{{.*}} %[[FREE_HANDLE]], i64{{.*}}%[[coro_size]], i64{{.*}}%[[coro_align]])