Author: Utkarsh Saxena Date: 2026-02-19T18:49:01+01:00 New Revision: 6e9a7367139ab3fae805d66a66247865624e4c69
URL: https://github.com/llvm/llvm-project/commit/6e9a7367139ab3fae805d66a66247865624e4c69 DIFF: https://github.com/llvm/llvm-project/commit/6e9a7367139ab3fae805d66a66247865624e4c69.diff LOG: [LifetimeSafety] Fix 'this' origin handling in lambdas (#182300) Fixes https://github.com/llvm/llvm-project/issues/182291 Added: Modified: clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp clang/lib/Analysis/LifetimeSafety/Origins.cpp clang/test/Sema/warn-lifetime-safety-suggestions.cpp Removed: ################################################################################ diff --git a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp index 0b25a6a401e08..0b6e70212003c 100644 --- a/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp +++ b/clang/lib/Analysis/LifetimeSafety/FactsGenerator.cpp @@ -711,10 +711,10 @@ llvm::SmallVector<Fact *> FactsGenerator::issuePlaceholderLoans() { return {}; llvm::SmallVector<Fact *> PlaceholderLoanFacts; - if (const auto *MD = dyn_cast<CXXMethodDecl>(FD); MD && MD->isInstance()) { - OriginList *List = *FactMgr.getOriginMgr().getThisOrigins(); - const PlaceholderLoan *L = - FactMgr.getLoanMgr().createLoan<PlaceholderLoan>(MD); + if (auto ThisOrigins = FactMgr.getOriginMgr().getThisOrigins()) { + OriginList *List = *ThisOrigins; + const PlaceholderLoan *L = FactMgr.getLoanMgr().createLoan<PlaceholderLoan>( + cast<CXXMethodDecl>(FD)); PlaceholderLoanFacts.push_back( FactMgr.createFact<IssueFact>(L->getID(), List->getOuterOriginID())); } diff --git a/clang/lib/Analysis/LifetimeSafety/Origins.cpp b/clang/lib/Analysis/LifetimeSafety/Origins.cpp index 9141859a81345..a9e40d6b7aaf1 100644 --- a/clang/lib/Analysis/LifetimeSafety/Origins.cpp +++ b/clang/lib/Analysis/LifetimeSafety/Origins.cpp @@ -88,9 +88,15 @@ bool doesDeclHaveStorage(const ValueDecl *D) { } OriginManager::OriginManager(ASTContext &AST, const Decl *D) : AST(AST) { - if (const auto *MD = llvm::dyn_cast_or_null<CXXMethodDecl>(D); - MD && MD->isInstance()) - ThisOrigins = buildListForType(MD->getThisType(), MD); + // Create OriginList for 'this' expr. + const auto *MD = llvm::dyn_cast_or_null<CXXMethodDecl>(D); + if (!MD || !MD->isInstance()) + return; + // Lambdas can capture 'this' from the surrounding context, but in that case + // 'this' does not refer to the lambda object itself. + if (const CXXRecordDecl *P = MD->getParent(); P && P->isLambda()) + return; + ThisOrigins = buildListForType(MD->getThisType(), MD); } OriginList *OriginManager::createNode(const ValueDecl *D, QualType QT) { @@ -146,10 +152,8 @@ OriginList *OriginManager::getOrCreateList(const Expr *E) { QualType Type = E->getType(); // Special handling for 'this' expressions to share origins with the method's // implicit object parameter. - if (llvm::isa<CXXThisExpr>(E)) { - assert(ThisOrigins && "origins for 'this' should be set for a method decl"); + if (isa<CXXThisExpr>(E) && ThisOrigins) return *ThisOrigins; - } // Special handling for expressions referring to a decl to share origins with // the underlying decl. diff --git a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp index 1887b2f257226..4bd8a717d9d30 100644 --- a/clang/test/Sema/warn-lifetime-safety-suggestions.cpp +++ b/clang/test/Sema/warn-lifetime-safety-suggestions.cpp @@ -393,3 +393,13 @@ View Reassigned(View a) { a = Global; return a; } + +struct NoSuggestionForThisCapturedByLambda { + MyObj s; + bool cond; + void foo() { + auto x = [&]() { + return cond > 0 ? &this->s : &s; + }; + } +}; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
