1 // RUN: %check_clang_tidy -std=c++20 %s cppcoreguidelines-avoid-reference-coroutine-parameters %t --
2 
3 // NOLINTBEGIN
4 namespace std {
5   template <typename T, typename... Args>
6   struct coroutine_traits {
7     using promise_type = typename T::promise_type;
8   };
9   template <typename T = void>
10   struct coroutine_handle;
11   template <>
12   struct coroutine_handle<void> {
13     coroutine_handle() noexcept;
14     coroutine_handle(decltype(nullptr)) noexcept;
15     static constexpr coroutine_handle from_address(void*);
16   };
17   template <typename T>
18   struct coroutine_handle {
19     coroutine_handle() noexcept;
20     coroutine_handle(decltype(nullptr)) noexcept;
21     static constexpr coroutine_handle from_address(void*);
22     operator coroutine_handle<>() const noexcept;
23   };
24 } // namespace std
25 
26 struct Awaiter {
27   bool await_ready() noexcept;
28   void await_suspend(std::coroutine_handle<>) noexcept;
29   void await_resume() noexcept;
30 };
31 
32 struct Coro {
33   struct promise_type {
34     Awaiter initial_suspend();
35     Awaiter final_suspend() noexcept;
36     void return_void();
37     Coro get_return_object();
38     void unhandled_exception();
39   };
40 };
41 // NOLINTEND
42 
43 struct Obj {};
44 
no_args()45 Coro no_args() {
46   co_return;
47 }
48 
no_references(int x,int * y,Obj z,const Obj w)49 Coro no_references(int x, int* y, Obj z, const Obj w) {
50   co_return;
51 }
52 
accepts_references(int & x,const int & y)53 Coro accepts_references(int& x, const int &y) {
54   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
55   // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
56   co_return;
57 }
58 
accepts_references_and_non_references(int & x,int y)59 Coro accepts_references_and_non_references(int& x, int y) {
60   // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
61   co_return;
62 }
63 
accepts_references_to_objects(Obj & x)64 Coro accepts_references_to_objects(Obj& x) {
65   // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
66   co_return;
67 }
68 
non_coro_accepts_references(int & x)69 Coro non_coro_accepts_references(int& x) {
70   if (x);
71   return Coro{};
72 }
73 
defines_a_lambda()74 void defines_a_lambda() {
75   auto NoArgs = [](int x) -> Coro { co_return; };
76 
77   auto NoReferences = [](int x) -> Coro { co_return; };
78 
79   auto WithReferences = [](int& x) -> Coro { co_return; };
80   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
81 
82   auto WithReferences2 = [](int&) -> Coro { co_return; };
83   // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
84 }
85 
coroInFunctionWithReference(int &)86 void coroInFunctionWithReference(int&) {
87   auto SampleCoro = [](int x) -> Coro { co_return; };
88 }
89 
lambdaWithReferenceInCoro()90 Coro lambdaWithReferenceInCoro() {
91   auto SampleLambda = [](int& x) {};
92   co_return;
93 }
94 
95 using MyIntegerRef = int&;
coroWithReferenceBehindTypedef(MyIntegerRef ref)96 Coro coroWithReferenceBehindTypedef(MyIntegerRef ref) {
97 // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: coroutine parameters should not be references [cppcoreguidelines-avoid-reference-coroutine-parameters]
98   co_return;
99 }
100