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

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 16 06:40:09 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;
----------------
ilya-biryukov wrote:

The only downside of continuing as-is is that people who start using this warning might have to rewrite their code *if CWG responds that it is UB*.

Even though I don't expect to get an answer it's UB because there is a conversion to a function pointer on the same lambdas that's supposed to work in that case. The most natural implementation is to share the code between wherever call operators forwards to and where function pointers points at. So both should either work or not.

I guess this leads me to think that the approach of not showing the warning for empty lambdas is ok as the answer that it's UB is highly unlikely (IMO).

So LG.

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


More information about the cfe-commits mailing list