================ @@ -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) { ---------------- hokein wrote:
nit: looks like `[[clang::coro_wrapper]]` attr is missing. 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