private static void CheckForNullDereference(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { var nullPointerCheck = new NullPointerCheck(explodedGraph); explodedGraph.AddExplodedGraphCheck(nullPointerCheck); var nullIdentifiers = new HashSet <IdentifierNameSyntax>(); void memberAccessedHandler(object sender, MemberAccessedEventArgs args) => CollectMemberAccesses(args, nullIdentifiers, context.SemanticModel); nullPointerCheck.MemberAccessed += memberAccessedHandler; try { explodedGraph.Walk(); } finally { nullPointerCheck.MemberAccessed -= memberAccessedHandler; } foreach (var nullIdentifier in nullIdentifiers) { context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, nullIdentifier.GetLocation(), nullIdentifier.Identifier.ValueText)); } }
public AnalysisContext(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { this.context = context; nullPointerCheck = explodedGraph.NullPointerCheck; nullPointerCheck.MemberAccessed += MemberAccessedHandler; }
public AnalysisContext(CSharpExplodedGraph explodedGraph) { this.objectDisposedPointerCheck = new ObjectDisposedPointerCheck(explodedGraph); this.objectDisposedPointerCheck.ObjectDisposed += ObjectDisposedHandler; explodedGraph.AddExplodedGraphCheck(this.objectDisposedPointerCheck); }
private void CheckForEmptyCollectionAccess(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { var check = new EmptyCollectionAccessedCheck(explodedGraph); explodedGraph.AddExplodedGraphCheck(check); var emptyCollections = new HashSet <SyntaxNode>(); var nonEmptyCollections = new HashSet <SyntaxNode>(); void explorationEnded(object sender, EventArgs args) => emptyCollections.Except(nonEmptyCollections) .Select(node => Diagnostic.Create(rule, node.GetLocation())) .ToList() .ForEach(d => context.ReportDiagnosticWhenActive(d)); void collectionAccessedHandler(object sender, CollectionAccessedEventArgs args) => (args.IsEmpty ? emptyCollections : nonEmptyCollections).Add(args.Node); explodedGraph.ExplorationEnded += explorationEnded; check.CollectionAccessed += collectionAccessedHandler; try { explodedGraph.Walk(); } finally { check.CollectionAccessed -= collectionAccessedHandler; explodedGraph.ExplorationEnded -= explorationEnded; } }
private void CheckForEmptyCollectionAccess(CSharpExplodedGraph 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.ReportDiagnosticWhenActive(Diagnostic.Create(rule, node.GetLocation())); } }
public AnalysisContext(CSharpExplodedGraph explodedGraph) { nullPointerCheck = new NullValueAccessedCheck(explodedGraph); nullPointerCheck.ValuePropertyAccessed += AddIdentifier; explodedGraph.AddExplodedGraphCheck(nullPointerCheck); }
private static void Analyze(CSharpSyntaxNode declarationBody, ISymbol symbol, Action <CSharpExplodedGraph, SyntaxNodeAnalysisContext> runAnalysis, SyntaxNodeAnalysisContext context) { if (declarationBody == null || declarationBody.ContainsDiagnostics) { return; } if (!CSharpControlFlowGraph.TryGet(declarationBody, context.SemanticModel, out var cfg)) { return; } var lva = CSharpLiveVariableAnalysis.Analyze(cfg, symbol, context.SemanticModel); try { var explodedGraph = new CSharpExplodedGraph(cfg, symbol, context.SemanticModel, lva); runAnalysis(explodedGraph, context); } catch (Exception e) { // Roslyn/MSBuild is currently cutting exception message at the end of the line instead // of displaying the full message. As a workaround, we replace the line ending with ' ## '. // See https://github.com/dotnet/roslyn/issues/1455 and https://github.com/dotnet/roslyn/issues/24346 var sb = new StringBuilder(); sb.AppendLine($"Error processing method: {symbol?.Name ?? "{unknown}"}"); sb.AppendLine($"Method file: {declarationBody.GetLocation()?.GetLineSpan().Path ?? "{unknown}"}"); sb.AppendLine($"Method line: {declarationBody.GetLocation()?.GetLineSpan().StartLinePosition.ToString() ?? "{unknown}"}"); sb.AppendLine($"Inner exception: {e}"); throw new SymbolicExecutionException(sb.ToString().Replace(Environment.NewLine, " ## "), e); } }
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 AnalysisContext(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { this.explodedGraph = explodedGraph; this.context = context; explodedGraph.MemberAccessed += MemberAccessedHandler; }
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); }
private static void CheckForMultipleDispose(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { var objectDisposedCheck = new ObjectDisposedPointerCheck(explodedGraph); explodedGraph.AddExplodedGraphCheck(objectDisposedCheck); // Store the nodes that should be reported and ignore duplicate reports for the same node. // This is needed because we generate two CFG blocks for the finally statements and even // though the syntax nodes are the same, when there is a return inside a try/catch block // the walked CFG paths could be different and FPs will appear. var nodesToReport = new Dictionary <SyntaxNode, string>(); void memberAccessedHandler(object sender, ObjectDisposedEventArgs args) { nodesToReport[args.SyntaxNode] = args.SymbolName; } objectDisposedCheck.ObjectDisposed += memberAccessedHandler; try { explodedGraph.Walk(); } finally { objectDisposedCheck.ObjectDisposed -= memberAccessedHandler; } foreach (var item in nodesToReport) { context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, item.Key.GetLocation(), item.Value)); } }
private static void CheckEmptyNullableAccess(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { var nullPointerCheck = new NullValueAccessedCheck(explodedGraph); explodedGraph.AddExplodedGraphCheck(nullPointerCheck); var nullIdentifiers = new HashSet <IdentifierNameSyntax>(); void nullValueAccessedHandler(object sender, MemberAccessedEventArgs args) => nullIdentifiers.Add(args.Identifier); nullPointerCheck.ValuePropertyAccessed += nullValueAccessedHandler; try { explodedGraph.Walk(); } finally { nullPointerCheck.ValuePropertyAccessed -= nullValueAccessedHandler; } foreach (var nullIdentifier in nullIdentifiers) { context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, nullIdentifier.Parent.GetLocation(), nullIdentifier.Identifier.ValueText)); } }
public AnalysisContext(CSharpExplodedGraph explodedGraph) { check = new EmptyCollectionAccessedCheck(explodedGraph); check.CollectionAccessed += CollectionAccessedHandler; explodedGraph.AddExplodedGraphCheck(check); }
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); }
private void Analyze(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { var analyzerContexts = InitializeAnalyzers(explodedGraph, context).ToList(); try { explodedGraph.ExplorationEnded += ExplorationEndedHandler; explodedGraph.Walk(); } finally { explodedGraph.ExplorationEnded -= ExplorationEndedHandler; } // Some of the rules can return good results if the tree was only partially visited; others need to completely // walk the tree in order to avoid false positives. // // Due to this we split the rules in two sets and report the diagnostics in steps: // - When the tree is successfully visited and ExplorationEnded event is raised. // - When the tree visit ends (explodedGraph.Walk() returns). This will happen even if the maximum number of steps was // reached or if an exception was thrown during analysis. ReportDiagnostics(analyzerContexts, context, true); void ExplorationEndedHandler(object sender, EventArgs args) { ReportDiagnostics(analyzerContexts, context, false); } }
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.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 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 numberOfLastInstructionVisits = 0; var numberOfProcessedInstructions = 0; explodedGraph.InstructionProcessed += (sender, args) => { numberOfProcessedInstructions++; if (args.Instruction.ToString() == "a = false") { args.ProgramState.GetSymbolValue(aSymbol).Should().Be(SymbolicValue.False); } if (args.Instruction.ToString() == "b = true") { Execute.Assertion.FailWith("We should never get into this branch"); } if (args.Instruction.ToString() == "b = false") { args.ProgramState.GetSymbolValue(bSymbol).Should().Be(SymbolicValue.False); args.ProgramState.GetSymbolValue(aSymbol) .Should().BeNull("a is dead, so there should be no associated value to it."); } if (args.Instruction.ToString() == "a = b") { numberOfLastInstructionVisits++; } }; explodedGraph.Walk(); explorationEnded.Should().BeTrue(); numberOfProcessedInstructions.Should().Be(8); numberOfExitBlockReached.Should().Be(1); numberOfLastInstructionVisits.Should().Be(1); }
private void Analyze(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { var analyzerContexts = InitializeAnalyzers(explodedGraph, context).ToList(); var steps = explodedGraph.Walk(_maxSteps, _cancellationToken); Steps = Math.Max(Steps, steps); ReportDiagnostics(analyzerContexts, context); }
public void ExplodedGraph_SequentialInput() { string testInput = "var a = true; var b = false; b = !b; 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 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); }
private void Analyze(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { var analyzerContexts = InitializeAnalyzers(explodedGraph, context).ToList(); try { explodedGraph.Walk(); } finally { foreach (var diagnostic in analyzerContexts.SelectMany(analyzerContext => analyzerContext.GetDiagnostics())) { context.ReportDiagnosticWhenActive(diagnostic); } analyzerContexts.ForEach(analyzerContext => analyzerContext.Dispose()); } }
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.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out 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 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(); explorationEnded.Should().BeTrue(); numberOfExitBlockReached.Should().Be(1); numberOfCw1InstructionVisits.Should().Be(1); numberOfCw2InstructionVisits.Should().Be(1); }
public void ExplodedGraph_BothBranchesVisited_StateMerge() { var testInput = "var a = !true; bool b; if (inParameter) { b = false; } else { b = false; } 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 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; explodedGraph.InstructionProcessed += (sender, args) => { numberOfProcessedInstructions++; if (args.Instruction.ToString() == "a = b") { args.ProgramState.GetSymbolValue(aSymbol).Should().Be(SymbolicValue.False); numberOfLastInstructionVisits++; } }; explodedGraph.Walk(); explorationEnded.Should().BeTrue(); numberOfExitBlockReached.Should().Be(1); numberOfLastInstructionVisits.Should().Be(1); }
public void ExplodedGraph_SingleBranchVisited_And() { var testInput = "var a = false; if (a && !a) { a = true; }"; 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 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.False); // Roslyn is clever !true has const value. } if (args.Instruction.ToString() == "!a") { Execute.Assertion.FailWith("We should never get into this branch"); } }; explodedGraph.Walk(); explorationEnded.Should().BeTrue(); numberOfExitBlockReached.Should().Be(1); }
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 = 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() == "Property") { args.ProgramState.GetSymbolValue(propertySymbol).Should().BeNull(); } }; explodedGraph.Walk(); explorationEnded.Should().BeTrue(); numberOfExitBlockReached.Should().Be(1); }
public void ExplodedGraph_SequentialInput_OutParameter() { var testInput = "outParameter = true;"; var method = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out var 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 = 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() == "outParameter = true") { args.ProgramState.GetSymbolValue(outParameterSymbol) .Should().Be(SymbolicValue.True); } }; explodedGraph.Walk(); explorationEnded.Should().BeTrue(); numberOfProcessedInstructions.Should().Be(2); numberOfExitBlockReached.Should().Be(1); }
private static void CheckForMultipleDispose(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) { var objectDisposedCheck = new ObjectDisposedPointerCheck(explodedGraph); explodedGraph.AddExplodedGraphCheck(objectDisposedCheck); void memberAccessedHandler(object sender, ObjectDisposedEventArgs args) { context.ReportDiagnosticWhenActive( Diagnostic.Create(rule, args.Location, args.Name)); } objectDisposedCheck.ObjectDisposed += memberAccessedHandler; try { explodedGraph.Walk(); } finally { objectDisposedCheck.ObjectDisposed -= memberAccessedHandler; } }
private IEnumerable <ISymbolicExecutionAnalysisContext> InitializeAnalyzers(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) => symbolicExecutionAnalyzerFactory .GetEnabledAnalyzers(context) .Select(analyzer => analyzer.AddChecks(explodedGraph, context));
public ISymbolicExecutionAnalysisContext AddChecks(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) => new AnalysisContext(explodedGraph);
public EmptyCollectionAccessedCheck(CSharpExplodedGraph explodedGraph) : base(explodedGraph) { }
public NullValueAccessedCheck(CSharpExplodedGraph explodedGraph) : base(explodedGraph) { }
public ObjectDisposedPointerCheck(CSharpExplodedGraph explodedGraph, AnalysisContext context) : base(explodedGraph) => this.context = context;