================
@@ -7581,3 +7580,59 @@ alignment boundary. Its value must be a power of 2, 
between 1 and 4096
 
   }];
 }
+
+def CoroLifetimeBoundDoc : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+The ``[[clang::coro_lifetimebound]]`` is a class attribute which can be applied
+to a `coroutine return type (CRT) 
<https://clang.llvm.org/docs/AttributeReference.html#coro-return-type>` _ (i.e.
+it should also be annotated with ``[[clang::coro_return_type]]``).
+
+All arguments to a function are considered to be `lifetime bound 
<https://clang.llvm.org/docs/AttributeReference.html#lifetimebound> _`
+if the function returns a coroutine return type (CRT) annotated with 
``[[clang::coro_lifetimebound]]``.
+
+Reference parameters of a coroutine are susceptible to capturing references to 
temporaries or local variables.
+
+For example,
+
+.. code-block:: c++
+
+  task<int> coro(const int& a) { co_return a + 1; }
+  task<int> dangling_refs(int a) {
+    // `coro` captures reference to a temporary. `foo` would now contain a 
dangling reference to `a`.
+    auto foo = coro(1);
+    // `coro` captures reference to local variable `a` which is destroyed 
after the return. 
+    return coro(a);
+  }
+
+`Lifetime bound 
<https://clang.llvm.org/docs/AttributeReference.html#lifetimebound> _` static 
analysis
+can be used to detect such instances when coroutines capture references which 
may die earlier than the
+coroutine frame itself. In the above example, if the CRT `task` is annotated 
with 
+``[[clang::coro_lifetimebound]]``, then lifetime bound analysis would detect 
capturing reference to
+temporaries or return address of a local variable.
+
+Both coroutines and coroutine wrappers are part of this analysis.
+
+.. code-block:: c++
+
+  template <typename T> struct [[clang::coro_return_type, 
clang::coro_lifetimebound]] Task {
+    using promise_type = some_promise_type;
+  };
+
+  Task<int> coro(const int& a) { co_return a + 1; }
+  Task<int> [[clang::coro_wrapper]] coro_wrapper(const int& a, const int& b) { 
+    return a > b ? coro(a) : coro(b);
+  }
+  Task<int> temporary_reference() {
+    auto foo = coro(1); // warning: capturing reference to a temporary which 
would die after the expression.
+
+    int a = 1;
+    auto bar = coro_wrapper(a, 0); // warning: `b` captures reference to a 
temporary.
+
+    co_return co_await coro(1); // fine.
+  }
+  Task<int> stack_reference(int a) {
+    return coro(a); // returning address of stack variable `a`.
----------------
hokein wrote:

this case should be a warning, right?

https://github.com/llvm/llvm-project/pull/72851
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to