[PATCH] D149276: [Clang] Fix parsing of `(auto(x))`.

Corentin Jabot via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 27 02:20:25 PDT 2023


cor3ntin added inline comments.


================
Comment at: clang/lib/Parse/ParseTentative.cpp:237
       ConsumeAnnotationToken();
-    if (Tok.is(tok::identifier))
+    if (Tok.isOneOf(tok::identifier, tok::kw_auto))
       ConsumeToken();
----------------
aaron.ballman wrote:
> This smells a bit off to me because of the comments above -- this is trying to parse an elaborated type specifier, and `auto` cannot appear in this position for that case. Can you help me understand what's going on?
You are right, this should not have been committed, nice catch!


================
Comment at: clang/test/Parser/cxx1z-decomposition.cpp:97
     decltype(auto) [b] = s; // expected-error {{cannot be declared with type 'decltype(auto)'}}
-    auto ([c]) = s; // expected-error {{cannot be declared with parentheses}}
+    auto ([c]) = s; // expected-error {{'auto' not allowed here}} \
+                    // expected-error {{use of undeclared identifier 'c'}} \
----------------
aaron.ballman wrote:
> This first diagnostic is incorrect -- `auto` is definitely allowed there, just that the rest of the declaration is nonsense. I think the "use of undeclared identifier" diagnostic is reasonable. The lambda diagnostic is.... interesting.
> 
> Any way you can improve this, or is that a slog?
There were multiple issues there.

The "decomposition declaration cannot be declared with parenthese" error which i had remove can still occur at global scope where a declaration is expected so i put that back and added a test.
Then, I'm running all the tests in c++17 and 23 modes as the behavior is different.

I did restore the current behavior in C++20 and earlier modes, such that we will always consider `auto` starts a declaration. That way we can have that structured binding in parentheses diag.

But in c++23 mode,  We establish it's not a valid declarator. so we parse it as an expression. `[` is always considered as a lambda introducer, which it could be, ie `auto([c] {});` is a valid expression assuming that C exists.
At that point trying to figure out that `]` is not followed by `{` and is therefore not a lambda seems extremely tricky as you can have arbitrary long expressions between the square brackets.



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D149276/new/

https://reviews.llvm.org/D149276



More information about the cfe-commits mailing list