https://github.com/zyn0217 updated https://github.com/llvm/llvm-project/pull/112177
>From 78657277495bbd1f82faef655c49320a4315272f Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Mon, 14 Oct 2024 17:42:17 +0800 Subject: [PATCH] [Clang] Fix a DeclContext mismatch when parsing nested lambda parameters --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaExpr.cpp | 9 ++++++++ clang/lib/Sema/SemaExprCXX.cpp | 2 +- .../SemaCXX/lambda-capture-type-deduction.cpp | 23 +++++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8d02cc3eae9fd9..3d6da43cf02f69 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -487,6 +487,8 @@ Bug Fixes to C++ Support - Clang now uses the correct set of template argument lists when comparing the constraints of out-of-line definitions and member templates explicitly specialized for a given implicit instantiation of a class template. (#GH102320) +- Fixed a bug in lambda captures where ``constexpr`` class-type objects were not properly considered ODR-used in + certain situations. (#GH47400), (#GH90896) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index f930a21ea870ec..dd6ac26cf49b94 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -18843,7 +18843,16 @@ bool Sema::tryCaptureVariable( // We need to sync up the Declaration Context with the // FunctionScopeIndexToStopAt if (FunctionScopeIndexToStopAt) { + assert(!FunctionScopes.empty() && "No function scopes to stop at?"); unsigned FSIndex = FunctionScopes.size() - 1; + // When we're parsing the lambda parameter list, the current DeclContext is + // NOT the lambda but its parent. So move away the current LSI before + // aligning DC and FunctionScopeIndexToStopAt. + if (auto *LSI = dyn_cast<LambdaScopeInfo>(FunctionScopes[FSIndex]); + LSI && !LSI->AfterParameterList) + --FSIndex; + assert(MaxFunctionScopesIndex <= FSIndex && + "FSIndex is larger than the size of function scopes?"); while (FSIndex != MaxFunctionScopesIndex) { DC = getLambdaAwareParentOfDeclContext(DC); --FSIndex; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index d490452e91c3bb..09ab83dcf21c22 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -8679,7 +8679,7 @@ static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures( while (isa_and_nonnull<CapturedDecl>(DC)) DC = DC->getParent(); assert( - CurrentLSI->CallOperator == DC && + (CurrentLSI->CallOperator == DC || !CurrentLSI->AfterParameterList) && "The current call operator must be synchronized with Sema's CurContext"); #endif // NDEBUG diff --git a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp index 7bf36a6a9cab73..32f09b38f84e23 100644 --- a/clang/test/SemaCXX/lambda-capture-type-deduction.cpp +++ b/clang/test/SemaCXX/lambda-capture-type-deduction.cpp @@ -297,3 +297,26 @@ void __trans_tmp_1() { } } + +namespace GH47400 { + +struct Foo {}; + +template <int, Foo f> struct Arr {}; + +template <int> struct S {}; + +constexpr bool foo() { + constexpr Foo f; // f constitutes an ODR-use + [&]<int is>() { + [&](Arr<is, f>) {}({}); + }.template operator()<42>(); + + constexpr int C = 1; + []() { + [](S<C>) { }; // ... while C doesn't + }; + return true; +} + +} // namespace GH47400 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits