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);
        }
        private void CheckForEmptyCollectionAccess(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var check = new EmptyCollectionAccessedCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(check);

            var emptyCollections    = new HashSet <SyntaxNode>();
            var nonEmptyCollections = new HashSet <SyntaxNode>();

            EventHandler <CollectionAccessedEventArgs> collectionAccessedHandler = (sender, args) =>
                                                                                   (args.IsEmpty ? emptyCollections : nonEmptyCollections).Add(args.Node);

            check.CollectionAccessed += collectionAccessedHandler;
            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                check.CollectionAccessed -= collectionAccessedHandler;
            }

            foreach (var node in emptyCollections.Except(nonEmptyCollections))
            {
                context.ReportDiagnostic(Diagnostic.Create(rule, node.GetLocation()));
            }
        }
        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 void CheckForNullDereference(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var nullPointerCheck = new NullPointerCheck(explodedGraph);
            explodedGraph.AddExplodedGraphCheck(nullPointerCheck);

            var nullIdentifiers = new HashSet<IdentifierNameSyntax>();

            EventHandler<MemberAccessedEventArgs> memberAccessedHandler =
                (sender, args) => CollectMemberAccesses(args, nullIdentifiers, context.SemanticModel);

            nullPointerCheck.MemberAccessed += memberAccessedHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                nullPointerCheck.MemberAccessed -= memberAccessedHandler;
            }

            foreach (var nullIdentifier in nullIdentifiers)
            {
                context.ReportDiagnostic(Diagnostic.Create(Rule, nullIdentifier.GetLocation(), nullIdentifier.Identifier.ValueText));
            }
        }
        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);
        }
        private static void CheckEmptyNullableAccess(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var nullPointerCheck = new NullValueAccessedCheck(explodedGraph);
            explodedGraph.AddExplodedGraphCheck(nullPointerCheck);

            var nullIdentifiers = new HashSet<IdentifierNameSyntax>();

            EventHandler<MemberAccessedEventArgs> nullValueAccessedHandler =
                (sender, args) => nullIdentifiers.Add(args.Identifier);

            nullPointerCheck.ValuePropertyAccessed += nullValueAccessedHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                nullPointerCheck.ValuePropertyAccessed -= nullValueAccessedHandler;
            }

            foreach (var nullIdentifier in nullIdentifiers)
            {
                context.ReportDiagnostic(Diagnostic.Create(Rule, nullIdentifier.Parent.GetLocation(), nullIdentifier.Identifier.ValueText));
            }
        }
        private static void CheckEmptyNullableAccess(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var nullPointerCheck = new NullValueAccessedCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(nullPointerCheck);

            var nullIdentifiers = new HashSet <IdentifierNameSyntax>();

            EventHandler <MemberAccessedEventArgs> nullValueAccessedHandler =
                (sender, args) => nullIdentifiers.Add(args.Identifier);

            nullPointerCheck.ValuePropertyAccessed += nullValueAccessedHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                nullPointerCheck.ValuePropertyAccessed -= nullValueAccessedHandler;
            }

            foreach (var nullIdentifier in nullIdentifiers)
            {
                context.ReportDiagnostic(Diagnostic.Create(rule, nullIdentifier.Parent.GetLocation(), nullIdentifier.Identifier.ValueText));
            }
        }
Esempio n. 8
0
        private static void CheckForNullDereference(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var nullPointerCheck = new NullPointerCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(nullPointerCheck);

            var nullIdentifiers = new HashSet <IdentifierNameSyntax>();

            EventHandler <MemberAccessedEventArgs> memberAccessedHandler =
                (sender, args) => CollectMemberAccesses(args, nullIdentifiers, context.SemanticModel);

            nullPointerCheck.MemberAccessed += memberAccessedHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                nullPointerCheck.MemberAccessed -= memberAccessedHandler;
            }

            foreach (var nullIdentifier in nullIdentifiers)
            {
                context.ReportDiagnostic(Diagnostic.Create(Rule, nullIdentifier.GetLocation(), nullIdentifier.Identifier.ValueText));
            }
        }
        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);
        }
Esempio n. 11
0
        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_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_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);
        }
        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);
        }
        private static void CheckForRedundantConditions(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var conditionTrue  = new HashSet <SyntaxNode>();
            var conditionFalse = new HashSet <SyntaxNode>();

            EventHandler <ConditionEvaluatedEventArgs> collectConditions =
                (sender, args) => CollectConditions(args, conditionTrue, conditionFalse);

            EventHandler explorationEnded =
                (sender, args) => ProcessVisitedBlocks(conditionTrue, conditionFalse, context);

            explodedGraph.ExplorationEnded   += explorationEnded;
            explodedGraph.ConditionEvaluated += collectConditions;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                explodedGraph.ExplorationEnded   -= explorationEnded;
                explodedGraph.ConditionEvaluated -= collectConditions;
            }
        }
        private static void CheckForRedundantConditions(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var conditionTrue = new HashSet<SyntaxNode>();
            var conditionFalse = new HashSet<SyntaxNode>();

            EventHandler<ConditionEvaluatedEventArgs> collectConditions =
                (sender, args) => CollectConditions(args, conditionTrue, conditionFalse);

            EventHandler explorationEnded =
                (sender, args) => ProcessVisitedBlocks(conditionTrue, conditionFalse, context);

            explodedGraph.ExplorationEnded += explorationEnded;
            explodedGraph.ConditionEvaluated += collectConditions;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                explodedGraph.ExplorationEnded -= explorationEnded;
                explodedGraph.ConditionEvaluated -= collectConditions;
            }
        }
Esempio n. 17
0
        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 NullValueAccessedCheck(ExplodedGraph explodedGraph)
     : base(explodedGraph)
 {
 }
Esempio n. 19
0
        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 NullableCastCheck(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
     : this(explodedGraph)
 {
     this.context = context;
 }
 public NullValueAccessedCheck(ExplodedGraph explodedGraph)
     : base(explodedGraph)
 {
 }
Esempio n. 22
0
        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);
        }
        public void ExplodedGraph_BothBranchesVisited()
        {
            string        testInput = "var a = false; bool b; if (inParameter) { b = inParameter; } else { b = !inParameter; } 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 parameters        = method.DescendantNodes().OfType <ParameterSyntax>();
            var inParameterSymbol = semanticModel.GetDeclaredSymbol(parameters.First(d => d.Identifier.ToString() == "inParameter"));

            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;

            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++;

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

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

                    // b has value, but not true or false
                    Assert.IsNotNull(args.ProgramState.GetSymbolValue(bSymbol));
                    Assert.IsFalse(bSymbol.HasConstraint(BoolConstraint.False, args.ProgramState));
                    Assert.IsFalse(bSymbol.HasConstraint(BoolConstraint.True, args.ProgramState));

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

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

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(4 + 1, branchesVisited);
            Assert.AreEqual(1, numberOfExitBlockReached,
                            "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.");
            Assert.AreEqual(2, numberOfLastInstructionVisits);

            Assert.AreEqual(cfg.Blocks.Count() - 1 /* Exit block */, visitedBlocks.Count);
        }
            public NullPointerCheck(ExplodedGraph explodedGraph)
                : base(explodedGraph)
            {

            }
Esempio n. 25
0
        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);
        }
 private static void CheckEmptyNullableCast(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
 {
     explodedGraph.AddExplodedGraphCheck(new NullableCastCheck(explodedGraph, context));
     explodedGraph.Walk();
 }
Esempio n. 27
0
 protected ExplodedGraphCheck(ExplodedGraph explodedGraph)
 {
     this.explodedGraph = explodedGraph;
     this.semanticModel = explodedGraph.SemanticModel;
 }
        private static void Analyze(CSharpSyntaxNode declarationBody, ISymbol symbol,
            Action<ExplodedGraph, SyntaxNodeAnalysisContext> analyze, SyntaxNodeAnalysisContext context)
        {
            if (declarationBody == null ||
                declarationBody.ContainsDiagnostics)
            {
                return;
            }

            IControlFlowGraph cfg;
            if (!ControlFlowGraph.TryGet(declarationBody, context.SemanticModel, out cfg))
            {
                return;
            }

            var lva = LiveVariableAnalysis.Analyze(cfg, symbol, context.SemanticModel);

            var explodedGraph = new ExplodedGraph(cfg, symbol, context.SemanticModel, lva);
            analyze(explodedGraph, context);
        }
Esempio n. 29
0
        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);
        }
 public NullableCastCheck(ExplodedGraph explodedGraph)
     : base(explodedGraph)
 {
 }
Esempio n. 31
0
        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);
        }
Esempio n. 32
0
 public NullPointerCheck(ExplodedGraph explodedGraph)
     : base(explodedGraph)
 {
 }
Esempio n. 33
0
        public void ExplodedGraph_BothBranchesVisited()
        {
            string testInput = "var a = false; bool b; if (inParameter) { b = inParameter; } else { b = !inParameter; } 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 parameters = method.DescendantNodes().OfType<ParameterSyntax>();
            var inParameterSymbol = semanticModel.GetDeclaredSymbol(parameters.First(d => d.Identifier.ToString() == "inParameter"));

            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;

            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++;

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

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

                        // b has value, but not true or false
                        Assert.IsNotNull(args.ProgramState.GetSymbolValue(bSymbol));
                        Assert.IsFalse(bSymbol.HasConstraint(BoolConstraint.False, args.ProgramState));
                        Assert.IsFalse(bSymbol.HasConstraint(BoolConstraint.True, args.ProgramState));

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

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

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(4 + 1, branchesVisited);
            Assert.AreEqual(1, numberOfExitBlockReached,
                "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.");
            Assert.AreEqual(2, numberOfLastInstructionVisits);

            Assert.AreEqual(cfg.Blocks.Count() - 1 /* Exit block */, visitedBlocks.Count);
        }
 public NullableCastCheck(ExplodedGraph explodedGraph)
     : base(explodedGraph)
 {
 }
Esempio n. 35
0
        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 NullableCastCheck(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
     : this(explodedGraph)
 {
     this.context = context;
 }
 private static void CheckEmptyNullableCast(ExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
 {
     explodedGraph.AddExplodedGraphCheck(new NullableCastCheck(explodedGraph, context));
     explodedGraph.Walk();
 }
 public EmptyCollectionAccessedCheck(ExplodedGraph explodedGraph)
     : base(explodedGraph)
 {
 }
Esempio n. 39
0
        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_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);
        }