[PATCH] D77633: [Parser] Improve diagnostic and error recovery when C++ keywords are used as identifiers.
Haojian Wu via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 8 00:29:55 PDT 2020
hokein marked 2 inline comments as done.
hokein added inline comments.
================
Comment at: clang/lib/Parse/ParseDecl.cpp:6872
+ // Recovery if a keyword is used as an identifier.
+ if (Tok.getIdentifierInfo() &&
----------------
sammccall wrote:
> 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:
> - the identifier comes at the end of the declarator
> - if the identifier is dropped, the declarator is valid but anonymous (no identifier)
> - so declarator parsing succeeds, and then we have a trailing keyword, which is never valid in a param list (need , or ... or `)` )
>
> 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!)
yes, exactly, added comments. I first tried to handle it in ParseDeclarator, but failed with that.
And `void foo(int const)` would not trigger the diagnostic -- this is because it is a valid declarator, the identifier is dropped, case[2].
by restricting the case (only emit the diagnostic when the type is known, and identifier is null), `void foo(int x const)` will not trigger the diagnostic -- the type and identifier are known.
================
Comment at: clang/test/Parser/cxx-keyword-identifiers.cpp:12
+ // FIXME: we shoud improve the dianostics for the following cases.
+ int case; // expected-error {{expected unqualified-id}}
+ struct X {
----------------
sammccall wrote:
> this seems nice but harder, I think the grammar is more permissive here. I guess we'd be able to whitelist the keywords that can legitimately follow?
yeah, I think at least we could append a message to the `expected-unqualified-id` when the next Tok is a keyword.
================
Comment at: clang/test/Parser/cxx-keyword-identifiers.cpp:17
+int foo6(int case __attribute((weak))); // expected-error {{invalid parameter}} \
+ // expected-error {{expected ')'}} expected-note {{to match this '('}}
+
----------------
unfortunately, the error recovery doesn't handle well for this case, we emit a spurious diagnostic, but I think it is a fair tradeoff.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D77633/new/
https://reviews.llvm.org/D77633
More information about the cfe-commits
mailing list