Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CP] [parser] Ensure that list and map pattern parsing always makes progress. #52376

Closed
stereotype441 opened this issue May 12, 2023 · 4 comments
Assignees
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. cherry-pick-approved Label for approved cherrypick request cherry-pick-merged Cherry-pick has been merged to the stable or beta branch. cherry-pick-review Issue that need cherry pick triage to approve merge-to-stable

Comments

@stereotype441
Copy link
Member

Commit(s) to merge

8d2b2a1

Target

Stable

Prepared changelist for beta/stable

https://dart-review.googlesource.com/c/sdk/+/303081

Issue Description

In some circumstances involving error recovery, the parser can fail to make progress, resulting in an infinite loop, which causes the analysis server to become unresponsive and consume progressively more memory. For example, the following code triggers the infinite loop:

void f(Object? x) {
  switch (x) {
    case [if]:
  };
}

Note that due to code completion this situation is not as rare as it might seem at first. If the user types case [ and then requests code completions, one of the possible completions is if. Accepting this completion, even for only a split second, triggers the error condition.

What is the fix

The parser is modified so that when handling a list or map pattern, if an attempt to parse a sub-pattern fails to consume any tokens, the next token is dropped. This ensures that progress is made, and the parser can finish parsing the input file.

Why cherry-pick

Without the cherry-pick, the analysis server may become unresponsive and rapidly consume memory while the user is typing.

The fix only takes effect when a list or map pattern is being parsed, and the parser fails to make progress when trying to parse a sub-pattern; this in turn can only happen when there is a parse error. Since well-formed patterns always contain at least noe token, parsing of correct code is unaffected, so the fix should be low-risk.

Risk

low

Issue link(s)

#52352

Extra Info

No response

@stereotype441
Copy link
Member Author

Note: there are currently some failures on the analyzer-win-release bot that may or may not bisect to this CL (see https://ci.chromium.org/ui/p/dart/builders/ci.sandbox/analyzer-win-release/23007/overview). I'm currently coordinating with the analyzer team to investigate. I won't merge this change until I have more definitive information about the source of the failures.

@itsjustkevin itsjustkevin added cherry-pick-hold Hold off on this cherry-pick and removed cherry-pick-hold Hold off on this cherry-pick labels May 15, 2023
@stereotype441
Copy link
Member Author

Just got confirmation from @bwilkerson that the test failures on analyzer-win-release are unrelated to the CL I want to cherry-pick, so this cherry-pick is ready for review now.

@stereotype441 stereotype441 removed the cherry-pick-hold Hold off on this cherry-pick label May 15, 2023
@lrhn lrhn added the area-front-end Use area-front-end for front end / CFE / kernel format related issues. label May 17, 2023
@srawlins
Copy link
Member

I approve 👍

@sigmundch
Copy link
Member

I'm in favor of including this too

@itsjustkevin itsjustkevin added cherry-pick-approved Label for approved cherrypick request merge-to-stable labels May 19, 2023
copybara-service bot pushed a commit that referenced this issue May 19, 2023
…es progress.

In rare circumstances involving syntax errors, the `parsePattern`
method inserts a synthetic token but does not consume any
tokens. Usually when this happens it's not a problem, because whatever
method is calling `parsePattern` consumes some tokens, so the parser
always makes progress. However, when parsing list patterns, after
calling `parsePattern`, the parser would look for a `,`, and if it
didn't find one, it would supply a synthetic `,` and call
`parsePattern` again, resulting in an infinite loop. A similar
situation happened with map patterns, though the situation was more
complex because in between the calls to `parsePattern`, the parser
would also create synthetic key expressions and `:`s.

To fix the problem, when parsing a list or map pattern, after the call
to `parsePattern`, the parser checks whether any tokens were
consumed. If no tokens were consumed, it ignores the next token from
the input stream in order to make progress.

I also investigated whether there were similar issues with
parenthesized/record patterns and switch expressions, since those
constructs also consist of a sequence of patterns separated by tokens
and other things that could in principle be supplied
synthetically. Fortunately, parser recovery doesn't get into an
infinite loop in those cases, so I didn't make any further
changes. But I did include test cases to make sure.

Fixes: #52376

Bug: #52352
Change-Id: Ic9abf1bb82b8d7e1eb18e8a771a2ff9116fcfe21
Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/302803
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/303081
Reviewed-by: Jens Johansen <[email protected]>
Reviewed-by: Konstantin Shcheglov <[email protected]>
Commit-Queue: Paul Berry <[email protected]>
@itsjustkevin itsjustkevin added the cherry-pick-merged Cherry-pick has been merged to the stable or beta branch. label May 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-front-end Use area-front-end for front end / CFE / kernel format related issues. cherry-pick-approved Label for approved cherrypick request cherry-pick-merged Cherry-pick has been merged to the stable or beta branch. cherry-pick-review Issue that need cherry pick triage to approve merge-to-stable
Projects
None yet
Development

No branches or pull requests

9 participants