================ @@ -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:
It may not result in runtime errors (even in sanitizers), because this is never accessed, but I wonder if it is actually legal or UB in the standard? AFAIK, calling a method if the object argument is `null` is UB, even if `this` is never accessed inside the method itself (citation needed, though, I looked at section of class member access and function call, but couldn't find a decisive wording there). So, a coroutine frame ends up keeping a pointer to a lambda that goes out of scope. After initial suspension and on resume, it will probably **still call a method on that same pointer** per C++ standard. Which makes me skew in the direction of warning for these cases two (but we need some proof from the standard gurus here) https://github.com/llvm/llvm-project/pull/77066 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits