[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
Wed Nov 27 21:07:16 PST 2024


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-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 18:43:38 -0700
Subject: [PATCH 1/5] 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 a67c0b2b367d1a..e7417d1a884dcd 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-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 18:48:37 -0700
Subject: [PATCH 2/5] 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 ce0c78d677099a..ae43d4ebbdf821 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-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 21:52:22 -0700
Subject: [PATCH 3/5] 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 e7417d1a884dcd..82a0f926d6af75 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-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 21:58:20 -0700
Subject: [PATCH 4/5] 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 82a0f926d6af75..049cecea0c5875 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-003 at users.noreply.github.com>
Date: Wed, 27 Nov 2024 22:07:07 -0700
Subject: [PATCH 5/5] 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 049cecea0c5875..57854f8814617e 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;



More information about the cfe-commits mailing list