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

Reply via email to