Previously, clang emitted a less-usefull diagnostic and didnt recover
well when the keywords is used as identifier in function paramter.
void foo(int case, int x); // previously we drop all parameters after `int case`.
Differential D77633
[Parser] Improve diagnostic and error recovery when C++ keywords are used as identifiers. hokein on Apr 7 2020, 1:35 AM. Authored by
Details Previously, clang emitted a less-usefull diagnostic and didnt recover void foo(int case, int x); // previously we drop all parameters after `int case`.
Diff Detail
Unit Tests
Event Timeline
Comment Actions address review comments
Comment Actions This is fairly visible, but seems reasonably safe to me. Let's see if anyone complains :-)
Comment Actions This is cool, thx! One case I stumbled upon recently is: Which results in these rather confusing messages: /tmp/test.cpp:1:14: warning: explicit(bool) is a C++20 extension [-Wc++20-extensions] void explicit() { } ^ /tmp/test.cpp:1:15: error: expected expression void explicit() { } ^ /tmp/test.cpp:1:17: error: expected unqualified-id void explicit() { } ^ 1 warning and 2 errors generated. Just in case you want to continue this ;) |
As I understand it, we're trying to catch keywords in place of the identifier in a declarator, and in particular the common case where:
And we can't handle this in ParseDeclarator because in general keywords may be allowed to follow the declarator. (And in some cases there'd be better recovery like inserting punctuation).
Our recovery is just treating this as an anonymous parameter, and fortunately we've already almost done that.
So all of this would be good to capture in the comment :-)
We should restrict to these cases as much as possible: the type should be present, and the identifier should be null[1].
I don't know how confident we can be all the time that our interpretation (the keyword was meant to be a variable) is right, and the diagnostic might be confusing in that case.
e.g. void foo(int const) will trigger this diagnostic, and the user may intend anonymous void foo(const int). using keyword const as an identifier is not permitted may be less clear than e.g. the more specific invalid parameter name: 'const' is a keyword.
(Note that because of the [1] case, as the patch stands void foo(int x const) will trigger using keyword const as an identifier..., which is bad!)