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

Fix rethrowing in nested async catch #71578

Merged
merged 2 commits into from
Jan 24, 2024
Merged

Conversation

jjonescz
Copy link
Member

Fixes #71569.

The async catch rewriter was handling each rethrow via _currentAwaitCatchFrame but that might not be the current catch frame, that's only the nearest catch frame with awaits.

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Jan 11, 2024
@jjonescz jjonescz marked this pull request as ready for review January 11, 2024 15:31
@jjonescz jjonescz requested a review from a team as a code owner January 11, 2024 15:31
return result;
}

// We cannot get here from a catch without awaits.
Debug.Assert(!_inCatchWithoutAwaits);
Copy link
Contributor

@AlekseyTs AlekseyTs Jan 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug.Assert(!_inCatchWithoutAwaits);

Are we certain this is the case? What if a catch without awaits contains another try/catch that uses awaits? The outer catch doesn't use await directly, but the nested one does. Is this assert going to fail when we reach that nested catch with awaits? Are we testing a scenario like that? #Closed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like NestedRethrow_02 covers this scenario

Copy link
Member Author

@jjonescz jjonescz Jan 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the "await analysis" for the outer catch visits the whole block including the nested catches, I think, so it will report any outer catch to contain awaits whenever any of its nested catches contain an await. Hence we cannot have a catch without awaits and nested inside it a catch with awaits.

@AlekseyTs
Copy link
Contributor

LGTM (commit 1)

@jjonescz
Copy link
Member Author

@dotnet/roslyn-compiler for a second review, thanks

@jaredpar jaredpar requested a review from jcouv January 12, 2024 16:51
@jaredpar
Copy link
Member

@jcouv PTAL as second reviewer

@jjonescz
Copy link
Member Author

@jcouv @dotnet/roslyn-compiler for a second review, thanks

@@ -518,11 +519,18 @@ private BoundNode VisitCatchBlock(BoundCatchBlock node, AwaitCatchFrame parentAw
var origCurrentAwaitCatchFrame = _currentAwaitCatchFrame;
_currentAwaitCatchFrame = parentAwaitCatchFrame;

var origInCatchWithoutAwaits = _inCatchWithoutAwaits;
_inCatchWithoutAwaits = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly related to this PR: There are indirect ways of introducing an await in code. For instance, await foreach and await using.
I believe they get lowered to simple await in local rewriter, so should be registered properly as awaits here (CatchContainsAwait). But it may be good to check or test.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks (iteration 1)

@jcouv jcouv self-assigned this Jan 23, 2024
@jjonescz jjonescz enabled auto-merge (squash) January 24, 2024 10:50
@jjonescz jjonescz merged commit f74c2c6 into dotnet:main Jan 24, 2024
25 checks passed
@jjonescz jjonescz deleted the 71569-NestedRethrow branch January 24, 2024 12:15
@ghost ghost added this to the Next milestone Jan 24, 2024
@Cosifne Cosifne modified the milestones: Next, 17.10 P1 Jan 30, 2024
jjonescz added a commit to jjonescz/roslyn that referenced this pull request Feb 20, 2024
* Fix rethrowing in nested async catch

* Test await using and foreach
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Nested catch rethrows the parent exception in async methods
5 participants