Skip to content

Ensure we have a bound node for the unsafe block so that region analysis works correctly.#45334

Merged
gafter merged 3 commits intodotnet:masterfrom
gafter:master-4950
Jun 24, 2020
Merged

Ensure we have a bound node for the unsafe block so that region analysis works correctly.#45334
gafter merged 3 commits intodotnet:masterfrom
gafter:master-4950

Conversation

@gafter
Copy link
Member

@gafter gafter commented Jun 20, 2020

Fixes #4950

@gafter gafter added this to the Compiler.Net5 milestone Jun 20, 2020
@gafter gafter requested review from a team as code owners June 20, 2020 00:13
@gafter gafter self-assigned this Jun 20, 2020
// The C# binder produces an extra block for checked, unchecked, and unsafe statements, but they have no semantics of their own
boundBlock = boundBlock switch
{
{ Syntax: CheckedStatementSyntax _, Locals: { IsDefaultOrEmpty: true }, Statements: { Length: 1 } s } => (BoundBlock)s[0],
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 21, 2020

Choose a reason for hiding this comment

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

Syntax: CheckedStatementSyntax [](start = 18, length = 30)

I think we are trying to follow the principle that semantic meaning of bound nodes shouldn't depend on their associated syntax. This condition violates the principle. #Closed

// The C# binder produces an extra block for checked, unchecked, and unsafe statements, but they have no semantics of their own
boundBlock = boundBlock switch
{
{ Syntax: CheckedStatementSyntax _, Locals: { IsDefaultOrEmpty: true }, Statements: { Length: 1 } s } => (BoundBlock)s[0],
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 21, 2020

Choose a reason for hiding this comment

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

Locals [](start = 52, length = 6)

The block could also have LocalFunctions. #Closed

// The C# binder produces an extra block for checked, unchecked, and unsafe statements, but they have no semantics of their own
boundBlock = boundBlock switch
{
{ Syntax: CheckedStatementSyntax _, Locals: { IsDefaultOrEmpty: true }, Statements: { Length: 1 } s } => (BoundBlock)s[0],
Copy link
Contributor

@AlekseyTs AlekseyTs Jun 21, 2020

Choose a reason for hiding this comment

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

(BoundBlock) [](start = 121, length = 12)

The unconditional cast makes the code fragile, I believe. #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jun 21, 2020

@gafter

Ensure we have a bound node for the unsafe block so that region analysis works correctly.

Could you please elaborate why is that dummy block necessary for correct behavior of the region analysis. Do we have the same issue with parenthesized expressions missing from the bound tree? If we don't, could we treat unsafe/checked/unchecked statements in a similar manner? #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jun 21, 2020

I suspect we are failing to detect when we enter and leave the region. Could we simply dig through these statements when we determining the boundaries? #Closed

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jun 21, 2020

Done with review pass (iteration 1) #Closed


[|
IntPtr p;
unsafe
Copy link
Contributor

@CyrusNajmabadi CyrusNajmabadi Jun 22, 2020

Choose a reason for hiding this comment

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

Suggested change
unsafe
{keyword}
``` #Resolved

private static IntPtr NewMethod(object value)
{
IntPtr p;
unsafe
Copy link
Contributor

@CyrusNajmabadi CyrusNajmabadi Jun 22, 2020

Choose a reason for hiding this comment

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

Suggested change
unsafe
{keyword}
``` #Resolved

}
}
";
await TestExtractMethodAsync(code.Replace("unsafe", keyword), expected.Replace("unsafe", keyword));
Copy link
Contributor

@CyrusNajmabadi CyrusNajmabadi Jun 22, 2020

Choose a reason for hiding this comment

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

Suggested change
await TestExtractMethodAsync(code.Replace("unsafe", keyword), expected.Replace("unsafe", keyword));
await TestExtractMethodAsync(code, expected);
``` #Resolved

Comment on lines +11287 to +11289
[Fact, Trait(Traits.Feature, Traits.Features.ExtractMethod)]
[WorkItem(4950, "https://github.com/dotnet/roslyn/issues/4950")]
public async Task ExtractMethodInvolvingUnsafeBlock()
Copy link
Contributor

@CyrusNajmabadi CyrusNajmabadi Jun 22, 2020

Choose a reason for hiding this comment

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

Suggested change
[Fact, Trait(Traits.Feature, Traits.Features.ExtractMethod)]
[WorkItem(4950, "https://github.com/dotnet/roslyn/issues/4950")]
public async Task ExtractMethodInvolvingUnsafeBlock()
[Theory, InlineData("unsafe", "checked", "unchecked")]
[Trait(Traits.Feature, Traits.Features.ExtractMethod)]
[WorkItem(4950, "https://github.com/dotnet/roslyn/issues/4950")]
public async Task ExtractMethodInvolvingUnsafeBlock(string keyword)
``` #Resolved

Comment on lines +11291 to +11292
foreach (string keyword in new[] { "unsafe", "checked", "unchecked" })
{
Copy link
Contributor

@CyrusNajmabadi CyrusNajmabadi Jun 22, 2020

Choose a reason for hiding this comment

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

Suggested change
foreach (string keyword in new[] { "unsafe", "checked", "unchecked" })
{
``` #Resolved

Copy link
Contributor

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

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

IDE test change LGTM. Just showing the expected way to normally write a parameterized test. This has teh value of making 3 independent tests that can then be individually run in case only one of them fails and you need to debug it :)

@jaredpar jaredpar modified the milestones: Compiler.Net5, 16.8 Jun 23, 2020
@gafter
Copy link
Member Author

gafter commented Jun 23, 2020

@AlekseyTs @CyrusNajmabadi I think I've responded to all of your comments. Do you have any others?

@333fred Would you please review this PR?

Copy link
Member

@333fred 333fred left a comment

Choose a reason for hiding this comment

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

Done review pass (commit 2)

@AlekseyTs
Copy link
Contributor

AlekseyTs commented Jun 23, 2020

Done with review pass (iteration 2) #Closed

@gafter
Copy link
Member Author

gafter commented Jun 24, 2020

@AlekseyTs I think I've responded to all of your comments. Do you have any others?

Copy link
Contributor

@AlekseyTs AlekseyTs left a comment

Choose a reason for hiding this comment

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

LGTM (iteration 3), assuming CI is passing

@gafter gafter merged commit 2f626aa into dotnet:master Jun 24, 2020
@ghost ghost modified the milestones: 16.8, Next Jun 24, 2020
@dibarbet dibarbet modified the milestones: Next, 16.7.P4 Jun 30, 2020
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.

Extract Method refactoring fails to capture inputs/outputs when unsafe blocks are included

6 participants