Skip to content

Fix faulty cast in state machine rewriter#55063

Merged
333fred merged 1 commit intodotnet:mainfrom
333fred:crash-switch-cast
Jul 23, 2021
Merged

Fix faulty cast in state machine rewriter#55063
333fred merged 1 commit intodotnet:mainfrom
333fred:crash-switch-cast

Conversation

@333fred
Copy link
Copy Markdown
Member

@333fred 333fred commented Jul 23, 2021

HoistRefInitialization assumed that the declarator syntax for locals would always be an await expression, but this is not true for switch expressions. CalculateLocalSyntaxOffset already correctly handles switch expressions, so we just needed to update this call site. I also inspected any other calls to CalculateLocalSyntaxOffset to make sure that nothing else was making such an assumption, but I didn't see any that are concerning.

Fixes #51930.

HoistRefInitialization assumed that the declarator syntax for locals would always be an await expression, but this is not true for switch expressions. CalculateLocalSyntaxOffset already correctly handles switch expressions, so we just needed to update this call site. I also inspected any other calls to CalculateLocalSyntaxOffset to make sure that nothing else was making such an assumption, but I didn't see any that are concerning.
@333fred 333fred requested a review from a team as a code owner July 23, 2021 00:15
@ghost ghost added the Area-Compilers label Jul 23, 2021
@333fred
Copy link
Copy Markdown
Member Author

333fred commented Jul 23, 2021

@dotnet/roslyn-compiler for a quick review.

{
awaitSyntaxOpt = (AwaitExpressionSyntax)local.GetDeclaratorSyntax();
awaitSyntaxOpt = local.GetDeclaratorSyntax();
Debug.Assert(awaitSyntaxOpt.IsKind(SyntaxKind.AwaitExpression) || awaitSyntaxOpt.IsKind(SyntaxKind.SwitchExpression));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you help me understand why only await and switch are expected to be encountered here? For example if I had GetRef() = flag ? await GetAsync() : 42 would I hit this assert?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

You would not hit this assert. There's some differences in the syntaxes used by the SpillSequenceSpiller here, and the local in the case you mentioned would be the await expression, not the ternary. I'd need to dig more into the local rewriter to tell you the exact reasons for that difference.

@333fred
Copy link
Copy Markdown
Member Author

333fred commented Jul 23, 2021

@dotnet/roslyn-compiler for a second review.

@333fred 333fred merged commit a3b5d0f into dotnet:main Jul 23, 2021
@ghost ghost added this to the Next milestone Jul 23, 2021
@333fred 333fred deleted the crash-switch-cast branch July 23, 2021 21:31
@allisonchou allisonchou modified the milestones: Next, 17.0.P3 Jul 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compiler crushes with InvalidCastException in async method with switch-expression assignment to ref-return method

4 participants