[clang] [FixIt] Improve Source Ranges and Fix-It Hints for Unused Lambda Captures #106445 (PR #117953)
via cfe-commits
cfe-commits at lists.llvm.org
Sat May 3 06:48:59 PDT 2025
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff HEAD~1 HEAD --extensions cpp -- clang/lib/Parse/ParseExprCXX.cpp clang/lib/Sema/SemaLambda.cpp clang/test/CXX/temp/temp.decls/temp.variadic/init-capture.cpp clang/test/FixIt/fixit-unused-lambda-capture.cpp clang/test/Parser/lambda-misplaced-capture-default.cpp clang/test/SemaCXX/cxx1y-init-captures.cpp
``````````
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 5cdb05d26..91342360d 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1274,13 +1274,13 @@ static void tryConsumeLambdaSpecifierToken(Parser &P,
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);
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index be9a9f023..9c02c4703 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -15,7 +15,9 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/MangleNumberingContext.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Lexer.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
@@ -28,8 +30,6 @@
#include "clang/Sema/SemaSYCL.h"
#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;
@@ -1189,25 +1189,27 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
CheckCXXThisCapture(C->Loc, /*Explicit=*/true, /*BuildAndDiagnose*/ true,
/*FunctionScopeIndexToStopAtPtr*/ nullptr,
C->Kind == LCK_StarThis);
- if (!LSI->Captures.empty()) { //
+ if (!LSI->Captures.empty()) { //
SourceManager &SourceMgr = Context.getSourceManager();
const LangOptions &LangOpts = Context.getLangOpts();
- SourceRange TrimmedRange = Lexer::makeFileCharRange(
- CharSourceRange::getTokenRange(C->ExplicitRange), SourceMgr, LangOpts)
- .getAsRange();
+ 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.
}
- if (!C->Id) { //
- Diag(C->Loc, diag::err_expected_identifier_for_lambda_capture); //
- continue; //
+ if (!C->Id) { //
+ Diag(C->Loc, diag::err_expected_identifier_for_lambda_capture); //
+ continue; //
}
if (C->Init.isInvalid()) {
- Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); //
- continue; //
+ Diag(C->Loc, diag::err_invalid_lambda_capture_initializer_type); //
+ continue; //
}
ValueDecl *Var = nullptr;
@@ -1221,66 +1223,61 @@ 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.
-// Ensure the initialization is valid before proceeding
+ // 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->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;
+ }
- if (!C->Init.get()) {
- continue;
- }
+ ASTContext &Ctx = this->Context;
+ QualType DeducedType = C->Init.get()->getType();
- ASTContext &Ctx = this->Context;
- QualType DeducedType = C->Init.get()->getType();
+ if (DeducedType.isNull()) {
+ continue;
+ }
- 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 (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;
- 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);
- auto *TempVarDecl = VarDecl::Create(
- Ctx, nullptr, C->Loc, C->Loc,
- DummyID, DummyType, nullptr, SC_None
- );
+ if (!TempVarDecl) {
+ continue;
+ }
- if (!TempVarDecl) {
- continue;
- }
+ DeducedType = deduceVarTypeFromInitializer(
+ TempVarDecl, TempVarDecl->getDeclName(), TempVarDecl->getType(),
+ nullptr, TempVarDecl->getSourceRange(), false, C->Init.get());
- 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()) {
- 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);
+ }
}
- }
-
- if (!DeducedType.isNull()) {
- C->InitCaptureType = ParsedType::make(DeducedType);
- }
-}
unsigned InitStyle;
switch (C->InitKind) {
@@ -1420,14 +1417,16 @@ if (!C->InitCaptureType || C->InitCaptureType.get().isNull()) {
: TryCaptureKind::ExplicitByVal;
tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc);
}
- 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;
+ }
}
finishLambdaExplicitCaptures(LSI);
LSI->ContainsUnexpandedParameterPack |= ContainsUnexpandedParameterPack;
@@ -2236,32 +2235,37 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
bool IsCaptureUsed = true;
-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;
- }
- }
+ 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);
- }
-}
+ IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From);
+ }
+ }
if (CaptureRange.isValid()) {
CurHasPreviousCapture |= IsCaptureUsed;
``````````
</details>
https://github.com/llvm/llvm-project/pull/117953
More information about the cfe-commits
mailing list