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/4] [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/4] 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()); } } } >From 19674e6cff8045269ef8655cd4e16816127af6f4 Mon Sep 17 00:00:00 2001 From: benedekaibas <[email protected]> Date: Sat, 29 Aug 2026 23:05:25 +0200 Subject: [PATCH 3/4] Fix formatting issue --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 0ab2d22b87fe2..c503d686fb407 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -3061,7 +3061,8 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, return std::make_pair(state->getLValue(FD, ParamSVal), FD->getType()); } - return std::make_pair(state->getLValue(FD, loc::MemRegionVal(PVR)), FD->getType()); + return std::make_pair(state->getLValue(FD, loc::MemRegionVal(PVR)), + FD->getType()); } } } >From 57ec566d0cf17f95ae58630740d8c90be7d2877b Mon Sep 17 00:00:00 2001 From: benedekaibas <[email protected]> Date: Mon, 31 Aug 2026 11:43:52 +0200 Subject: [PATCH 4/4] Correct comments and RUN line. --- clang/test/Analysis/explicit-lambda-capture.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/test/Analysis/explicit-lambda-capture.cpp b/clang/test/Analysis/explicit-lambda-capture.cpp index 2d98b80ce9637..89d249a63da43 100644 --- a/clang/test/Analysis/explicit-lambda-capture.cpp +++ b/clang/test/Analysis/explicit-lambda-capture.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -std=c++23 -analyzer-checker=core.DivideZero -verify %s +// RUN: %clang_analyze_cc1 -std=c++23 -analyzer-checker=core -verify %s int implicit_capture_by_value() { int d = 0; @@ -32,12 +32,12 @@ int gh218708_explicit_by_value_self() { 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. + auto lam = [d](this auto &&self) { return 1 / d; }; // no-warning 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. + auto lam = [d](this auto self) { return 1 / d; }; // no-warning return lam(); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
