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

Local function calls don't work in DataFlowsOutWalker #39569

Open
agocke opened this issue Oct 29, 2019 · 0 comments
Open

Local function calls don't work in DataFlowsOutWalker #39569

agocke opened this issue Oct 29, 2019 · 0 comments

Comments

@agocke
Copy link
Member

agocke commented Oct 29, 2019

DataFlowsOut expects to intercept all assignments by overriding the AssignImpl method in definite assignment. This method requires the bound node of the value, being assigned and the bound node of the variable being assigned. That information is not available for local function calls and is not possible to store.

To make this API work for local function calls we need a new interception point that only requires the slot being assigned, since that is all that is stored for local functions and should be sufficient to provide the basic information for DataFlowsOut.

see the following test:

        [Fact]
        [WorkItem(39569, "https://github.com/dotnet/roslyn/issues/39569")]
        public void AssignmentInsideLocal05()
        {
            var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowStatements(@"
class Program
{
    static void Main()
    {
        int x = 3, y = 4;
        void Local()
        {
            x = 1;
        }
/*<bind>*/
        Local();
/*</bind>*/
        System.Console.WriteLine(x);
    }
}
");
            // Right now region analysis requires bound nodes for each variable and value being
            // assigned. This doesn't work with the current local function analysis because we only
            // store the slots, not the full boundnode of every assignment (which is impossible
            // anyway)
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
            Assert.Null(GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
            Assert.Equal("x, y", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
            Assert.Equal("x", GetSymbolNamesJoined(dataFlowAnalysisResults.Captured));
        }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants