Skip to content

Improve error message for invalid lambda captures #94865

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,9 @@ 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 for captures that refer to a class member.
Fixes #GH94764.

- 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.
The check is now stricter to prevent crashes for some unsupported declarations (Fixes #GH95495).
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -8204,6 +8204,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">;
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/Sema/SemaLambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,11 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,

if (auto *BD = R.getAsSingle<BindingDecl>())
Var = BD;
else
else if (auto *FD = R.getAsSingle<FieldDecl>()) {
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;
Expand Down
9 changes: 9 additions & 0 deletions clang/test/SemaCXX/lambda-expressions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}}
Expand Down
Loading