Skip to content

Commit 51d87aa

Browse files
authored
[Clang] Improve error message for lambda captures that name a class member (#94865)
This introduces are more helpful error message when trying to explicitly capture a class member in a lambda. Fixes #94764.
1 parent 0d88f66 commit 51d87aa

File tree

4 files changed

+19
-1
lines changed

4 files changed

+19
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,9 @@ Improvements to Clang's diagnostics
639639
- Clang no longer emits a "declared here" note for a builtin function that has no declaration in source.
640640
Fixes #GH93369.
641641

642+
- Clang now has an improved error message for captures that refer to a class member.
643+
Fixes #GH94764.
644+
642645
- Clang now diagnoses unsupported class declarations for ``std::initializer_list<E>`` when they are
643646
used rather than when they are needed for constant evaluation or when code is generated for them.
644647
The check is now stricter to prevent crashes for some unsupported declarations (Fixes #GH95495).

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8204,6 +8204,8 @@ let CategoryName = "Lambda Issue" in {
82048204
"'&' must precede a capture when the capture default is '='">;
82058205
def err_capture_does_not_name_variable : Error<
82068206
"%0 in capture list does not name a variable">;
8207+
def err_capture_class_member_does_not_name_variable : Error<
8208+
"class member %0 cannot appear in capture list as it is not a variable">;
82078209
def err_capture_non_automatic_variable : Error<
82088210
"%0 cannot be captured because it does not have automatic storage "
82098211
"duration">;

clang/lib/Sema/SemaLambda.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
12461246

12471247
if (auto *BD = R.getAsSingle<BindingDecl>())
12481248
Var = BD;
1249-
else
1249+
else if (auto *FD = R.getAsSingle<FieldDecl>()) {
1250+
Diag(C->Loc, diag::err_capture_class_member_does_not_name_variable)
1251+
<< C->Id;
1252+
continue;
1253+
} else
12501254
Var = R.getAsSingle<VarDecl>();
12511255
if (Var && DiagnoseUseOfDecl(Var, C->Loc))
12521256
continue;

clang/test/SemaCXX/lambda-expressions.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,15 @@ namespace PR25627_dont_odr_use_local_consts {
609609
}
610610
}
611611

612+
namespace PR94764 {
613+
struct X {
614+
int x;
615+
void foo() {
616+
[x](){}; // expected-error{{class member 'x' cannot appear in capture list as it is not a variable}}
617+
}
618+
};
619+
}
620+
612621
namespace ConversionOperatorDoesNotHaveDeducedReturnType {
613622
auto x = [](int){};
614623
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}}

0 commit comments

Comments
 (0)