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

Avoid cycles in constant initializer #75366

Closed
wants to merge 3 commits into from

Conversation

jjonescz
Copy link
Member

@jjonescz jjonescz commented Oct 3, 2024

Fixes #75353.

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Oct 3, 2024
{
var source = """
const int x =
checked(x);
Copy link
Member Author

Choose a reason for hiding this comment

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

Note that the issue is not just with switch expressions. I added this test to demonstrate that. The stack overflow can happen anywhere we get a binder using this.GetBinder(node) because then we lose the current LocalInProgressBinder which the cycle detection was relying on.

@jjonescz jjonescz marked this pull request as ready for review October 3, 2024 16:41
@jjonescz jjonescz requested a review from a team as a code owner October 3, 2024 16:41
@@ -574,7 +574,7 @@ private void MakeConstantTuple(LocalSymbol inProgress, BoundExpression boundInit

internal override ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, BindingDiagnosticBag diagnostics = null)
{
if (this.IsConst && inProgress == this)
if (this.IsConst && (inProgress == this || this.ForbiddenZone?.Contains(node) == true))
Copy link
Member

Choose a reason for hiding this comment

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

This will catch a direct reference to x in the initializer for const x. Is there also a problem with an indirect reference: const int x = y; const int y = ...x...;?

Copy link
Member Author

@jjonescz jjonescz Oct 3, 2024

Choose a reason for hiding this comment

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

Could not reproduce that failing even in main. Added tests.

@jcouv jcouv self-assigned this Oct 3, 2024
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.

Done with review pass (iteration 2)

public void ConstCycle_SwitchExpression_MutuallyReferencing()
{
var source = """
const int y = x switch { };
Copy link
Member

Choose a reason for hiding this comment

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

{ }

nit: consider adding _ => 0 to simplify diagnostics

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 3)

@@ -574,7 +574,7 @@ private void MakeConstantTuple(LocalSymbol inProgress, BoundExpression boundInit

internal override ConstantValue GetConstantValue(SyntaxNode node, LocalSymbol inProgress, BindingDiagnosticBag diagnostics = null)
{
if (this.IsConst && inProgress == this)
if (this.IsConst && (inProgress == this || this.ForbiddenZone?.Contains(node) == true))
Copy link
Contributor

Choose a reason for hiding this comment

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

|| this.ForbiddenZone?.Contains(node) == true)

While, perhaps, this change prevents the stack overflow for the specific scenario, I think we should be addressing the root cause of the problem, i.e. the binder hierarchy used to perform binding.
I am fine if we proceed with this change as a quick, low risk, temporary fix. But we should follow-up on the issue around binder hierarchy.

@jcouv jcouv marked this pull request as draft October 3, 2024 19:29
@jjonescz jjonescz closed this Oct 11, 2024
@jjonescz jjonescz deleted the 75353-ConstCycle branch October 11, 2024 17:33
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.

crash on assigning result of a switch expression to a constant
3 participants