xref: /llvm-project/clang/test/SemaCXX/coroutine-alloc-4.cpp (revision 9aae408d551083bbbac96ecc512d45c30358e4b9)
1 // Tests that we'll find aligned allocation function properly.
2 // RUN: %clang_cc1 %s -std=c++20 %s -fsyntax-only -verify -fcoro-aligned-allocation
3 
4 #include "Inputs/std-coroutine.h"
5 
6 namespace std {
7     typedef __SIZE_TYPE__ size_t;
8     enum class align_val_t : size_t {};
9 }
10 
11 struct task {
12   struct promise_type {
initial_suspendtask::promise_type13     auto initial_suspend() { return std::suspend_always{}; }
final_suspendtask::promise_type14     auto final_suspend() noexcept { return std::suspend_always{}; }
get_return_objecttask::promise_type15     auto get_return_object() { return task{}; }
unhandled_exceptiontask::promise_type16     void unhandled_exception() {}
return_valuetask::promise_type17     void return_value(int) {}
18     void *operator new(std::size_t); // expected-warning 1+{{under -fcoro-aligned-allocation, the non-aligned allocation function for the promise type 'f' has higher precedence than the global aligned allocation function}}
19   };
20 };
21 
f()22 task f() {
23     co_return 43;
24 }
25 
26 struct task2 {
27   struct promise_type {
initial_suspendtask2::promise_type28     auto initial_suspend() { return std::suspend_always{}; }
final_suspendtask2::promise_type29     auto final_suspend() noexcept { return std::suspend_always{}; }
get_return_objecttask2::promise_type30     auto get_return_object() { return task2{}; }
unhandled_exceptiontask2::promise_type31     void unhandled_exception() {}
return_valuetask2::promise_type32     void return_value(int) {}
33     void *operator new(std::size_t, std::align_val_t);
34   };
35 };
36 
37 // no diagnostic expected
f1()38 task2 f1() {
39     co_return 43;
40 }
41 
42 struct task3 {
43   struct promise_type {
initial_suspendtask3::promise_type44     auto initial_suspend() { return std::suspend_always{}; }
final_suspendtask3::promise_type45     auto final_suspend() noexcept { return std::suspend_always{}; }
get_return_objecttask3::promise_type46     auto get_return_object() { return task3{}; }
unhandled_exceptiontask3::promise_type47     void unhandled_exception() {}
return_valuetask3::promise_type48     void return_value(int) {}
49     void *operator new(std::size_t, std::align_val_t) noexcept;
50     void *operator new(std::size_t) noexcept;
get_return_object_on_allocation_failuretask3::promise_type51     static auto get_return_object_on_allocation_failure() { return task3{}; }
52   };
53 };
54 
55 // no diagnostic expected
f2()56 task3 f2() {
57     co_return 43;
58 }
59 
60 struct task4 {
61   struct promise_type {
initial_suspendtask4::promise_type62     auto initial_suspend() { return std::suspend_always{}; }
final_suspendtask4::promise_type63     auto final_suspend() noexcept { return std::suspend_always{}; }
get_return_objecttask4::promise_type64     auto get_return_object() { return task4{}; }
unhandled_exceptiontask4::promise_type65     void unhandled_exception() {}
return_valuetask4::promise_type66     void return_value(int) {}
67     void *operator new(std::size_t, std::align_val_t, int, double, int) noexcept;
68   };
69 };
70 
71 // no diagnostic expected
f3(int,double,int)72 task4 f3(int, double, int) {
73     co_return 43;
74 }
75 
76 struct task5 {
77   struct promise_type {
initial_suspendtask5::promise_type78     auto initial_suspend() { return std::suspend_always{}; }
final_suspendtask5::promise_type79     auto final_suspend() noexcept { return std::suspend_always{}; }
get_return_objecttask5::promise_type80     auto get_return_object() { return task5{}; }
unhandled_exceptiontask5::promise_type81     void unhandled_exception() {}
return_valuetask5::promise_type82     void return_value(int) {}
83   };
84 };
85 
86 // no diagnostic expected.
87 // The aligned allocation will be declared by the compiler.
f4()88 task5 f4() {
89     co_return 43;
90 }
91 
92 namespace std {
93   struct nothrow_t {};
94   constexpr nothrow_t nothrow = {};
95 }
96 
97 struct task6 {
98   struct promise_type {
initial_suspendtask6::promise_type99     auto initial_suspend() { return std::suspend_always{}; }
final_suspendtask6::promise_type100     auto final_suspend() noexcept { return std::suspend_always{}; }
get_return_objecttask6::promise_type101     auto get_return_object() { return task6{}; }
unhandled_exceptiontask6::promise_type102     void unhandled_exception() {}
return_valuetask6::promise_type103     void return_value(int) {}
get_return_object_on_allocation_failuretask6::promise_type104     static task6 get_return_object_on_allocation_failure() { return task6{}; }
105   };
106 };
107 
f5()108 task6 f5() { // expected-error 1+{{unable to find '::operator new(size_t, align_val_t, nothrow_t)' for 'f5'}}
109     co_return 43;
110 }
111 
112 void *operator new(std::size_t, std::align_val_t, std::nothrow_t) noexcept;
113 
f6()114 task6 f6() {
115     co_return 43;
116 }
117