This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Fix parsing of `(auto(x))`.
ClosedPublic

Authored by cor3ntin on Apr 26 2023, 11:13 AM.

Details

Summary

Allow auto(x) to appear in a parenthesis
expression.

The pattern (auto( can appear as part of a declarator,
so the parser is modified to avoid the ambiguity,
in a way consistent with the proposed resolution to CWG1223.

Diff Detail

Event Timeline

cor3ntin created this revision.Apr 26 2023, 11:13 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 26 2023, 11:13 AM
cor3ntin requested review of this revision.Apr 26 2023, 11:13 AM
Herald added a project: Restricted Project. · View Herald Transcript
cor3ntin updated this revision to Diff 517248.Apr 26 2023, 11:17 AM

Fix whitespace only changes

aaron.ballman added inline comments.Apr 26 2023, 12:09 PM
clang/docs/ReleaseNotes.rst
459
clang/include/clang/Parse/Parser.h
2657
2665–2666
clang/lib/Parse/ParseTentative.cpp
234

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?

320
542
1413–1414

This seems incorrect to me, consider:

auto [[clang::annotate_type("test")]] i = 12;

https://godbolt.org/z/7Gx3Gb18h

1415–1417
2114
clang/test/Parser/cxx1z-decomposition.cpp
99–101

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?

cor3ntin updated this revision to Diff 517488.Apr 27 2023, 2:08 AM
cor3ntin marked 8 inline comments as done.
  • Fix tests
  • Address aaron's comments
cor3ntin updated this revision to Diff 517491.Apr 27 2023, 2:13 AM

Do not parse auto( as an expression before C++23

tbaeder added inline comments.
clang/lib/Parse/ParseTentative.cpp
1064

Not part of this commit I guess, but four bool parameters is truly horrific :/

cor3ntin added inline comments.Apr 27 2023, 2:20 AM
clang/lib/Parse/ParseTentative.cpp
234

You are right, this should not have been committed, nice catch!

clang/test/Parser/cxx1z-decomposition.cpp
99–101

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.

aaron.ballman added inline comments.Apr 27 2023, 5:42 AM
clang/lib/Parse/ParseTentative.cpp
1064

Yeah, a refactoring here would not be amiss (but outside of this patch, I think).

1413–1414

Ignore this -- l_brace is not l_square. :-D

clang/test/Parser/cxx1z-decomposition.cpp
99–101

Thanks for the explanation -- that seems defensible to me.

cor3ntin updated this revision to Diff 517536.Apr 27 2023, 6:14 AM

Fix tests

aaron.ballman edited reviewers, added: hubert.reinterpretcast, Restricted Project; removed: jdoerfert.Apr 27 2023, 10:51 AM

The changes generally LGTM, but:

in a way consistent with the proposed resolution to CWG1223.

What are the chances that CWG changes their mind and picks a different direction?

The changes generally LGTM, but:

in a way consistent with the proposed resolution to CWG1223.

What are the chances that CWG changes their mind and picks a different direction?

CWG acts in mysterious ways, so it's hard to tell. but i think anything else than this resolution could potentially break code?

clang/lib/Parse/ParseTentative.cpp
1064

Agreed, we probably want an enum there instead, i could follow up

@rsmith @hubert.reinterpretcast do you see any reason not to go ahead with this?

shafik added a subscriber: shafik.Apr 28 2023, 9:40 AM

I see that we do have an issue but so far the examples in the tests don't feel very natural and so I would like to understand if there is a larger motivation here.

I see that we do have an issue but so far the examples in the tests don't feel very natural and so I would like to understand if there is a larger motivation here.

The context is that a user realized we fail to implement P0849 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0849r8.html
and as a result we fail to compile simple range code https://godbolt.org/z/3ajj1c135 (this was observed by a user on the llvm discord and i don't think they made a github issue, unfortunately)

@aaron.ballman this won;t get approve by core un

The changes generally LGTM, but:

in a way consistent with the proposed resolution to CWG1223.

What are the chances that CWG changes their mind and picks a different direction?

They were happy with the direction friday when we looked at it ( not the wording though). I think we should go ahead, waiting until after issaquah might be a bit too late (and if we are claiming auto(x) is implemented we should merge that in 17)

aaron.ballman accepted this revision.May 15 2023, 4:48 AM

@aaron.ballman this won;t get approve by core un

The changes generally LGTM, but:

in a way consistent with the proposed resolution to CWG1223.

What are the chances that CWG changes their mind and picks a different direction?

They were happy with the direction friday when we looked at it ( not the wording though). I think we should go ahead, waiting until after issaquah might be a bit too late (and if we are claiming auto(x) is implemented we should merge that in 17)

We don't have to wait for the wording to be final so long as the direction is in line with what you've done here, so LGTM! Thank you!

This revision is now accepted and ready to land.May 15 2023, 4:48 AM
This revision was automatically updated to reflect the committed changes.

hi!

this seem to have regressed compilation for some valid C++ code:

struct Bar {
  const char *name();
};
struct Baz {
  static Bar *method();
};
struct Foo {
  Foo(const char *);
};

template <typename T> void bar() { Foo _(T::method()->name()); }
void foo() { bar<Baz>(); }

compiles fine without this change, starting with this it produces the following error:

a.cc:11:55: error: expected unqualified-id
template <typename T> void bar() { Foo _(T::method()->name()); }
                                                      ^
a.cc:11:40: error: no matching constructor for initialization of 'Foo'
template <typename T> void bar() { Foo _(T::method()->name()); }
                                       ^
a.cc:12:14: note: in instantiation of function template specialization 'bar<Baz>' requested here
void foo() { bar<Baz>(); }
             ^
a.cc:8:3: note: candidate constructor not viable: requires 1 argument, but 0 were provided
  Foo(const char *);
  ^
a.cc:7:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
struct Foo {
       ^
a.cc:7:8: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided

https://github.com/llvm/llvm-project/issues/62733 is the bug report that triggered the investigation.

cor3ntin reopened this revision.May 16 2023, 11:58 PM

@kadircet thanks for letting me know, I'm investigating

This revision is now accepted and ready to land.May 16 2023, 11:58 PM
cor3ntin updated this revision to Diff 522979.May 17 2023, 3:24 AM
  • When tentative parse an abstract declarator whithout auto specifier, do not classify it as a declaration based on the presence of arrow
  • When tentative parse a declarion vs member access, do not annotate the token after the arrow expression as this annotation would be incorrect.
aaron.ballman added inline comments.May 18 2023, 10:45 AM
clang/lib/Parse/ParseTentative.cpp
2178–2182

This comment looks like it can be re-flowed to 80 columns instead of shortened like this.

2185–2187

Something smells off here -- NextToken() is a peek; were you trying to advance the tokens stream? If not, then Next.is(...) would be more clear.

cor3ntin updated this revision to Diff 523729.May 19 2023, 4:18 AM

Address Aaron's feedback

This revision was landed with ongoing or failed builds.May 20 2023, 4:23 AM
This revision was automatically updated to reflect the committed changes.