[clang-tools-extra] [RFC] Perform lifetime bound checks for arguments to coroutine (PR #69360)

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 25 07:41:11 PDT 2023


================
@@ -0,0 +1,184 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra -Wno-error=unreachable-code -Wno-unused
+
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+
+#define CORO_TYPE [[clang::annotate("coro_type")]]
+#define CORO_UNSAFE [[clang::annotate("coro_unsafe")]]
+
+template <typename T> struct CORO_TYPE Gen {
+  struct promise_type {
+    Gen<T> get_return_object() {
+      return {};
+    }
+    suspend_always initial_suspend();
+    suspend_always final_suspend() noexcept;
+    void unhandled_exception();
+    void return_value(const T &t);
+
+    template <typename U>
+    auto await_transform(const Gen<U> &) {
+      struct awaitable {
+        bool await_ready() noexcept { return false; }
+        void await_suspend(std::coroutine_handle<>) noexcept {}
+        U await_resume() noexcept { return {}; }
+      };
+      return awaitable{};
+    }
+  };
+};
+
+template <typename T> using Co = Gen<T>;
+
+Gen<int> foo_coro(const int& b);
+
+Gen<int> plain_return_foo_decl(int b) {
+  return foo_coro(b); // expected-warning {{address of stack memory associated with parameter}}
+}
+
+Gen<int> foo_coro(const int& b) {
+  if (b > 0)
+    co_return 1;
+  co_return 2;
+}
+
+int getInt() { return 0; }
+
+Co<int> bar_coro(const int &b, int c) {
+  int x = co_await foo_coro(b);
+  int y = co_await foo_coro(1);
----------------
ChuanqiXu9 wrote:

How is this implemented? I mean how can we don't emit warnings to `co_await foo_coro(1)` but emit warnings to `auto unsafe1 = foo_coro(1);`? This is not showed in this patch itself.

I envision the reason may be that we will copy the parameters at the beginning of the coroutines. If it is indeed the reason, then it smells bad. Since the behavior depends that behavior implicitly.

For example, the behavior of `co_await foo_coro();` depends on the implementation of the corresponding awaiter. It is completely possible that `co_await foo_coro();` doing exactly the same thing with a standalone `foo_coro();`. But we may emit warnings for one place but not the other one.

https://github.com/llvm/llvm-project/pull/69360


More information about the cfe-commits mailing list