https://github.com/benedekaibas updated 
https://github.com/llvm/llvm-project/pull/219726

>From cd800a911d402fafe1f32e4ff2709d5061732e08 Mon Sep 17 00:00:00 2001
From: benedekaibas <[email protected]>
Date: Sat, 29 Aug 2026 22:41:18 +0200
Subject: [PATCH 1/2] [analyzer] Resolve lambda captures for explicit object
 parameters

---
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp  | 26 +++++++++--
 .../test/Analysis/explicit-lambda-capture.cpp | 43 +++++++++++++++++++
 2 files changed, 65 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/Analysis/explicit-lambda-capture.cpp

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index e6349eb4eba2a..01e05924a2537 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -3040,12 +3040,30 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, 
const NamedDecl *D,
       // Sema follows a sequence of complex rules to determine whether the
       // variable should be captured.
       if (const FieldDecl *FD = LambdaCaptureFields[VD]) {
-        Loc CXXThis = svalBuilder.getCXXThis(MD, SF);
-        SVal CXXThisVal = state->getSVal(CXXThis);
-        return std::make_pair(state->getLValue(FD, CXXThisVal), FD->getType());
+        if (MD->isImplicitObjectMemberFunction()) {
+          Loc CXXThis = svalBuilder.getCXXThis(MD, SF);
+          SVal CXXThisVal = state->getSVal(CXXThis);
+          return std::make_pair(state->getLValue(FD, CXXThisVal),
+                                FD->getType());
+        }
+        const ParmVarDecl *PVD = MD->getParamDecl(0);
+        if (const Expr *CallSite = SF->getCallSite()) {
+          unsigned Idx = PVD->getFunctionScopeIndex();
+          const ParamVarRegion *PVR =
+              state->getStateManager().getRegionManager().getParamVarRegion(
+                  CallSite, Idx, SF);
+          const Expr *SelfArgExpr = cast<CallExpr>(CallSite)->getArg(0);
+          state =
+              state->bindLoc(loc::MemRegionVal(PVR),
+                             state->getSVal(SelfArgExpr, SF->getParent()), SF);
+          SVal ParamSVal = state->getSVal(loc::MemRegionVal(PVR));
+          if (!PVD->getType()->isReferenceType())
+            return std::make_pair(state->getLValue(FD, loc::MemRegionVal(PVR)),
+                                  FD->getType());
+          return std::make_pair(state->getLValue(FD, ParamSVal), 
FD->getType());
+        }
       }
     }
-
     return std::nullopt;
   };
 
diff --git a/clang/test/Analysis/explicit-lambda-capture.cpp 
b/clang/test/Analysis/explicit-lambda-capture.cpp
new file mode 100644
index 0000000000000..2d98b80ce9637
--- /dev/null
+++ b/clang/test/Analysis/explicit-lambda-capture.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -analyze -std=c++23 -analyzer-checker=core.DivideZero 
-verify %s
+
+int implicit_capture_by_value() {
+  int d = 0;
+  auto lam = [d]() { return 1 / d; }; // expected-warning {{Division by zero}}
+  return lam(); 
+}
+
+int explicit_rvalue_self_capture_by_reference() {
+  int d = 0;
+  auto lam = [&d](this auto &&self) { return 1 / d; }; // expected-warning 
{{Division by zero}}
+  return lam(); 
+}
+
+int gh218708_explicit_rvalue_self() {
+  int d = 0;
+  auto lam = [d](this auto &&self) { return 1 / d; }; // expected-warning 
{{Division by zero}}
+  return lam(); 
+}
+
+int gh218708_explicit_lvalue_self() {
+  int d = 0;
+  auto lam = [d](this auto &self) { return 1 / d; }; // expected-warning 
{{Division by zero}}
+  return lam(); 
+}
+
+int gh218708_explicit_by_value_self() {
+  int d = 0;
+  auto lam = [d](this auto self) { return 1 / d; }; // expected-warning 
{{Division by zero}}
+  return lam();
+}
+
+int explicit_rvalue_no_error() {
+  int d = 5;
+  auto lam = [d](this auto &&self) { return 1 / d; }; // 'd' is non-zero so 
there is no division by zero error. 
+  return lam(); 
+}
+
+int explicit_by_value_no_error() {
+  int d = 9;
+  auto lam = [d](this auto self) { return 1 / d; }; // 'd' is non-zero so 
there is no division by zero error.
+  return lam();
+}

>From 14f335aaecfcfe15de5aa0550c210b97e20a5283 Mon Sep 17 00:00:00 2001
From: benedekaibas <[email protected]>
Date: Sat, 29 Aug 2026 22:58:50 +0200
Subject: [PATCH 2/2] Fix unconditional compute for the reference type
 construction.

---
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp 
b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 01e05924a2537..0ab2d22b87fe2 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -3053,14 +3053,15 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, 
const NamedDecl *D,
               state->getStateManager().getRegionManager().getParamVarRegion(
                   CallSite, Idx, SF);
           const Expr *SelfArgExpr = cast<CallExpr>(CallSite)->getArg(0);
-          state =
-              state->bindLoc(loc::MemRegionVal(PVR),
-                             state->getSVal(SelfArgExpr, SF->getParent()), SF);
-          SVal ParamSVal = state->getSVal(loc::MemRegionVal(PVR));
-          if (!PVD->getType()->isReferenceType())
-            return std::make_pair(state->getLValue(FD, loc::MemRegionVal(PVR)),
+          if (PVD->getType()->isReferenceType()) {
+            state = state->bindLoc(loc::MemRegionVal(PVR),
+                                   state->getSVal(SelfArgExpr, 
SF->getParent()),
+                                   SF);
+            SVal ParamSVal = state->getSVal(loc::MemRegionVal(PVR));
+            return std::make_pair(state->getLValue(FD, ParamSVal),
                                   FD->getType());
-          return std::make_pair(state->getLValue(FD, ParamSVal), 
FD->getType());
+          }
+          return std::make_pair(state->getLValue(FD, loc::MemRegionVal(PVR)), 
FD->getType());
         }
       }
     }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to