llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Avi Kivity (avikivity)

<details>
<summary>Changes</summary>

09231ed02384 ("[clang] Delay dependent co_return promise calls") made 
Sema::BuildCoreturnStmt return early for a type-dependent operand, before 
reaching the ActOnFinishFullExpr() call that every other path performs.

Inside a lambda, a reference to a variable of an enclosing function is not 
captured immediately: DoMarkPotentialCapture() only records it via 
LambdaScopeInfo::addPotentialCapture(), and relies on ActOnFinishFullExpr() to 
turn it into an actual capture and odr-use. Skipping that on the dependent path 
silently drops the pending capture, so a variable mentioned only in the operand 
of a dependent co_return never gets a capture field. When the generic lambda's 
call operator is later instantiated from another context, Sema tries to capture 
the variable again and rejects valid code with "reference to local variable 'p' 
declared in enclosing function".

Finish the full-expression on the dependent path as well.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@<!-- -->anthropic.com&gt;

Fixes #<!-- -->220233

---
Full diff: https://github.com/llvm/llvm-project/pull/220234.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaCoroutine.cpp (+8-2) 
- (modified) clang/test/SemaCXX/coreturn.cpp (+47) 


``````````diff
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index b46efba09500f..d22260b887415 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -1058,9 +1058,15 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, 
Expr *E,
   // A type-dependent operand can init to either void or non-void.
   // Delay selecting return_void or return_value until template init
   // rebuilds the co_return statement with the operand type.
-  if (E && !isa<InitListExpr>(E) && E->isTypeDependent())
+  if (E && !isa<InitListExpr>(E) && E->isTypeDependent()) {
+    // Still finish the full-expression, so that potential captures in the
+    // operand are turned into actual captures of the enclosing lambda.
+    ExprResult FE = ActOnFinishFullExpr(E, /*DiscardedValue=*/false);
+    if (FE.isInvalid())
+      return StmtError();
     return new (Context)
-        CoreturnStmt(Loc, E, /*PromiseCall=*/nullptr, IsImplicit);
+        CoreturnStmt(Loc, FE.get(), /*PromiseCall=*/nullptr, IsImplicit);
+  }
 
   VarDecl *Promise = FSI->CoroutinePromise;
   ExprResult PC;
diff --git a/clang/test/SemaCXX/coreturn.cpp b/clang/test/SemaCXX/coreturn.cpp
index 8fb2506848c3d..8ed78d6f0b9a2 100644
--- a/clang/test/SemaCXX/coreturn.cpp
+++ b/clang/test/SemaCXX/coreturn.cpp
@@ -164,3 +164,50 @@ coro f(Ctx &ctx) {
 
 void use(Ctx &ctx) { f<int>(ctx); }
 }
+
+namespace dependent_coreturn_lambda_capture {
+// A variable of the enclosing function referenced only from the type-dependent
+// operand of a co_return must still be captured by the enclosing lambda.
+struct coro_void {
+  struct promise_type {
+    coro_void get_return_object();
+    suspend_never initial_suspend();
+    suspend_never final_suspend() noexcept;
+    void unhandled_exception();
+    void return_void();
+  };
+};
+
+struct coro_value {
+  struct promise_type {
+    coro_value get_return_object();
+    suspend_never initial_suspend();
+    suspend_never final_suspend() noexcept;
+    void unhandled_exception();
+    void return_value(int);
+  };
+};
+
+template <typename T> void use_void(int &, T);
+template <typename T> int use_value(int &, T);
+
+// Instantiates the generic lambda from a context that no longer has the
+// enclosing function's scopes on the stack.
+template <typename F> void call(F f) {
+  int t = 0;
+  f(t);
+}
+
+void captured_by_dependent_coreturn(int p) {
+  call([&](auto &t) -> coro_void {
+    if (t)
+      co_return;
+    co_return use_void(p, t);
+  });
+  call([&](auto &t) -> coro_value {
+    if (t)
+      co_return 0;
+    co_return use_value(p, t);
+  });
+}
+} // namespace dependent_coreturn_lambda_capture

``````````

</details>


https://github.com/llvm/llvm-project/pull/220234
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to