public void ExplodedGraph_BothBranchesVisited_NonCondition()
        {
            string        testInput = "var str = this?.ToString();";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var countConditionEvaluated = 0;

            explodedGraph.ConditionEvaluated += (sender, args) => { countConditionEvaluated++; };

            var visitedBlocks = new HashSet <Block>();

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                visitedBlocks.Add(args.ProgramPoint.Block);
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(cfg.Blocks.Count() - 1 /* Exit block */, visitedBlocks.Count);
            Assert.AreEqual(0, countConditionEvaluated);
        }
        private static ISymbol GetSymbol()
        {
            var testInput = "var a = true; var b = false; b = !b; a = (b);";
            var method    = ControlFlowGraphTest.CompileWithMethodBody(string.Format(ControlFlowGraphTest.TestInput, testInput), "Bar", out var semanticModel);

            return(semanticModel.GetDeclaredSymbol(method));
        }
        public void ExplodedGraph_SequentialInput_Max()
        {
            var inputBuilder = new StringBuilder();

            for (int i = 0; i < ExplodedGraph.MaxStepCount / 2 + 1; i++)
            {
                inputBuilder.AppendLine($"var x{i} = true;");
            }
            string        testInput = inputBuilder.ToString();
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };
            var maxStepCountReached = false;

            explodedGraph.MaxStepCountReached += (sender, args) => { maxStepCountReached = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            explodedGraph.Walk();

            Assert.IsFalse(explorationEnded);
            Assert.IsTrue(maxStepCountReached);
            Assert.AreEqual(0, numberOfExitBlockReached);
        }
        public void ExplodedGraph_LoopExploration()
        {
            string        testInput = "var i = 0; while (i < 1) { i = i + 1; }";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var exceeded = 0;

            explodedGraph.ProgramPointVisitCountExceedLimit += (sender, args) =>
            {
                exceeded++;
                args.ProgramPoint.Block.Instructions.Where(i => i.ToString() == "i < 1").Should().NotBeEmpty();
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(1, exceeded);
        }
        public void ExplodedGraph_SequentialInput_Max()
        {
            var inputBuilder = new StringBuilder();

            for (var i = 0; i < CSharpExplodedGraph.MaxStepCount / 2 + 1; i++)
            {
                inputBuilder.AppendLine($"var x{i} = true;");
            }
            var testInput    = inputBuilder.ToString();
            var method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };
            var maxStepCountReached = false;

            explodedGraph.MaxStepCountReached += (sender, args) => { maxStepCountReached = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            explodedGraph.Walk();

            explorationEnded.Should().BeFalse();
            maxStepCountReached.Should().BeTrue();
            numberOfExitBlockReached.Should().Be(0);
        }
        public void ExplodedGraph_BothBranchesVisited_NonCondition()
        {
            var testInput    = "var str = this?.ToString();";
            var method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var countConditionEvaluated = 0;

            explodedGraph.ConditionEvaluated += (sender, args) => { countConditionEvaluated++; };

            var visitedBlocks = new HashSet <Block>();

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                visitedBlocks.Add(args.ProgramPoint.Block);
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            visitedBlocks.Count.Should().Be(cfg.Blocks.Count() - 1 /* Exit block */);
            countConditionEvaluated.Should().Be(0);
        }
        public void ExplodedGraph_LoopExploration()
        {
            var testInput    = "var i = 0; while (i < 1) { i = i + 1; }";
            var method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var exceeded = 0;

            explodedGraph.ProgramPointVisitCountExceedLimit += (sender, args) =>
            {
                exceeded++;
                args.ProgramPoint.Block.Instructions.Should().Contain(i => i.ToString() == "i < 1");
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            exceeded.Should().Be(1);
        }
        public void ExplodedGraph_SingleBranchVisited_If()
        {
            string        testInput = "var a = false; bool b; if (a) { b = true; } else { b = false; } a = b;";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var           bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfLastInstructionVisits = 0;
            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = false")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);
                }
                if (args.Instruction.ToString() == "b = true")
                {
                    Assert.Fail("We should never get into this branch");
                }
                if (args.Instruction.ToString() == "b = false")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(bSymbol) == SymbolicValue.False);
                    Assert.IsNull(args.ProgramState.GetSymbolValue(aSymbol),
                                  "a is dead, so there should be no associated value to it.");
                }
                if (args.Instruction.ToString() == "a = b")
                {
                    numberOfLastInstructionVisits++;
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(10, numberOfProcessedInstructions);
            Assert.AreEqual(1, numberOfExitBlockReached);
            Assert.AreEqual(1, numberOfLastInstructionVisits);
        }
        public void ExplodedGraph_SequentialInput()
        {
            string        testInput = "var a = true; var b = false; b = !b; a = (b);";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var           bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = true")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "b = false")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(bSymbol) == SymbolicValue.False);
                }
                if (args.Instruction.ToString() == "b = !b")
                {
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(bSymbol) == SymbolicValue.False);
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(bSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "a = (b)")
                {
                    Assert.AreEqual(
                        args.ProgramState.GetSymbolValue(bSymbol),
                        args.ProgramState.GetSymbolValue(aSymbol));
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(11, numberOfProcessedInstructions);
            Assert.AreEqual(1, numberOfExitBlockReached);
        }
        public void ExplodedGraph_SequentialInput()
        {
            var testInput      = "var a = true; var b = false; b = !b; a = (b);";
            var method         = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = true")
                {
                    args.ProgramState.GetSymbolValue(aSymbol).Should().Be(SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "b = false")
                {
                    args.ProgramState.GetSymbolValue(bSymbol).Should().Be(SymbolicValue.False);
                }
                if (args.Instruction.ToString() == "b = !b")
                {
                    args.ProgramState.GetSymbolValue(bSymbol).Should().NotBe(SymbolicValue.False);
                    args.ProgramState.GetSymbolValue(bSymbol).Should().NotBe(SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "a = (b)")
                {
                    args.ProgramState.GetSymbolValue(bSymbol)
                    .Should().Be(args.ProgramState.GetSymbolValue(aSymbol));
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfProcessedInstructions.Should().Be(9);
            numberOfExitBlockReached.Should().Be(1);
        }
        public void ExplodedGraph_AllBranchesVisited()
        {
            string        testInput = "int i = 1; switch (i) { case 1: default: cw1(); break; case 2: cw2(); break; }";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfCw1InstructionVisits  = 0;
            var numberOfCw2InstructionVisits  = 0;
            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "cw1()")
                {
                    numberOfCw1InstructionVisits++;
                }
                if (args.Instruction.ToString() == "cw2()")
                {
                    numberOfCw2InstructionVisits++;
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(1, numberOfExitBlockReached);
            Assert.AreEqual(1, numberOfCw1InstructionVisits);
            Assert.AreEqual(1, numberOfCw2InstructionVisits);
        }
        public void ExplodedGraph_BothBranchesVisited_StateMerge()
        {
            string        testInput = "var a = !true; bool b; if (inParameter) { b = false; } else { b = false; } a = b;";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfLastInstructionVisits = 0;
            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = b")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);
                    numberOfLastInstructionVisits++;
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(1, numberOfExitBlockReached);
            Assert.AreEqual(1, numberOfLastInstructionVisits);
        }
        public void ExplodedGraph_SingleBranchVisited_And()
        {
            string        testInput = "var a = false; if (a && !a) { a = true; }";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = !true")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);     // Roslyn is clever !true has const value.
                }
                if (args.Instruction.ToString() == "!a")
                {
                    Assert.Fail("We should never get into this branch");
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(1, numberOfExitBlockReached);
        }
Beispiel #14
0
            public LiveVariableAnalysisContext(string methodBody, string localFunctionName = null)
            {
                var              method = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, methodBody), "Main", out var semanticModel);
                IMethodSymbol    symbol;
                CSharpSyntaxNode body;

                if (localFunctionName == null)
                {
                    symbol = semanticModel.GetDeclaredSymbol(method);
                    body   = method.Body;
                }
                else
                {
                    var function = (LocalFunctionStatementSyntaxWrapper)method.DescendantNodes().Single(x => x.Kind() == SyntaxKindEx.LocalFunctionStatement && ((LocalFunctionStatementSyntaxWrapper)x).Identifier.Text == localFunctionName);
                    symbol = semanticModel.GetDeclaredSymbol(function) as IMethodSymbol;
                    body   = (CSharpSyntaxNode)function.Body ?? function.ExpressionBody;
                }
                this.CFG = CSharpControlFlowGraph.Create(body, semanticModel);
                this.LVA = CSharpLiveVariableAnalysis.Analyze(this.CFG, symbol, semanticModel);
            }
Beispiel #15
0
        public void ExplodedGraph_NonLocalNorFieldSymbolBranching()
        {
            string        testInput = "if (Property) { cw(); }";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           propertySymbol = semanticModel.GetSymbolInfo(
                method.DescendantNodes().OfType <IdentifierNameSyntax>().First(d => d.Identifier.ToString() == "Property")).Symbol;

            propertySymbol.Should().NotBeNull();

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "Property")
                {
                    args.ProgramState.GetSymbolValue(propertySymbol).Should().BeNull();
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfExitBlockReached.Should().Be(1);
        }
        public void ExplodedGraph_NonLocalSymbolBranching()
        {
            string        testInput = "if (field) { cw(); }";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);
            var           fieldSymbol  = semanticModel.GetSymbolInfo(
                method.DescendantNodes().OfType <IdentifierNameSyntax>().First(d => d.Identifier.ToString() == "field")).Symbol;

            Assert.IsNotNull(fieldSymbol);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "field")
                {
                    Assert.IsNull(args.ProgramState.GetSymbolValue(fieldSymbol));
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(1, numberOfExitBlockReached);
        }
Beispiel #17
0
        public void ExplodedGraph_SequentialInput_OutParameter()
        {
            string        testInput = "outParameter = true;";
            SemanticModel semanticModel;
            var           method             = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol       = semanticModel.GetDeclaredSymbol(method);
            var           parameters         = method.DescendantNodes().OfType <ParameterSyntax>();
            var           outParameterSymbol = semanticModel.GetDeclaredSymbol(parameters.First(d => d.Identifier.ToString() == "outParameter"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "outParameter = true")
                {
                    args.ProgramState.GetSymbolValue(outParameterSymbol)
                    .Should().Be(SymbolicValue.True);
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            numberOfProcessedInstructions.Should().Be(2);
            numberOfExitBlockReached.Should().Be(1);
        }
        public void ExplodedGraph_NonDecisionMakingAssignments()
        {
            string        testInput = "var a = true; a |= false; var b = 42; b++; ++b;";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var           bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);

            SymbolicValue sv = null;
            var           numberOfProcessedInstructions = 0;
            var           branchesVisited = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = true")
                {
                    branchesVisited++;
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "a |= false")
                {
                    branchesVisited++;
                    Assert.IsNotNull(args.ProgramState.GetSymbolValue(aSymbol));
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "b = 42")
                {
                    branchesVisited++;
                    sv = args.ProgramState.GetSymbolValue(bSymbol);
                    Assert.IsNotNull(sv);
                }
                if (args.Instruction.ToString() == "b++")
                {
                    branchesVisited++;
                    var svNew = args.ProgramState.GetSymbolValue(bSymbol);
                    Assert.IsNotNull(svNew);
                    Assert.AreNotEqual(sv, svNew);
                }
                if (args.Instruction.ToString() == "++b")
                {
                    branchesVisited++;
                    var svNew = args.ProgramState.GetSymbolValue(bSymbol);
                    Assert.IsNotNull(svNew);
                    Assert.AreNotEqual(sv, svNew);
                }
            };

            explodedGraph.Walk();

            Assert.AreEqual(11, numberOfProcessedInstructions);
            Assert.AreEqual(5, branchesVisited);
        }
        public void ExplodedGraph_NonDecisionMakingAssignments()
        {
            var testInput      = "var a = true; a |= false; var b = 42; b++; ++b;";
            var method         = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);

            SymbolicValue sv = null;
            var           numberOfProcessedInstructions = 0;
            var           branchesVisited = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = true")
                {
                    branchesVisited++;
                    args.ProgramState.GetSymbolValue(aSymbol).Should().Be(SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "a |= false")
                {
                    branchesVisited++;
                    args.ProgramState.GetSymbolValue(aSymbol).Should().NotBeNull();
                    args.ProgramState.GetSymbolValue(aSymbol).Should().NotBe(SymbolicValue.False);
                    args.ProgramState.GetSymbolValue(aSymbol).Should().NotBe(SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "b = 42")
                {
                    branchesVisited++;
                    sv = args.ProgramState.GetSymbolValue(bSymbol);
                    sv.Should().NotBeNull();
                }
                if (args.Instruction.ToString() == "b++")
                {
                    branchesVisited++;
                    var svNew = args.ProgramState.GetSymbolValue(bSymbol);
                    svNew.Should().NotBeNull();
                    svNew.Should().NotBe(sv);
                }
                if (args.Instruction.ToString() == "++b")
                {
                    branchesVisited++;
                    var svNew = args.ProgramState.GetSymbolValue(bSymbol);
                    svNew.Should().NotBeNull();
                    svNew.Should().NotBe(sv);
                }
            };

            explodedGraph.Walk();

            numberOfProcessedInstructions.Should().Be(11);
            branchesVisited.Should().Be(5);
        }
        public void ExplodedGraph_BothBranchesVisited()
        {
            var testInput    = "var a = false; bool b; if (inParameter) { b = inParameter; } else { b = !inParameter; } a = b;";
            var method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var semanticModel);
            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var parameters        = method.DescendantNodes().OfType <ParameterSyntax>();
            var inParameterSymbol = semanticModel.GetDeclaredSymbol(parameters.First(d => d.Identifier.ToString() == "inParameter"));

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfLastInstructionVisits = 0;
            var numberOfProcessedInstructions = 0;

            var visitedBlocks   = new HashSet <Block>();
            var branchesVisited = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                visitedBlocks.Add(args.ProgramPoint.Block);

                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = false")
                {
                    branchesVisited++;

                    args.ProgramState.GetSymbolValue(aSymbol).Should().Be(SymbolicValue.False);     // Roslyn is clever !true has const value.
                }
                if (args.Instruction.ToString() == "b = inParameter")
                {
                    branchesVisited++;

                    bSymbol.HasConstraint(BoolConstraint.True, args.ProgramState).Should().BeTrue();
                    inParameterSymbol.HasConstraint(BoolConstraint.True, args.ProgramState).Should().BeTrue();
                }
                if (args.Instruction.ToString() == "b = !inParameter")
                {
                    branchesVisited++;

                    // b has value, but not true or false
                    args.ProgramState.GetSymbolValue(bSymbol).Should().NotBeNull();
                    bSymbol.HasConstraint(BoolConstraint.False, args.ProgramState).Should().BeFalse();
                    bSymbol.HasConstraint(BoolConstraint.True, args.ProgramState).Should().BeFalse();

                    inParameterSymbol.HasConstraint(BoolConstraint.False, args.ProgramState).Should().BeTrue();
                }
                if (args.Instruction.ToString() == "a = b")
                {
                    branchesVisited++;

                    args.ProgramState.GetSymbolValue(inParameterSymbol).Should().BeNull();     // not out/ref parameter and LVA says dead
                    numberOfLastInstructionVisits++;
                }
            };

            explodedGraph.Walk();

            explorationEnded.Should().BeTrue();
            branchesVisited.Should().Be(4 + 1);
            numberOfExitBlockReached.Should().Be(1,
                                                 "All variables are dead at the ExitBlock, so whenever we get there, the ExplodedGraph nodes should be the same, " +
                                                 "and thus should be processed only once.");
            numberOfLastInstructionVisits.Should().Be(2);

            visitedBlocks.Count.Should().Be(cfg.Blocks.Count() - 1 /* Exit block*/);
        }
Beispiel #21
0
 public ExplodedGraphContext(string methodBody)
     : this(ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, methodBody), "Main", out var semanticModel), semanticModel)
 {
 }
        public void ExplodedGraph_InternalStateCount_MaxReached()
        {
            var testInput    = @"
using System;

namespace TesteAnalyzer
{
    class Program
    {
        static bool GetBool() { return bool.Parse(""True""); }

        static void Main(string[] args)
        {
            bool corrupted = false;
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();

            if (!corrupted)
            {
                Console.Out.WriteLine();
            }
        }
    }
}
";
            var tree         = ControlFlowGraphTest.Compile(testInput, out var semanticModel);
            var method       = tree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().First(m => m.Identifier.ValueText == "Main");
            var methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = CSharpControlFlowGraph.Create(method.Body, semanticModel);
            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new CSharpExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };
            var maxStepCountReached = false;

            explodedGraph.MaxStepCountReached += (sender, args) => { maxStepCountReached = true; };
            var maxInternalStateCountReached = false;

            explodedGraph.MaxInternalStateCountReached += (sender, args) => { maxInternalStateCountReached = true; };

            explodedGraph.Walk();

            explorationEnded.Should().BeFalse();
            maxStepCountReached.Should().BeFalse();
            maxInternalStateCountReached.Should().BeTrue();
        }
Beispiel #23
0
    public string Main()
    {{
        return {ControlFlowGraphTest.ExtremelyNestedExpression()};
    }}
}}";