Skip to content
Merged
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ Bug Fixes to C++ Support
- Fixed a template depth issue when parsing lambdas inside a type constraint. (#GH162092)
- Diagnose unresolved overload sets in non-dependent compound requirements. (#GH51246) (#GH97753)
- Fix a crash when extracting unavailable member type from alias in template deduction. (#GH165560)
- Fix incorrect diagnostics for lambdas with init-captures inside braced initializers. (#GH163498)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
42 changes: 25 additions & 17 deletions clang/lib/Parse/ParseExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -772,9 +772,10 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,

// Produce a diagnostic if we're not tentatively parsing; otherwise track
// that our parse has failed.
auto Invalid = [&](llvm::function_ref<void()> Action) {
auto Result = [&](llvm::function_ref<void()> Action,
LambdaIntroducerTentativeParse State) {
if (Tentative) {
*Tentative = LambdaIntroducerTentativeParse::Invalid;
*Tentative = State;
return false;
}
Action();
Expand Down Expand Up @@ -824,9 +825,11 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
break;
}

return Invalid([&] {
Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare);
});
return Result(
[&] {
Diag(Tok.getLocation(), diag::err_expected_comma_or_rsquare);
},
LambdaIntroducerTentativeParse::Invalid);
}
ConsumeToken();
}
Expand Down Expand Up @@ -861,9 +864,11 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
ConsumeToken();
Kind = LCK_StarThis;
} else {
return Invalid([&] {
Diag(Tok.getLocation(), diag::err_expected_star_this_capture);
});
return Result(
[&] {
Diag(Tok.getLocation(), diag::err_expected_star_this_capture);
},
LambdaIntroducerTentativeParse::Invalid);
}
} else if (Tok.is(tok::kw_this)) {
Kind = LCK_This;
Expand All @@ -875,8 +880,9 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
// or the start of a capture (in the "&" case) with the rest of the
// capture missing. Both are an error but a misplaced capture-default
// is more likely if we don't already have a capture default.
return Invalid(
[&] { Diag(Tok.getLocation(), diag::err_capture_default_first); });
return Result(
[&] { Diag(Tok.getLocation(), diag::err_capture_default_first); },
LambdaIntroducerTentativeParse::Incomplete);
} else {
TryConsumeToken(tok::ellipsis, EllipsisLocs[0]);

Expand All @@ -899,14 +905,16 @@ bool Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro,
Id = Tok.getIdentifierInfo();
Loc = ConsumeToken();
} else if (Tok.is(tok::kw_this)) {
return Invalid([&] {
// FIXME: Suggest a fixit here.
Diag(Tok.getLocation(), diag::err_this_captured_by_reference);
});
return Result(
[&] {
// FIXME: Suggest a fixit here.
Diag(Tok.getLocation(), diag::err_this_captured_by_reference);
},
LambdaIntroducerTentativeParse::Invalid);
} else {
return Invalid([&] {
Diag(Tok.getLocation(), diag::err_expected_capture);
});
return Result(
[&] { Diag(Tok.getLocation(), diag::err_expected_capture); },
LambdaIntroducerTentativeParse::Invalid);
}

TryConsumeToken(tok::ellipsis, EllipsisLocs[2]);
Expand Down
9 changes: 9 additions & 0 deletions clang/test/Parser/lambda-misplaced-capture-default.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,12 @@ template <typename... Args> void Test(Args... args) {
[... xs = &args, &] {}; // expected-error {{capture default must be first}}
}
} // namespace misplaced_capture_default_pack

namespace GH163498 {
struct S {
template <class T> S(T) {}
};
void t() {
S s{[a(42), &] {}}; // expected-error {{capture default must be first}}
}
}
Loading