[Flang] remove whole-archive option for AIX linker (#76039)
[llvm-project.git] / clang / test / SemaCXX / coro-lifetimebound.cpp
blobb4dc029a13984846f54447eaed9ef327059f7e3c
1 // RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused -Wno-c++23-lambda-attributes
3 #include "Inputs/std-coroutine.h"
5 using std::suspend_always;
6 using std::suspend_never;
8 template <typename T> struct [[clang::coro_lifetimebound, clang::coro_return_type]] Co {
9 struct promise_type {
10 Co<T> get_return_object() {
11 return {};
13 suspend_always initial_suspend();
14 suspend_always final_suspend() noexcept;
15 void unhandled_exception();
16 void return_value(const T &t);
18 template <typename U>
19 auto await_transform(const Co<U> &) {
20 struct awaitable {
21 bool await_ready() noexcept { return false; }
22 void await_suspend(std::coroutine_handle<>) noexcept {}
23 U await_resume() noexcept { return {}; }
25 return awaitable{};
30 Co<int> foo_coro(const int& b) {
31 if (b > 0)
32 co_return 1;
33 co_return 2;
36 int getInt() { return 0; }
38 Co<int> bar_coro(const int &b, int c) {
39 int x = co_await foo_coro(b);
40 int y = co_await foo_coro(1);
41 int z = co_await foo_coro(getInt());
42 auto unsafe1 = foo_coro(1); // expected-warning {{temporary whose address is used as value of local variable}}
43 auto unsafe2 = foo_coro(getInt()); // expected-warning {{temporary whose address is used as value of local variable}}
44 auto safe1 = foo_coro(b);
45 auto safe2 = foo_coro(c);
46 co_return co_await foo_coro(co_await foo_coro(1));
49 [[clang::coro_wrapper]] Co<int> plain_return_co(int b) {
50 return foo_coro(b); // expected-warning {{address of stack memory associated with parameter}}
53 [[clang::coro_wrapper]] Co<int> safe_forwarding(const int& b) {
54 return foo_coro(b);
57 [[clang::coro_wrapper]] Co<int> unsafe_wrapper(int b) {
58 return safe_forwarding(b); // expected-warning {{address of stack memory associated with parameter}}
61 [[clang::coro_wrapper]] Co<int> complex_plain_return(int b) {
62 return b > 0
63 ? foo_coro(1) // expected-warning {{returning address of local temporary object}}
64 : bar_coro(0, 1); // expected-warning {{returning address of local temporary object}}
67 void lambdas() {
68 auto unsafe_lambda = [] [[clang::coro_wrapper]] (int b) {
69 return foo_coro(b); // expected-warning {{address of stack memory associated with parameter}}
71 auto coro_lambda = [] (const int&) -> Co<int> {
72 co_return 0;
74 auto unsafe_coro_lambda = [&] (const int& b) -> Co<int> {
75 int x = co_await coro_lambda(b);
76 auto safe = coro_lambda(b);
77 auto unsafe1 = coro_lambda(1); // expected-warning {{temporary whose address is used as value of local variable}}
78 auto unsafe2 = coro_lambda(getInt()); // expected-warning {{temporary whose address is used as value of local variable}}
79 auto unsafe3 = coro_lambda(co_await coro_lambda(b)); // expected-warning {{temporary whose address is used as value of local variable}}
80 co_return co_await safe;
82 auto safe_lambda = [](int b) -> Co<int> {
83 int x = co_await foo_coro(1);
84 co_return x + co_await foo_coro(b);
87 // =============================================================================
88 // Safe usage when parameters are value
89 // =============================================================================
90 namespace by_value {
91 Co<int> value_coro(int b) { co_return co_await foo_coro(b); }
92 [[clang::coro_wrapper]] Co<int> wrapper1(int b) { return value_coro(b); }
93 [[clang::coro_wrapper]] Co<int> wrapper2(const int& b) { return value_coro(b); }
96 // =============================================================================
97 // Lifetime bound but not a Coroutine Return Type: No analysis.
98 // =============================================================================
99 namespace not_a_crt {
100 template <typename T> struct [[clang::coro_lifetimebound]] CoNoCRT {
101 struct promise_type {
102 CoNoCRT<T> get_return_object() {
103 return {};
105 suspend_always initial_suspend();
106 suspend_always final_suspend() noexcept;
107 void unhandled_exception();
108 void return_value(const T &t);
112 CoNoCRT<int> foo_coro(const int& a) { co_return a; }
113 CoNoCRT<int> bar(int a) {
114 auto x = foo_coro(a);
115 co_return 1;
117 } // namespace not_a_crt