[clang] [coroutines] Detect lifetime issues with coroutine lambda captures (PR #77066)

Utkarsh Saxena via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 8 01:45:46 PST 2024


================
@@ -7575,15 +7577,27 @@ static void visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
     Path.pop_back();
   };
 
-  if (ObjectArg && implicitObjectParamIsLifetimeBound(Callee))
-    VisitLifetimeBoundArg(Callee, ObjectArg);
-
   bool CheckCoroCall = false;
   if (const auto *RD = Callee->getReturnType()->getAsRecordDecl()) {
     CheckCoroCall = RD->hasAttr<CoroLifetimeBoundAttr>() &&
                     RD->hasAttr<CoroReturnTypeAttr>() &&
                     !Callee->hasAttr<CoroDisableLifetimeBoundAttr>();
   }
+
+  if (ObjectArg) {
+    bool CheckCoroObjArg = CheckCoroCall;
+    // Ignore `__promise.get_return_object()` as it is not lifetimebound.
+    if (CheckCoroObjArg && Callee->getDeclName().isIdentifier() &&
+        Callee->getName() == "get_return_object")
+      CheckCoroObjArg = false;
+    // Coroutine lambda objects with empty capture list are not lifetimebound.
+    if (auto *LE = dyn_cast<LambdaExpr>(ObjectArg->IgnoreImplicit());
+        LE && LE->captures().empty())
+      CheckCoroObjArg = false;
----------------
usx95 wrote:

I can explain. The lambda call operator is a coroutine and receives a lambda object as an implicit `this` param.
This lambda object would not be used or read in the coroutine body (as there is no capture list). But this analysis would still consider the object argument to be lifetime bound to the return object and would flag it the return object outlives the lambda object (which is true in the mentioned example).

Coro_lifetimebound, by design, has false positives because of it strictness. It considers all args to be lifetimebound but it might not be true in practice, for eg. if the arg is not used by the coro or used before first suspend.
Lambda with no capture list allows us to recognize one such instance where it can be proven to be a false positive always.

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


More information about the cfe-commits mailing list