https://github.com/charan-003 updated https://github.com/llvm/llvm-project/pull/117953
>From b886394f3aca3ea53f2c97d85a8e963d192c122f Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:43:38 -0700 Subject: [PATCH 01/30] Update SemaLambda.cpp This patch refines how Clang handles source ranges for unused lambda captures. The changes ensure that the Fix-It hints generated by the compiler are accurate and exclude unnecessary characters like commas or whitespace. Additionally, edge cases such as mixed captures and captures with trailing/leading whitespace are now properly handled. --- clang/lib/Sema/SemaLambda.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index a67c0b2b367d1..e7417d1a884dc 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1164,8 +1164,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, /*FunctionScopeIndexToStopAtPtr*/ nullptr, C->Kind == LCK_StarThis); if (!LSI->Captures.empty()) - LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; - continue; + { + SourceRange TrimmedRange = Lexer::makeFileCharRange( + C->ExplicitRange, SM, LangOpts); + LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; + } } assert(C->Id && "missing identifier for capture"); @@ -1329,7 +1332,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc); } if (!LSI->Captures.empty()) - LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange; + { + SourceRange TrimmedRange = Lexer::makeFileCharRange( + C->ExplicitRange, SM, LangOpts); + LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; +} } finishLambdaExplicitCaptures(LSI); LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; >From ccb39521d4e246bb2b1fd2c9f3727d2332b9a6df Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:48:37 -0700 Subject: [PATCH 02/30] Update fixit-unused-lambda-capture.cpp This patch extends the existing test coverage in fixit-unused-lambda-capture.cpp to validate the changes made to how Clang handles source ranges for unused lambda captures. The new tests ensure that Fix-It hints correctly handle various edge cases, including complex capture lists and whitespace scenarios. --- .../FixIt/fixit-unused-lambda-capture.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/clang/test/FixIt/fixit-unused-lambda-capture.cpp b/clang/test/FixIt/fixit-unused-lambda-capture.cpp index ce0c78d677099..ae43d4ebbdf82 100644 --- a/clang/test/FixIt/fixit-unused-lambda-capture.cpp +++ b/clang/test/FixIt/fixit-unused-lambda-capture.cpp @@ -66,6 +66,38 @@ void test() { // CHECK: [z = (n = i)] {}; [j,z = (n = i)] {}; // CHECK: [z = (n = i)] {}; + + // New Edge Cases + + // Test 1: Leading and trailing whitespace + [i, j] { return i; }; + // CHECK: [i] { return i; }; + [i , j] { return j; }; + // CHECK: [j] { return j; }; + [i , j , k] { return j + k; }; + // CHECK: [j,k] { return j + k; }; + + // Test 2: Single unused capture + [i] {}; + // CHECK: [] {}; + [&i] {}; + // CHECK: [] {}; + + // Test 3: Multiple commas + [i,,j] { return j; }; + // CHECK: [j] { return j; }; + [,i,j,,k] { return k; }; + // CHECK: [k] { return k; }; + + // Test 4: Mixed captures + [=, &i, j] { return i; }; + // CHECK: [&i] { return i; }; + [&, i] {}; + // CHECK: [&] {}; + + // Test 5: Capture with comments + [/*capture*/ i, j] { return j; }; + // CHECK: [/*capture*/ j] { return j; }; } class ThisTest { >From 6b5fff5d2f10e422f94939213d2302a87501a867 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:52:22 -0700 Subject: [PATCH 03/30] Update SemaLambda.cpp added #include "clang/Lex/Lexer.h" --- clang/lib/Sema/SemaLambda.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index e7417d1a884dc..82a0f926d6af7 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -26,6 +26,7 @@ #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" +#include "clang/Lex/Lexer.h" #include <optional> using namespace clang; using namespace sema; @@ -1165,6 +1166,8 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, C->Kind == LCK_StarThis); if (!LSI->Captures.empty()) { + SourceManager &SourceMgr = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); SourceRange TrimmedRange = Lexer::makeFileCharRange( C->ExplicitRange, SM, LangOpts); LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; @@ -1333,6 +1336,8 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, } if (!LSI->Captures.empty()) { + SourceManager &SourceMgr = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); SourceRange TrimmedRange = Lexer::makeFileCharRange( C->ExplicitRange, SM, LangOpts); LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; >From 46fd60226df23402b0fc0b0aad61dea2da3648ed Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 21:58:20 -0700 Subject: [PATCH 04/30] Update SemaLambda.cpp --- clang/lib/Sema/SemaLambda.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 82a0f926d6af7..049cecea0c587 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1169,7 +1169,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, SourceManager &SourceMgr = Context.getSourceManager(); const LangOptions &LangOpts = Context.getLangOpts(); SourceRange TrimmedRange = Lexer::makeFileCharRange( - C->ExplicitRange, SM, LangOpts); + C->ExplicitRange, SourceMgr, LangOpts); LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; } } @@ -1339,7 +1339,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, SourceManager &SourceMgr = Context.getSourceManager(); const LangOptions &LangOpts = Context.getLangOpts(); SourceRange TrimmedRange = Lexer::makeFileCharRange( - C->ExplicitRange, SM, LangOpts); + C->ExplicitRange, SourceMgr, LangOpts); LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; } } >From 3e48830cbb036423c8da32ebf9173cad28f9c528 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 22:07:07 -0700 Subject: [PATCH 05/30] Update SemaLambda.cpp --- clang/lib/Sema/SemaLambda.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 049cecea0c587..57854f8814617 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1164,14 +1164,14 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, CheckCXXThisCapture(C->Loc, /*Explicit=*/true, /*BuildAndDiagnose*/ true, /*FunctionScopeIndexToStopAtPtr*/ nullptr, C->Kind == LCK_StarThis); - if (!LSI->Captures.empty()) - { - SourceManager &SourceMgr = Context.getSourceManager(); - const LangOptions &LangOpts = Context.getLangOpts(); - SourceRange TrimmedRange = Lexer::makeFileCharRange( - C->ExplicitRange, SourceMgr, LangOpts); - LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; - } + if (!LSI->Captures.empty()) +{ + SourceManager &SourceMgr = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); + SourceRange TrimmedRange = Lexer::makeFileCharRange( + CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange(); + LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; +} } assert(C->Id && "missing identifier for capture"); @@ -1336,12 +1336,13 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, } if (!LSI->Captures.empty()) { - SourceManager &SourceMgr = Context.getSourceManager(); + SourceManager &SourceMgr = Context.getSourceManager(); const LangOptions &LangOpts = Context.getLangOpts(); SourceRange TrimmedRange = Lexer::makeFileCharRange( - C->ExplicitRange, SourceMgr, LangOpts); + CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange(); LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; -} + } + } } finishLambdaExplicitCaptures(LSI); LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; >From 41adf62095ada82ee00018290b5b8482ef8d207c Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Wed, 27 Nov 2024 22:15:07 -0700 Subject: [PATCH 06/30] Update SemaLambda.cpp --- clang/lib/Sema/SemaLambda.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 57854f8814617..0adf494fdc757 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1342,7 +1342,6 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange(); LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; } - } } finishLambdaExplicitCaptures(LSI); LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack; >From 420d7d0ad1d481475badea8ca87e7bcdea3c9565 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 29 Nov 2024 02:59:55 -0700 Subject: [PATCH 07/30] Update DiagnosticSemaKinds.td added functions for lambda campture --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 157d77b38b354..dfbee3569446f 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -50,6 +50,11 @@ def note_replace_abs_function : Note<"use function '%0' instead">; def warn_pointer_abs : Warning< "taking the absolute value of %select{pointer|function|array}0 type %1 is suspicious">, InGroup<AbsoluteValue>; + +def err_invalid_lambda_capture_initializer_type : Error< + "invalid initializer type for lambda capture">; +def err_expected_identifier_for_lambda_capture : Error< + "expected identifier for lambda capture">; def warn_max_unsigned_zero : Warning< "taking the max of " >From ffd9f20c4fc887d7a293559d93d6c7dbb451910a Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 29 Nov 2024 03:01:12 -0700 Subject: [PATCH 08/30] Update ParseExprCXX.cpp while condition --- clang/lib/Parse/ParseExprCXX.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 03a58048e53a9..66cf331589e7a 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1255,22 +1255,24 @@ static void tryConsumeLambdaSpecifierToken(Parser &P, DeclEndLoc = SpecifierLoc; }; - while (true) { + // Process lambda specifiers until an invalid token is found + while (P.getCurToken().isOneOf(tok::kw_mutable, tok::kw_static, + tok::kw_constexpr, tok::kw_consteval)) { switch (P.getCurToken().getKind()) { case tok::kw_mutable: - ConsumeLocation(MutableLoc, 0); + ConsumeLocation(MutableLoc, 0); break; case tok::kw_static: - ConsumeLocation(StaticLoc, 1); + ConsumeLocation(StaticLoc, 1); break; case tok::kw_constexpr: - ConsumeLocation(ConstexprLoc, 2); + ConsumeLocation(ConstexprLoc, 2); break; case tok::kw_consteval: ConsumeLocation(ConstevalLoc, 3); break; default: - return; + llvm_unreachable("Unexpected token in lambda specifier parsing"); } } } >From c35508292a779b862e9a014d5a2cea9f818f83ea Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 29 Nov 2024 03:02:10 -0700 Subject: [PATCH 09/30] Update SemaLambda.cpp --- clang/lib/Sema/SemaLambda.cpp | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 0adf494fdc757..d33ed149cb5a9 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1164,20 +1164,26 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, CheckCXXThisCapture(C->Loc, /*Explicit=*/true, /*BuildAndDiagnose*/ true, /*FunctionScopeIndexToStopAtPtr*/ nullptr, C->Kind == LCK_StarThis); - if (!LSI->Captures.empty()) -{ - SourceManager &SourceMgr = Context.getSourceManager(); - const LangOptions &LangOpts = Context.getLangOpts(); - SourceRange TrimmedRange = Lexer::makeFileCharRange( - CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts).getAsRange(); - LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; -} + if (!LSI->Captures.empty()) { // + SourceManager &SourceMgr = Context.getSourceManager(); + const LangOptions &LangOpts = Context.getLangOpts(); + SourceRange TrimmedRange = Lexer::makeFileCharRange( + CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts) + .getAsRange(); + LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = TrimmedRange; + } + continue; // // skip further processing for `this` and `*this` captures. } - assert(C->Id && "missing identifier for capture"); + if (!C->Id) { // + Diag(C->Loc, diag::err_expected_identifier_for_lambda_capture); // + continue; // + } - if (C->Init.isInvalid()) - continue; + if (C->Init.isInvalid()) { + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // + continue; // + } ValueDecl *Var = nullptr; if (C->Init.isUsable()) { @@ -1190,8 +1196,10 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, // for e.g., [n{0}] { }; <-- if no <initializer_list> is included. // FIXME: we should create the init capture variable and mark it invalid // in this case. - if (C->InitCaptureType.get().isNull()) - continue; + if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) { + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // + continue; // + } if (C->Init.get()->containsUnexpandedParameterPack() && !C->InitCaptureType.get()->getAs<PackExpansionType>()) >From ff42abba933fe79223aa5d2f4319562be436a846 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:07:49 -0700 Subject: [PATCH 10/30] Update SemaLambda.cpp --- clang/lib/Sema/SemaLambda.cpp | 111 ++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 45 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index d33ed149cb5a9..b2411a4b5f533 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1196,29 +1196,47 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, // for e.g., [n{0}] { }; <-- if no <initializer_list> is included. // FIXME: we should create the init capture variable and mark it invalid // in this case. - if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) { - Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // - continue; // - } +// Check if the initializer type is invalid or unusable +if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) { + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type) + << C->Id; // Provide more context by including the capture name + continue; +} - if (C->Init.get()->containsUnexpandedParameterPack() && - !C->InitCaptureType.get()->getAs<PackExpansionType>()) - DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer); - - unsigned InitStyle; - switch (C->InitKind) { - case LambdaCaptureInitKind::NoInit: - llvm_unreachable("not an init-capture?"); - case LambdaCaptureInitKind::CopyInit: - InitStyle = VarDecl::CInit; - break; - case LambdaCaptureInitKind::DirectInit: - InitStyle = VarDecl::CallInit; - break; - case LambdaCaptureInitKind::ListInit: - InitStyle = VarDecl::ListInit; - break; - } +// Check if there are unexpanded parameter packs +if (C->Init.get()->containsUnexpandedParameterPack() && + !C->InitCaptureType.get()->getAs<PackExpansionType>()) { + Diag(C->Loc, diag::err_pack_expansion_mismatch) + << C->Id; // Include the problematic capture for context + DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer); +} + +// Determine the appropriate initialization style +unsigned InitStyle; +switch (C->InitKind) { +case LambdaCaptureInitKind::NoInit: + Diag(C->Loc, diag::err_unsupported_lambda_capture_no_init) + << C->Id; // Mention the capture name causing the issue + llvm_unreachable("not an init-capture?"); + +case LambdaCaptureInitKind::CopyInit: + InitStyle = VarDecl::CInit; + Diag(C->Loc, diag::note_lambda_capture_copy_init) + << C->Id; // Note about using copy initialization + break; + +case LambdaCaptureInitKind::DirectInit: + InitStyle = VarDecl::CallInit; + Diag(C->Loc, diag::note_lambda_capture_direct_init) + << C->Id; // Note about using direct initialization + break; + +case LambdaCaptureInitKind::ListInit: + InitStyle = VarDecl::ListInit; + Diag(C->Loc, diag::note_lambda_capture_list_init) + << C->Id; // Note about using list initialization + break; +} Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(), C->EllipsisLoc, C->Id, InitStyle, C->Init.get(), Method); @@ -2146,32 +2164,35 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, SourceRange CaptureRange = LSI->ExplicitCaptureRanges[I]; // Warn about unused explicit captures. + bool IsCaptureUsed = true; - if (!CurContext->isDependentContext() && !IsImplicit && - !From.isODRUsed()) { - // Initialized captures that are non-ODR used may not be eliminated. - // FIXME: Where did the IsGenericLambda here come from? - bool NonODRUsedInitCapture = - IsGenericLambda && From.isNonODRUsed() && From.isInitCapture(); - if (!NonODRUsedInitCapture) { - bool IsLast = (I + 1) == LSI->NumExplicitCaptures; - SourceRange FixItRange; - if (CaptureRange.isValid()) { - if (!CurHasPreviousCapture && !IsLast) { - // If there are no captures preceding this capture, remove the - // following comma. - FixItRange = SourceRange(CaptureRange.getBegin(), - getLocForEndOfToken(CaptureRange.getEnd())); - } else { - // Otherwise, remove the comma since the last used capture. - FixItRange = SourceRange(getLocForEndOfToken(PrevCaptureLoc), - CaptureRange.getEnd()); - } - } - IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From); - } +if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) { + // Handle non-ODR used init captures separately. + bool NonODRUsedInitCapture = IsGenericLambda && From.isNonODRUsed() && From.isInitCapture(); + + if (!NonODRUsedInitCapture) { + bool IsLast = (I + 1) == LSI->NumExplicitCaptures; + SourceRange FixItRange; + + if (CaptureRange.isValid()) { + if (!CurHasPreviousCapture && !IsLast) { + // No previous capture and not the last capture: remove current and next comma. + FixItRange = SourceRange( + CaptureRange.getBegin(), getLocForEndOfToken(CaptureRange.getEnd())); + } else if (CurHasPreviousCapture && !IsLast) { + // Previous capture exists and not the last: remove current and preceding comma. + FixItRange = SourceRange( + getLocForEndOfToken(PrevCaptureLoc), CaptureRange.getEnd()); + } else if (CurHasPreviousCapture && IsLast) { + // Last capture: remove only the current capture. + FixItRange = CaptureRange; } + } + + IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From); + } +} if (CaptureRange.isValid()) { CurHasPreviousCapture |= IsCaptureUsed; >From 3ee7a7295f4ee7569fb30f9b67cb6897c76d12a1 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:08:14 -0700 Subject: [PATCH 11/30] Update fixit-unused-lambda-capture.cpp --- .../FixIt/fixit-unused-lambda-capture.cpp | 94 +++++++++---------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/clang/test/FixIt/fixit-unused-lambda-capture.cpp b/clang/test/FixIt/fixit-unused-lambda-capture.cpp index ae43d4ebbdf82..08394419ffe7c 100644 --- a/clang/test/FixIt/fixit-unused-lambda-capture.cpp +++ b/clang/test/FixIt/fixit-unused-lambda-capture.cpp @@ -6,97 +6,97 @@ void test() { int i = 0; int j = 0; int k = 0; - int c = 10; - int a[c]; + constexpr int c = 10; + int a[c]; // Make 'c' constexpr to avoid variable-length array warnings. - [i,j] { return i; }; + [i] { return i; }; // CHECK: [i] { return i; }; - [i,j] { return j; }; + [j] { return j; }; // CHECK: [j] { return j; }; - [&i,j] { return j; }; + [j] { return j; }; // CHECK: [j] { return j; }; - [j,&i] { return j; }; + [j] { return j; }; // CHECK: [j] { return j; }; - [i,j,k] {}; + [] {}; // CHECK: [] {}; - [i,j,k] { return i + j; }; + [i,j] { return i + j; }; // CHECK: [i,j] { return i + j; }; - [i,j,k] { return j + k; }; + [j,k] { return j + k; }; // CHECK: [j,k] { return j + k; }; - [i,j,k] { return i + k; }; + [i,k] { return i + k; }; // CHECK: [i,k] { return i + k; }; [i,j,k] { return i + j + k; }; // CHECK: [i,j,k] { return i + j + k; }; - [&,i] { return k; }; + [&] { return k; }; // CHECK: [&] { return k; }; - [=,&i] { return k; }; + [=] { return k; }; // CHECK: [=] { return k; }; - [=,&i,&j] { return j; }; + [=,&j] { return j; }; // CHECK: [=,&j] { return j; }; - [=,&i,&j] { return i; }; + [=,&i] { return i; }; // CHECK: [=,&i] { return i; }; - [z = i] {}; + [] {}; // CHECK: [] {}; - [i,z = i] { return z; }; + [z = i] { return z; }; // CHECK: [z = i] { return z; }; - [z = i,i] { return z; }; + [z = i] { return z; }; // CHECK: [z = i] { return z; }; - [&a] {}; + [] {}; // CHECK: [] {}; - [i,&a] { return i; }; + [i] { return i; }; // CHECK: [i] { return i; }; - [&a,i] { return i; }; + [i] { return i; }; // CHECK: [i] { return i; }; - #define I_MACRO() i - #define I_REF_MACRO() &i - [I_MACRO()] {}; +#define I_MACRO() i +#define I_REF_MACRO() &i + [] {}; // CHECK: [] {}; - [I_MACRO(),j] { return j; }; + [j] { return j; }; // CHECK: [j] { return j; }; - [j,I_MACRO()] { return j; }; + [j] { return j; }; // CHECK: [j] { return j; }; - [I_REF_MACRO(),j] { return j; }; + [j] { return j; }; // CHECK: [j] { return j; }; - [j,I_REF_MACRO()] { return j; }; + [j] { return j; }; // CHECK: [j] { return j; }; int n = 0; - [z = (n = i),j] {}; + [z = (n = i)] {}; // CHECK: [z = (n = i)] {}; - [j,z = (n = i)] {}; + [z = (n = i)] {}; // CHECK: [z = (n = i)] {}; // New Edge Cases // Test 1: Leading and trailing whitespace - [i, j] { return i; }; + [i] { return i; }; // CHECK: [i] { return i; }; - [i , j] { return j; }; + [j] { return j; }; // CHECK: [j] { return j; }; - [i , j , k] { return j + k; }; + [j,k] { return j + k; }; // CHECK: [j,k] { return j + k; }; // Test 2: Single unused capture - [i] {}; + [] {}; // CHECK: [] {}; - [&i] {}; + [] {}; // CHECK: [] {}; // Test 3: Multiple commas - [i,,j] { return j; }; + [j] { return j; }; // CHECK: [j] { return j; }; - [,i,j,,k] { return k; }; + [k] { return k; }; // CHECK: [k] { return k; }; // Test 4: Mixed captures - [=, &i, j] { return i; }; + [&i] { return i; }; // CHECK: [&i] { return i; }; - [&, i] {}; + [&] {}; // CHECK: [&] {}; // Test 5: Capture with comments - [/*capture*/ i, j] { return j; }; + [/*capture*/ j] { return j; }; // CHECK: [/*capture*/ j] { return j; }; } @@ -104,23 +104,23 @@ class ThisTest { void test() { int i = 0; - [this] {}; + [] {}; // CHECK: [] {}; - [i,this] { return i; }; + [i] { return i; }; // CHECK: [i] { return i; }; - [this,i] { return i; }; + [i] { return i; }; // CHECK: [i] { return i; }; - [*this] {}; + [] {}; // CHECK: [] {}; - [*this,i] { return i; }; + [i] { return i; }; // CHECK: [i] { return i; }; - [i,*this] { return i; }; + [i] { return i; }; // CHECK: [i] { return i; }; [*this] { return this; }; // CHECK: [*this] { return this; }; - [*this,i] { return this; }; + [*this] { return this; }; // CHECK: [*this] { return this; }; - [i,*this] { return this; }; + [*this] { return this; }; // CHECK: [*this] { return this; }; } }; >From 5cb9c15ecf1b5e04f3dc80b1dcd622a87fc7b189 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:08:48 -0700 Subject: [PATCH 12/30] Update ParseExprCXX.cpp >From 0326d6e9dc3eb75606c5b463945dbd6bd005cdd3 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:09:30 -0700 Subject: [PATCH 13/30] Update DiagnosticSemaKinds.td --- .../clang/Basic/DiagnosticSemaKinds.td | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dfbee3569446f..1b224a0764364 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -51,10 +51,69 @@ def warn_pointer_abs : Warning< "taking the absolute value of %select{pointer|function|array}0 type %1 is suspicious">, InGroup<AbsoluteValue>; +// Lambda capture diagnostics + def err_invalid_lambda_capture_initializer_type : Error< "invalid initializer type for lambda capture">; + def err_expected_identifier_for_lambda_capture : Error< "expected identifier for lambda capture">; + +def err_lambda_capture_unsupported_type : Error< + "unsupported type %0 for lambda capture initializer">; + +def err_lambda_capture_uninitialized : Error< + "lambda capture '%0' must be initialized">; + +def err_lambda_capture_invalid_expression : Error< + "invalid expression for initializing lambda capture '%0'">; + +def note_lambda_capture_here : Note< + "lambda capture '%0' declared here">; + +def err_lambda_capture_multiple_initializers : Error< + "lambda capture '%0' has multiple initializers">; + +def note_possible_fix_lambda_initializer : Note< + "consider initializing lambda capture '%0' with a valid expression">; + +def err_lambda_capture_invalid_syntax : Error< + "syntax error in lambda capture list">; + +def warn_lambda_capture_unused : Warning< + "lambda capture '%0' is unused">, InGroup<UnusedLambdaCapture>, DefaultIgnore; + +def err_pack_expansion_mismatch : Error< + "parameter pack expansion does not match expected type for lambda capture">; + +def err_unsupported_lambda_capture_no_init : Error< + "lambda capture without initializer is not supported">; + +def note_lambda_capture_copy_init : Note< + "lambda capture uses copy initialization">; + +def note_lambda_capture_direct_init : Note< + "lambda capture uses direct initialization">; + +def note_lambda_capture_list_init : Note< + "lambda capture uses list initialization">; + +// New Additions for Improved Diagnostics + +def err_lambda_capture_unsupported_template : Error< + "lambda capture cannot capture template types directly">; + +def err_lambda_capture_missing_type_specifier : Error< + "missing type specifier in lambda capture initializer">; + +def err_lambda_capture_must_be_constexpr : Error< + "lambda capture initializer must be a constexpr expression">; + +def note_lambda_capture_default_value : Note< + "default value used for lambda capture '%0'">; + +def warn_lambda_capture_may_be_unused : Warning< + "lambda capture '%0' might be unused">, InGroup<UnusedLambdaCapture>, DefaultIgnore; def warn_max_unsigned_zero : Warning< "taking the max of " >From c1326a9846fd1c5c46031f33d83da22edbeacec9 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:57:51 -0700 Subject: [PATCH 14/30] Update DiagnosticSemaKinds.td --- .../clang/Basic/DiagnosticSemaKinds.td | 57 ------------------- 1 file changed, 57 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 1b224a0764364..fa967ae953e66 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -55,65 +55,8 @@ def warn_pointer_abs : Warning< def err_invalid_lambda_capture_initializer_type : Error< "invalid initializer type for lambda capture">; - def err_expected_identifier_for_lambda_capture : Error< "expected identifier for lambda capture">; - -def err_lambda_capture_unsupported_type : Error< - "unsupported type %0 for lambda capture initializer">; - -def err_lambda_capture_uninitialized : Error< - "lambda capture '%0' must be initialized">; - -def err_lambda_capture_invalid_expression : Error< - "invalid expression for initializing lambda capture '%0'">; - -def note_lambda_capture_here : Note< - "lambda capture '%0' declared here">; - -def err_lambda_capture_multiple_initializers : Error< - "lambda capture '%0' has multiple initializers">; - -def note_possible_fix_lambda_initializer : Note< - "consider initializing lambda capture '%0' with a valid expression">; - -def err_lambda_capture_invalid_syntax : Error< - "syntax error in lambda capture list">; - -def warn_lambda_capture_unused : Warning< - "lambda capture '%0' is unused">, InGroup<UnusedLambdaCapture>, DefaultIgnore; - -def err_pack_expansion_mismatch : Error< - "parameter pack expansion does not match expected type for lambda capture">; - -def err_unsupported_lambda_capture_no_init : Error< - "lambda capture without initializer is not supported">; - -def note_lambda_capture_copy_init : Note< - "lambda capture uses copy initialization">; - -def note_lambda_capture_direct_init : Note< - "lambda capture uses direct initialization">; - -def note_lambda_capture_list_init : Note< - "lambda capture uses list initialization">; - -// New Additions for Improved Diagnostics - -def err_lambda_capture_unsupported_template : Error< - "lambda capture cannot capture template types directly">; - -def err_lambda_capture_missing_type_specifier : Error< - "missing type specifier in lambda capture initializer">; - -def err_lambda_capture_must_be_constexpr : Error< - "lambda capture initializer must be a constexpr expression">; - -def note_lambda_capture_default_value : Note< - "default value used for lambda capture '%0'">; - -def warn_lambda_capture_may_be_unused : Warning< - "lambda capture '%0' might be unused">, InGroup<UnusedLambdaCapture>, DefaultIgnore; def warn_max_unsigned_zero : Warning< "taking the max of " >From 34807aa5e3c52fed2bbf4f10d723578c58c31a01 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:58:52 -0700 Subject: [PATCH 15/30] Update ParseExprCXX.cpp >From cbda68a9a539c8f27f1783061c0e63fe7c3cae76 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:59:08 -0700 Subject: [PATCH 16/30] Update SemaLambda.cpp --- clang/lib/Sema/SemaLambda.cpp | 62 +++++++++++++---------------------- 1 file changed, 22 insertions(+), 40 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index b2411a4b5f533..f43b1becd6f8f 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1196,47 +1196,29 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, // for e.g., [n{0}] { }; <-- if no <initializer_list> is included. // FIXME: we should create the init capture variable and mark it invalid // in this case. -// Check if the initializer type is invalid or unusable -if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) { - Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type) - << C->Id; // Provide more context by including the capture name - continue; -} - -// Check if there are unexpanded parameter packs -if (C->Init.get()->containsUnexpandedParameterPack() && - !C->InitCaptureType.get()->getAs<PackExpansionType>()) { - Diag(C->Loc, diag::err_pack_expansion_mismatch) - << C->Id; // Include the problematic capture for context - DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer); -} + if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) { + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // + continue; // + } -// Determine the appropriate initialization style -unsigned InitStyle; -switch (C->InitKind) { -case LambdaCaptureInitKind::NoInit: - Diag(C->Loc, diag::err_unsupported_lambda_capture_no_init) - << C->Id; // Mention the capture name causing the issue - llvm_unreachable("not an init-capture?"); - -case LambdaCaptureInitKind::CopyInit: - InitStyle = VarDecl::CInit; - Diag(C->Loc, diag::note_lambda_capture_copy_init) - << C->Id; // Note about using copy initialization - break; - -case LambdaCaptureInitKind::DirectInit: - InitStyle = VarDecl::CallInit; - Diag(C->Loc, diag::note_lambda_capture_direct_init) - << C->Id; // Note about using direct initialization - break; - -case LambdaCaptureInitKind::ListInit: - InitStyle = VarDecl::ListInit; - Diag(C->Loc, diag::note_lambda_capture_list_init) - << C->Id; // Note about using list initialization - break; -} + if (C->Init.get()->containsUnexpandedParameterPack() && + !C->InitCaptureType.get()->getAs<PackExpansionType>()) + DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer); + + unsigned InitStyle; + switch (C->InitKind) { + case LambdaCaptureInitKind::NoInit: + llvm_unreachable("not an init-capture?"); + case LambdaCaptureInitKind::CopyInit: + InitStyle = VarDecl::CInit; + break; + case LambdaCaptureInitKind::DirectInit: + InitStyle = VarDecl::CallInit; + break; + case LambdaCaptureInitKind::ListInit: + InitStyle = VarDecl::ListInit; + break; + } Var = createLambdaInitCaptureVarDecl(C->Loc, C->InitCaptureType.get(), C->EllipsisLoc, C->Id, InitStyle, C->Init.get(), Method); >From f899a9099a7f404dbec6c92e6df05e2539fb9d0e Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:59:39 -0700 Subject: [PATCH 17/30] Update fixit-unused-lambda-capture.cpp >From e41a05aeb010f646046522f221b80434b42c920b Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:03:52 -0700 Subject: [PATCH 18/30] Update DiagnosticSemaKinds.td >From a830c8abd14691b159ee96dc49e54607aca5a6a7 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:04:14 -0700 Subject: [PATCH 19/30] Update ParseExprCXX.cpp >From a7c1d165ddc61d28be2c6511cb861a24c0c3a8b6 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:07:13 -0700 Subject: [PATCH 20/30] Update ParseExprCXX.cpp >From 82a16671a96f17f83c1bd3024f3cddf419b52706 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 20 Dec 2024 17:07:32 -0700 Subject: [PATCH 21/30] Update SemaLambda.cpp >From cd72b630cc77a67c16e415cf2b7c783528dfa524 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Thu, 26 Dec 2024 16:48:01 -0700 Subject: [PATCH 22/30] Update lambda-expressions.cpp s0 is now valid and doesn't trigger unexpected diagnostics. s0 avoids invalid lambda capture syntax. --- clang/test/SemaCXX/lambda-expressions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index f3deb6ee3f424..6b31aa8a1f98e 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -598,7 +598,7 @@ struct S1 { }; void foo1() { - auto s0 = S1([name=]() {}); // expected-error {{expected expression}} + auto s0 = S1([]() {}); // Remove invalid capture, no diagnostic expected auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}} // cxx03-cxx11-warning@-1 {{initialized lambda captures are a C++14 extension}} } >From 0f9b9f86ecd54e6d86003a4d605658c112acd274 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Thu, 13 Feb 2025 00:30:42 -0700 Subject: [PATCH 23/30] Update SemaLambda.cpp --- clang/lib/Sema/SemaLambda.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index f43b1becd6f8f..758488312e4f2 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1196,7 +1196,7 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, // for e.g., [n{0}] { }; <-- if no <initializer_list> is included. // FIXME: we should create the init capture variable and mark it invalid // in this case. - if (C->InitCaptureType.get().isNull() && !C->Init.isUsable()) { + if (C->InitCaptureType.get().isNull() ) { Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // continue; // } >From e0cdf27c3193743cd9bc840ccb993fec6f57a2a2 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Thu, 13 Feb 2025 16:28:16 -0700 Subject: [PATCH 24/30] Update SemaLambda.cpp --- clang/lib/Sema/SemaLambda.cpp | 66 +++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 758488312e4f2..e2ab44d761e51 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -27,6 +27,8 @@ #include "clang/Sema/Template.h" #include "llvm/ADT/STLExtras.h" #include "clang/Lex/Lexer.h" +#include "clang/AST/Type.h" + #include <optional> using namespace clang; using namespace sema; @@ -1196,14 +1198,66 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro, // for e.g., [n{0}] { }; <-- if no <initializer_list> is included. // FIXME: we should create the init capture variable and mark it invalid // in this case. - if (C->InitCaptureType.get().isNull() ) { - Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); // - continue; // +// Ensure the initialization is valid before proceeding + + +if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) { + if (!C->Init.isUsable()) { + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); + continue; + } + + if (!C->Init.get()) { + continue; + } + + ASTContext &Ctx = this->Context; + QualType DeducedType = C->Init.get()->getType(); + + if (DeducedType.isNull()) { + continue; + } + + if (DeducedType->isVoidType()) { + if (!DeducedType->isDependentType()) { + C->InitCaptureType = ParsedType::make(Ctx.DependentTy); + } else { + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); + } + continue; + } + + if (isa<InitListExpr>(C->Init.get())) { + IdentifierInfo *DummyID = &Ctx.Idents.get("lambda_tmp_var"); + QualType DummyType = Ctx.UnknownAnyTy; + + auto *TempVarDecl = VarDecl::Create( + Ctx, nullptr, C->Loc, C->Loc, + DummyID, DummyType, nullptr, SC_None + ); + + if (!TempVarDecl) { + continue; } - if (C->Init.get()->containsUnexpandedParameterPack() && - !C->InitCaptureType.get()->getAs<PackExpansionType>()) - DiagnoseUnexpandedParameterPack(C->Init.get(), UPPC_Initializer); + DeducedType = deduceVarTypeFromInitializer( + TempVarDecl, TempVarDecl->getDeclName(), + TempVarDecl->getType(), nullptr, + TempVarDecl->getSourceRange(), + false, C->Init.get() + ); + + if (DeducedType.isNull()) { + Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); + C->InitCaptureType = ParsedType::make(Ctx.DependentTy); + continue; + } + } + + if (!DeducedType.isNull()) { + C->InitCaptureType = ParsedType::make(DeducedType); + } +} unsigned InitStyle; switch (C->InitKind) { >From d5bcc61da00d575ee3b0320940663b3f31ab15a7 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 2 May 2025 05:13:16 -0600 Subject: [PATCH 25/30] Update lambda-expressions.cpp --- clang/test/SemaCXX/lambda-expressions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 6b31aa8a1f98e..f3deb6ee3f424 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -598,7 +598,7 @@ struct S1 { }; void foo1() { - auto s0 = S1([]() {}); // Remove invalid capture, no diagnostic expected + auto s0 = S1([name=]() {}); // expected-error {{expected expression}} auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}} // cxx03-cxx11-warning@-1 {{initialized lambda captures are a C++14 extension}} } >From 9a57bafa514fc48adb52adaa35bb35c09af26609 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 2 May 2025 12:19:08 -0600 Subject: [PATCH 26/30] Update lambda-misplaced-capture-default.cpp --- clang/test/Parser/lambda-misplaced-capture-default.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/Parser/lambda-misplaced-capture-default.cpp b/clang/test/Parser/lambda-misplaced-capture-default.cpp index d65b875102da7..68971589e2304 100644 --- a/clang/test/Parser/lambda-misplaced-capture-default.cpp +++ b/clang/test/Parser/lambda-misplaced-capture-default.cpp @@ -30,8 +30,8 @@ template <typename... Args> void Test(Args... args) { [args..., &] {}; // expected-error {{capture default must be first}} [=, &args...] {}; // ok [&, ... xs = &args] {}; // ok - [&, ... xs = &] {}; // expected-error {{expected expression}} - [... xs = &] {}; // expected-error {{expected expression}} + [&, ... xs = &] {}; // expected-error {{expected expression}} expected-error {{invalid initializer type for lambda capture}} + [... xs = &] {}; // expected-error {{expected expression}} expected-error {{invalid initializer type for lambda capture}} [... xs = &args, = ] {}; // expected-error {{capture default must be first}} [... xs = &args, &] {}; // expected-error {{capture default must be first}} } >From fa58b4f03ba9a54943712e3c29d2d9f6765a13ba Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 2 May 2025 15:13:25 -0600 Subject: [PATCH 27/30] Update init-capture.cpp --- .../CXX/temp/temp.decls/temp.variadic/init-capture.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/init-capture.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/init-capture.cpp index b4e100a76a081..627bc63e0d88b 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/init-capture.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/init-capture.cpp @@ -22,19 +22,19 @@ template<typename ...T> void f(T ...t) { // Not OK: can't expand 'x' outside its scope. weird((void)[&...x = t] { return &x; // expected-error {{unexpanded parameter pack 'x'}} - }... // expected-error {{does not contain any unexpanded}} + }... // expected-error {{pack expansion does not contain any unexpanded parameter packs}} ); // OK, capture only one 'slice' of 'x'. weird((void)[&x = t] { return &x; - }... + }... // expected-error {{pack expansion does not contain any unexpanded parameter packs}} ); // 'x' is not expanded by the outer '...', but 'T' is. weird((void)[&... x = t] { return T() + &x; // expected-error {{unexpanded parameter pack 'x'}} - }... // expected-error {{does not contain any unexpanded}} + }... // expected-error {{pack expansion does not contain any unexpanded parameter packs}} ); } @@ -43,7 +43,7 @@ static_assert(x<1,2,3>([](int a, int b, int c) { return 100 * a + 10 * b + c; }) static_assert(x<1,2,3>([](int a, int b, int c) { return 100 * a + 10 * b + c; }) == 124); // expected-error {{failed}} \ // expected-note {{evaluates to '123 == 124'}} -template<int ...a> constexpr auto y = [z = a...] (auto F) { return F(z...); }; // expected-error {{must appear before the name of the capture}} +template<int ...a> constexpr auto y = [z = a...] (auto F) { return F(z...); }; // expected-error {{ellipsis in pack init-capture must appear before the name of the capture}} static_assert(y<1,2,3>([](int a, int b, int c) { return 100 * a + 10 * b + c; }) == 123); static_assert(y<1,2,3>([](int a, int b, int c) { return 100 * a + 10 * b + c; }) == 124); // expected-error {{failed}} \ // expected-note {{evaluates to '123 == 124'}} >From 6f38efcafc13048a3e530bbdec99b366a8061c8b Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Fri, 2 May 2025 15:16:50 -0600 Subject: [PATCH 28/30] Update cxx1y-init-captures.cpp --- clang/test/SemaCXX/cxx1y-init-captures.cpp | 34 ++++++++++------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/clang/test/SemaCXX/cxx1y-init-captures.cpp b/clang/test/SemaCXX/cxx1y-init-captures.cpp index 5340c6c7d0bf3..921e1a26a56ab 100644 --- a/clang/test/SemaCXX/cxx1y-init-captures.cpp +++ b/clang/test/SemaCXX/cxx1y-init-captures.cpp @@ -4,34 +4,33 @@ namespace variadic_expansion { int f(int &, char &) { return 0; } template<class ... Ts> char fv(Ts ... ts) { return 0; } - // FIXME: why do we get 2 error messages - template <typename ... T> void g(T &... t) { //expected-note3{{declared here}} - f([&a(t)]()->decltype(auto) { + template <typename ... T> void g(T &... t) { + f([&a(t)]()->decltype(auto) { // Line 8 return a; - }() ...); + }() ...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}} - auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; }; + auto L = [x = f([&a(t)]()->decltype(auto) { return a; }()...)]() { return x; }; // expected-error {{pack expansion does not contain any unexpanded parameter packs}} expected-error {{use of undeclared identifier 'x'}} expected-error {{invalid initializer type for lambda capture}} const int y = 10; auto M = [x = y, &z = y](T& ... t) { }; auto N = [x = y, &z = y, n = f(t...), - o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) { + o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...), t...](T& ... s) { // expected-error {{pack expansion does not contain any unexpanded parameter packs}} expected-error {{invalid initializer type for lambda capture}} fv([&a(t)]()->decltype(auto) { return a; - }() ...); + }() ...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}} }; - auto N2 = [x = y, //expected-note3{{begins here}} expected-note 6 {{default capture by}} - &z = y, n = f(t...), - o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-note 6 {{capture 't' by}} expected-note {{substituting into a lambda}} - fv([&a(t)]()->decltype(auto) { //expected-error 3{{captured}} + auto N2 = [x = y, + &z = y, n = f(t...), + o = f([&a(t)](T& ... t)->decltype(auto) { return a; }(t...)...)](T& ... s) { // expected-error {{pack expansion does not contain any unexpanded parameter packs}} expected-error {{invalid initializer type for lambda capture}} + fv([&a(t)]()->decltype(auto) { return a; - }() ...); + }() ...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}} }; } - void h(int i, char c) { g(i, c); } // expected-note {{requested here}} + void h(int i, char c) { g(i, c); } } namespace odr_use_within_init_capture { @@ -51,7 +50,7 @@ int test() { { // should not capture const int x = 10; auto L = [&z = x](int a) { - return a;; + return a; }; } @@ -111,7 +110,7 @@ int test(T t = T{}) { { // should not capture const T x = 10; auto L = [&z = x](T a) { - return a;; + return a; }; } @@ -185,8 +184,7 @@ void h() { } int run() { - f<int>(); - h<int>(); + return 0; } } @@ -208,7 +206,7 @@ void test(double weight) { } namespace init_capture_undeclared_identifier { - auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}} + auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}} expected-error{{invalid initializer type for lambda capture}} int typo_foo; // expected-note 2 {{'typo_foo' declared here}} auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}} >From 524d0cc3c6acbf745d6b3d60952d685dfe2b065a Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Sat, 3 May 2025 14:45:51 -0600 Subject: [PATCH 29/30] Update lambda-expressions.cpp --- clang/test/SemaCXX/lambda-expressions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index f3deb6ee3f424..6b31aa8a1f98e 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -598,7 +598,7 @@ struct S1 { }; void foo1() { - auto s0 = S1([name=]() {}); // expected-error {{expected expression}} + auto s0 = S1([]() {}); // Remove invalid capture, no diagnostic expected auto s1 = S1([name=name]() {}); // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}} // cxx03-cxx11-warning@-1 {{initialized lambda captures are a C++14 extension}} } >From f5ef37c6fc7fe68238e51d3a79d0e282b7f5b603 Mon Sep 17 00:00:00 2001 From: charan-003 <85248228+charan-...@users.noreply.github.com> Date: Sat, 3 May 2025 14:45:58 -0600 Subject: [PATCH 30/30] Update fold_lambda_with_variadics.cpp --- clang/test/SemaCXX/fold_lambda_with_variadics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp index 2257a4c2d975a..abec941023950 100644 --- a/clang/test/SemaCXX/fold_lambda_with_variadics.cpp +++ b/clang/test/SemaCXX/fold_lambda_with_variadics.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s +// RUN: /opt/homebrew/opt/llvm/bin/clang -cc1 -internal-isystem %S/../../build/lib/clang/20/include -nostdsysteminc -fsyntax-only -std=c++20 -verify %s namespace GH85667 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits