[clang] Improve error message for invalid lambda captures (PR #94865)

via cfe-commits cfe-commits at lists.llvm.org
Sat Jun 29 18:25:50 PDT 2024


https://github.com/CedricSwa updated https://github.com/llvm/llvm-project/pull/94865

>From 012849c5410960001ca5bbcb90ea2cf4a661b840 Mon Sep 17 00:00:00 2001
From: Cedric Schwarzer <Cedric.Schwarzer at stud.uni-hannover.de>
Date: Sat, 8 Jun 2024 17:52:02 +0200
Subject: [PATCH 1/5] Improve error message for invalid lambda captures

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
 clang/lib/Sema/SemaLambda.cpp                    | 7 ++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9f0b6f5a36389..fdf4409125c00 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -8173,6 +8173,8 @@ let CategoryName = "Lambda Issue" in {
     "'&' must precede a capture when the capture default is '='">;
   def err_capture_does_not_name_variable : Error<
     "%0 in capture list does not name a variable">;
+  def err_capture_class_member_does_not_name_variable : Error<
+    "class member %0 cannot appear in capture list as it is not a variable">;
   def err_capture_non_automatic_variable : Error<
     "%0 cannot be captured because it does not have automatic storage "
     "duration">;
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index e9476a0c93c5d..79c10c3bad6d7 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1246,7 +1246,12 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
 
       if (auto *BD = R.getAsSingle<BindingDecl>())
         Var = BD;
-      else
+      else if (auto *FD = R.getAsSingle<FieldDecl>()) {
+        Var = R.getAsSingle<VarDecl>();
+        Diag(C->Loc, diag::err_capture_class_member_does_not_name_variable)
+            << C->Id;
+        continue;
+      } else
         Var = R.getAsSingle<VarDecl>();
       if (Var && DiagnoseUseOfDecl(Var, C->Loc))
         continue;

>From dc1ca518ea4a4b5407decd9d99e561282cf7f4e4 Mon Sep 17 00:00:00 2001
From: "cedric.SWA" <cedric.Swa at protonmail.com>
Date: Mon, 10 Jun 2024 20:48:59 +0200
Subject: [PATCH 2/5] remove unnecessary variable assignment

---
 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 79c10c3bad6d7..97f1d9428fef6 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1247,7 +1247,6 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
       if (auto *BD = R.getAsSingle<BindingDecl>())
         Var = BD;
       else if (auto *FD = R.getAsSingle<FieldDecl>()) {
-        Var = R.getAsSingle<VarDecl>();
         Diag(C->Loc, diag::err_capture_class_member_does_not_name_variable)
             << C->Id;
         continue;

>From 9ec08c86a22060a42996fdbc131a864e16ccb0d8 Mon Sep 17 00:00:00 2001
From: "cedric.SWA" <cedric.Swa at protonmail.com>
Date: Tue, 25 Jun 2024 17:09:39 +0200
Subject: [PATCH 3/5] test for lambda try captureing class member

---
 clang/test/SemaCXX/lambda-expressions.cpp | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 151d74f21d64d..acf8d014a9896 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -609,6 +609,15 @@ namespace PR25627_dont_odr_use_local_consts {
   }
 }
 
+namespace PR94764 {
+  struct X {
+    int x;
+    void foo() {
+      [x](){}; // expected-error{{class member 'x' cannot appear in capture list as it is not a variable}}
+    }
+  };
+}
+
 namespace ConversionOperatorDoesNotHaveDeducedReturnType {
   auto x = [](int){};
   auto y = [](auto &v) -> void { v.n = 0; }; // cxx03-cxx11-error {{'auto' not allowed in lambda parameter}} cxx03-cxx11-note {{candidate function not viable}} cxx03-cxx11-note {{conversion candidate}}

>From 9bed94ac9c0620807b1c9054fd36a5aaa7b0d8ab Mon Sep 17 00:00:00 2001
From: "cedric.SWA" <cedric.Swa at protonmail.com>
Date: Tue, 25 Jun 2024 18:12:20 +0200
Subject: [PATCH 4/5] add to diagnostic improvements in release notes

---
 clang/docs/ReleaseNotes.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b9c9070fcb22f..8358e8e32f18c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -569,6 +569,8 @@ Improvements to Clang's diagnostics
 - Clang no longer emits a "declared here" note for a builtin function that has no declaration in source.
   Fixes #GH93369.
 
+- Clang now has an improved error message when trying to capture a variable for lambda function expressions.
+
 Improvements to Clang's time-trace
 ----------------------------------
 

>From f5bb934f43b4185f8574e1dd198e02a6a2431d11 Mon Sep 17 00:00:00 2001
From: "cedric.SWA" <cedric.Swa at protonmail.com>
Date: Sun, 30 Jun 2024 01:28:45 +0200
Subject: [PATCH 5/5] more explicit release note

---
 clang/docs/ReleaseNotes.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 82441bcbf4d95..e78f76ba9b382 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -622,7 +622,7 @@ Improvements to Clang's diagnostics
 - Clang no longer emits a "declared here" note for a builtin function that has no declaration in source.
   Fixes #GH93369.
 
-- Clang now has an improved error message when trying to capture a variable for lambda function expressions.
+- Clang now has an improved error message when trying to capture a class member variable for lambda function expressions.
 
 - Clang now diagnoses unsupported class declarations for ``std::initializer_list<E>`` when they are
   used rather than when they are needed for constant evaluation or when code is generated for them.



More information about the cfe-commits mailing list