private static ControlFlowGraph Graph(string path) { var code = File.ReadAllText(path, Encoding.UTF8); var tree = CSharpSyntaxTree.ParseText(code); var compilation = CSharpCompilation.Create( "Suspension.Tests.Samples", new[] { tree }, new[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile("C:\\Program Files\\dotnet\\shared\\Microsoft.NETCore.App\\3.1.13\\System.Runtime.dll"), MetadataReference.CreateFromFile(typeof(Coroutine).Assembly.Location) }, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) ); var semantic = compilation.GetSemanticModel(tree); var method = tree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .That( new HasAttribute(semantic, new FullName("global::Suspension.SuspendableAttribute")) ) .Single(); return(ControlFlowGraph.Create(method, semantic)); }
public void LambdaFlow_04() { string source = @" struct C { void M(System.Action d1, System.Action<bool, bool> d2) /*<bind>*/{ d1 = () => { d2 = (bool result1, bool input1) => { result1 = input1; }; }; void local(bool result2, bool input2) => result2 = input2; }/*</bind>*/ } "; var compilation = CreateCompilation(source); var tree = compilation.SyntaxTrees.Single(); var semanticModel = compilation.GetSemanticModel(tree); var graphM = ControlFlowGraph.Create((IMethodBodyOperation)semanticModel.GetOperation(tree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().Single())); Assert.NotNull(graphM); Assert.Null(graphM.Parent); IFlowAnonymousFunctionOperation lambdaD1 = getLambda(graphM); Assert.Throws <ArgumentNullException>(() => graphM.GetLocalFunctionControlFlowGraph(null)); Assert.Throws <ArgumentOutOfRangeException>(() => graphM.GetLocalFunctionControlFlowGraph(lambdaD1.Symbol)); Assert.Throws <ArgumentNullException>(() => graphM.GetLocalFunctionControlFlowGraphInScope(null)); Assert.Throws <ArgumentOutOfRangeException>(() => graphM.GetLocalFunctionControlFlowGraphInScope(lambdaD1.Symbol)); var graphD1 = graphM.GetAnonymousFunctionControlFlowGraph(lambdaD1); Assert.NotNull(graphD1); Assert.Same(graphM, graphD1.Parent); var graphD1_FromExtension = graphM.GetAnonymousFunctionControlFlowGraphInScope(lambdaD1); Assert.Same(graphD1, graphD1_FromExtension); IFlowAnonymousFunctionOperation lambdaD2 = getLambda(graphD1); var graphD2 = graphD1.GetAnonymousFunctionControlFlowGraph(lambdaD2); Assert.NotNull(graphD2); Assert.Same(graphD1, graphD2.Parent); Assert.Throws <ArgumentNullException>(() => graphM.GetAnonymousFunctionControlFlowGraph(null)); Assert.Throws <ArgumentOutOfRangeException>(() => graphM.GetAnonymousFunctionControlFlowGraph(lambdaD2)); Assert.Throws <ArgumentNullException>(() => graphM.GetAnonymousFunctionControlFlowGraphInScope(null)); Assert.Throws <ArgumentOutOfRangeException>(() => graphM.GetAnonymousFunctionControlFlowGraphInScope(lambdaD2)); IFlowAnonymousFunctionOperation getLambda(ControlFlowGraph graph) { return(graph.Blocks.SelectMany(b => b.Operations.SelectMany(o => o.DescendantsAndSelf())).OfType <IFlowAnonymousFunctionOperation>().Single()); } }
static void Main(string [] args) { //var method = GetProgramMethod ("Triangle1"); AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(args[1]); TypeDefinition type = assembly.MainModule.GetType("TestCase"); MethodDefinition method = GetMethod(type.Methods, "Main"); var cfg = ControlFlowGraph.Create(method); FormatControlFlowGraph(Console.Out, cfg); Console.WriteLine("--------------------"); var store = AnnotationStore.CreateStore(cfg, BlockOptimization.Detailed); PrintAnnotations(method, store); var language = CSharp.GetLanguage(CSharpVersion.V1); //var body = method.Body.Decompile (language); var writer = language.GetWriter(new PlainTextFormatter(Console.Out)); writer.Write(method); Console.ReadKey(); }
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 EvaluationResult Evaluate(Dictionary <VariableSymbol, object> variables) { if (this.GlobalScope.Diagnostics.Any()) { return(new EvaluationResult(this.GlobalScope.Diagnostics, null)); } var program = this.GetProgram(); #if false // CFG Graphviz output var appPath = Environment.GetCommandLineArgs()[0]; var appDirectory = Path.GetDirectoryName(appPath) !; var cfgPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Slang", "cfg.dot"); //Path.Combine( appDirectory , "cfg.dot" ); var cfgStatement = !program.Statement.Statements.Any() && program.Functions.Any() ? program.Functions.Last().Value : program.Statement; var cfg = ControlFlowGraph.Create(cfgStatement); using var streamWriter = new StreamWriter(cfgPath); cfg.WriteTo(streamWriter); #endif if (program.Diagnostics.Any()) { return(new EvaluationResult(program.Diagnostics.ToImmutableArray(), null)); } var evaluator = new Evaluator(program, variables); var value = evaluator.Evaluate(); return(new EvaluationResult(ImmutableArray <Diagnostic> .Empty, value)); }
protected void RunTestCase(string name) { MethodDefinition method = LoadTestCaseMethod(name); ControlFlowGraph cfg = ControlFlowGraph.Create(method); Assert.AreEqual(Normalize(LoadExpectedControlFlowString(name)), Normalize(ToString(cfg))); }
public bool TryGetOrComputeResult( ImmutableArray <IOperation> operationBlocks, IMethodSymbol containingMethod, bool trackInstanceFields, out DataFlowAnalysisResult <DisposeBlockAnalysisResult, DisposeAbstractValue> disposeAnalysisResult, out DataFlowAnalysisResult <PointsToBlockAnalysisResult, PointsToAbstractValue> pointsToAnalysisResult, out ImmutableDictionary <IFieldSymbol, PointsToAbstractValue> trackedInstanceFieldPointsToMap) { foreach (var operationRoot in operationBlocks) { IBlockOperation topmostBlock = operationRoot.GetTopmostParentBlock(); if (topmostBlock != null) { var cfg = ControlFlowGraph.Create(topmostBlock); // Invoking an instance method may likely invalidate all the instance field analysis state, i.e. // reference type fields might be re-assigned to point to different objects in the called method. // An optimistic points to analysis assumes that the points to values of instance fields don't change on invoking an instance method. // A pessimistic points to analysis resets all the instance state and assumes the instance field might point to any object, hence has unknown state. // For dispose analysis, we want to perform an optimistic points to analysis as we assume a disposable field is not likely to be re-assigned to a separate object in helper method invocations in Dispose. pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, _wellKnownTypeProvider, pessimisticAnalysis: false); disposeAnalysisResult = DisposeAnalysis.GetOrComputeResult(cfg, containingMethod, _wellKnownTypeProvider, _disposeOwnershipTransferLikelyTypes, pointsToAnalysisResult, trackInstanceFields, out trackedInstanceFieldPointsToMap); return(true); } } disposeAnalysisResult = null; pointsToAnalysisResult = null; trackedInstanceFieldPointsToMap = null; return(false); }
private static bool ReportDiagnosticIfNecessary(OperationAnalysisContext operationContext, IOperation argumentValue, SyntaxNode syntax, ISymbol invokedSymbol, ISymbol containingMethod) { if (argumentValue.Type.SpecialType != SpecialType.System_String || !argumentValue.ConstantValue.HasValue) { // We have a candidate for diagnostic. perform more precise dataflow analysis. var topmostBlock = argumentValue.GetTopmostParentBlock(); if (topmostBlock != null) { var cfg = ControlFlowGraph.Create(topmostBlock); var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(operationContext.Compilation); var copyAnalysisResult = CopyAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider); var nullAnalysisResult = NullAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider); var pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, nullAnalysisResult); var stringContentResult = StringContentAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, copyAnalysisResult, nullAnalysisResult, pointsToAnalysisResult); StringContentAbstractValue value = stringContentResult[argumentValue]; if (value.NonLiteralState == StringContainsNonLiteralState.No) { // The value is a constant literal or default/unitialized, so avoid flagging this usage. return(false); } } // Review if the symbol passed to {invocation} in {method/field/constructor/etc} has user input. operationContext.ReportDiagnostic(syntax.CreateDiagnostic(Rule, invokedSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), containingMethod.Name)); return(true); } return(false); }
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_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); }
/// <summary> /// Evaluates the current compilation provided a symbol table with actual values. /// </summary> /// <param name="variables">The symbol table with actual values.</param> /// <returns>An evaluation result.</returns> public EvaluationResult Evaluate(Dictionary <VariableSymbol, object> variables) { var diagnostics = SyntaxTree.Diagnostics.Concat(GlobalScope.Diagnostics).ToImmutableArray(); if (diagnostics.Any()) { return(new EvaluationResult(diagnostics, null)); } var program = Binder.BindProgram(GlobalScope); var appPath = Environment.GetCommandLineArgs()[0]; var appDirectory = Path.GetDirectoryName(appPath); var cfgPath = Path.Combine(appDirectory, "cfg.dot"); var cfgStatement = !program.Statement.Statements.Any() && program.Functions.Any() ? program.Functions.Last().Value : program.Statement; var cfg = ControlFlowGraph.Create(cfgStatement); using (var streamWriter = new StreamWriter(cfgPath)) { cfg.WriteTo(streamWriter); } if (program.Diagnostics.Any()) { return(new EvaluationResult(program.Diagnostics.ToImmutableArray(), null)); } var evaluator = new Evaluator(program, variables); var value = evaluator.Evaluate(); return(new EvaluationResult(ImmutableArray <Diagnostic> .Empty, value)); }
internal static IEnumerable <object> TryAnalyze( SyntaxNode methodNode, SemanticModel semanticModel, CSharpCompilation compilation) { var cfg = ControlFlowGraph.Create(methodNode, semanticModel); var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); var owningSymbol = semanticModel.GetDeclaredSymbol(methodNode); var valueContentAnalysis = ValueContentAnalysis.TryGetOrComputeResult(cfg, owningSymbol, wellKnownTypeProvider, new AnalyzerOptions(ImmutableArray <AdditionalText> .Empty), null, CancellationToken.None ); if (HasLiteralStateLoss(valueContentAnalysis)) { return(null); } var returnValues = valueContentAnalysis.ReturnValueAndPredicateKindOpt?.Value.LiteralValues; return(returnValues); }
public void Analyze(ClassDeclarationSyntax classDeclarationSyntax, ClassModel classModel) { List <MethodDeclarationSyntax> methodDeclarationSyntaxes = classDeclarationSyntax .DescendantNodes() .OfType <MethodDeclarationSyntax>() .ToList(); foreach (MethodDeclarationSyntax methodDeclarationSyntax in methodDeclarationSyntaxes) { MethodModel methodModel = new MethodModel(); methodModel.Name = methodDeclarationSyntax.Identifier.Text; IMethodSymbol methodSymbol = SemanticModel.GetDeclaredSymbol(methodDeclarationSyntax) as IMethodSymbol; if (methodSymbol != null && !methodSymbol.IsAbstract) { ControlFlowGraph controlFlowGraph = ControlFlowGraph .Create(methodDeclarationSyntax, SemanticModel, CancellationToken.None); int numberOfBlocks = controlFlowGraph.Blocks.Length; int numberOfEdges = 0; foreach (BasicBlock basicBlock in controlFlowGraph.Blocks) { if (basicBlock.ConditionalSuccessor != null) { numberOfEdges++; } if (basicBlock.FallThroughSuccessor != null) { numberOfEdges++; } } methodModel.CyclomaticComplexity = numberOfEdges - numberOfBlocks + 2; } methodModel.Fqn = methodSymbol.ToString(); methodModel.Static = methodSymbol.IsStatic; methodModel.Abstract = methodSymbol.IsAbstract; methodModel.Sealed = methodSymbol.IsSealed; methodModel.Async = methodSymbol.IsAsync; methodModel.Override = methodSymbol.IsOverride; methodModel.Virtual = methodSymbol.IsVirtual; methodModel.Extern = methodSymbol.IsExtern; methodModel.Accessibility = methodSymbol.DeclaredAccessibility.ToString(); methodModel.ReturnType = methodSymbol.ReturnType.ToString(); methodModel.FirstLineNumber = methodDeclarationSyntax.GetLocation().GetLineSpan().StartLinePosition.Line + 1; methodModel.LastLineNumber = methodDeclarationSyntax.GetLocation().GetLineSpan().EndLinePosition.Line + 1; _invocationAnalyzer.Analyze(methodDeclarationSyntax, methodModel); _parameterAnalyzer.Analyze(methodDeclarationSyntax, methodModel); classModel.Methods.Add(methodModel); } }
private IEnumerable <Output> MakeSuspendable(MethodDeclarationSyntax method, SemanticModel semantic) { var symbol = semantic.GetDeclaredSymbol(method) ?? throw new Exception("GetDeclaredSymbol failed"); var graph = ControlFlowGraph.Create(method, semantic); var entry = graph.Entry(); var graph3 = new Graph3(graph); var references = graph3.ToDictionary(pair => pair.Suspension, pair => pair.References); Output Dumb(string name, FlowPoint point) { return(new Dumb(name, symbol, point, references[name], graph3)); } yield return(new Base(symbol, graph3)); yield return(Dumb("Entry", new FlowPoint(entry))); // todo put this code into bfs class var visited = new HashSet <BasicBlock>(); var queue = new Queue <BasicBlock>(); queue.Enqueue(entry); while (queue.Count > 0) { var block = queue.Dequeue(); if (visited.Contains(block)) { continue; } for (var i = 0; i < block.Operations.Length; i++) { var operation = block.Operations[i]; if (operation.Accept(new SuspensionPoint.Is())) { var name = operation.Accept(new SuspensionPoint.Name()); yield return(Dumb(name, new FlowPoint(block, i + 1))); } } visited.Add(block); if (block.ConditionalSuccessor is { } conditional) { queue.Enqueue(conditional.Destination); } if (block.FallThroughSuccessor?.Destination is { } destination) { queue.Enqueue(destination); } } if (references.ContainsKey("Exit")) { yield return(new Exit(symbol)); } }
public void ControlFlow() { var graph = ControlFlowGraph.Create( new ControlFlowNode(Instructions) ); InstructionTester.RunControlFlowTest(Instructions, graph); }
public void NotEqualsExpression() { SyntaxNode node = ParseStatement("{ if (a != 0); }"); ControlFlowGraph cfg = ControlFlowGraph.Create(node); Assert.AreEqual(SyntaxKind.NotEqualsExpression, cfg.BasicBlocks[0].Statements[0].CSharpKind()); }
public void ReturnStatement() { SyntaxNode node = ParseStatement("return foo;"); ControlFlowGraph cfg = ControlFlowGraph.Create(node); Assert.AreEqual(1, cfg.BasicBlocks.Count); Assert.AreEqual(1, cfg.BasicBlocks[0].Statements.Count); }
public void Block() { SyntaxNode node = ParseStatement("{ a = 0; a = 0; }"); ControlFlowGraph cfg = ControlFlowGraph.Create(node); Assert.AreEqual(1, cfg.BasicBlocks.Count); Assert.AreEqual(2, cfg.BasicBlocks[0].Statements.Count); }
public void TestGetFlowGraphNullArgument() { Assert.Throws <ArgumentNullException>(() => ControlFlowGraph.Create((IBlockOperation)null)); Assert.Throws <ArgumentNullException>(() => ControlFlowGraph.Create((IFieldInitializerOperation)null)); Assert.Throws <ArgumentNullException>(() => ControlFlowGraph.Create((IPropertyInitializerOperation)null)); Assert.Throws <ArgumentNullException>(() => ControlFlowGraph.Create((IParameterInitializerOperation)null)); Assert.Throws <ArgumentNullException>(() => ControlFlowGraph.Create((IConstructorBodyOperation)null)); Assert.Throws <ArgumentNullException>(() => ControlFlowGraph.Create((IMethodBodyOperation)null)); }
public void PrintGraph() { SyntaxNode node = ParseStatement("{ if (a == null) { return a; } return \"\"; }"); ControlFlowGraph cfg = ControlFlowGraph.Create(node); // FIXME Hardcoded path File.WriteAllText(@"C:\Users\vagrant\Desktop\cfg.dot", cfg.ToGraph()); }
public void SimpleAssignmentExpression() { SyntaxNode node = ParseStatement("a = 0;"); ControlFlowGraph cfg = ControlFlowGraph.Create(node); Assert.AreEqual(1, cfg.BasicBlocks.Count); Assert.AreEqual(1, cfg.BasicBlocks[0].Statements.Count); }
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 Test_02_ControlFlowGraph() { var compilation = CodeAnalysisTestingUtils.CreateFakeCompilation().LoadDocuments("TestData_ControlFlowGraph.cs"); var(method, model) = compilation.FindDocument().FindMethod("ControlFlowGraphExample"); var graph = ControlFlowGraph.Create(method, model) ?? throw new Exception("Control flow graph is null"); var message = RoslynDisplayUtils.GetDisplayString(graph); TestContext.WriteLine(message); }
public void Run(MethodBody body) { this.context = new DecompilationContext(body, ControlFlowGraph.Create(body.Method)); var block = new BlockStatement(); foreach (var step in steps) { block = step.Process(context, block); } body_block = block; }
static ControlFlowGraph GetTreeCFG(Compilation compilation) { var tree = compilation.SyntaxTrees.Single(); var root = tree.GetRoot(); var semanticModel = compilation.GetSemanticModel(tree); var firstMethod = root.DescendantNodes().OfType <BaseMethodDeclarationSyntax>().First(); var firstMethodOper = semanticModel.GetOperation(firstMethod) as IMethodBodyOperation; return(ControlFlowGraph.Create(firstMethodOper)); }
public string getIL_usingControlFLowGraph(MethodDefinition method) { try { ControlFlowGraph cfg = ControlFlowGraph.Create(method); return(this.FormatControlFlowGraph(cfg)); } catch (Exception exception) { DI.log.error("in CecilDecompiler.getIL :{0} \n\n{1}\n\n", new object[] { exception.Message, exception.StackTrace }); } return(""); }
public static ControlFlowGraph GetControlFlowGraph(SyntaxNode syntaxNode, SemanticModel model) { IOperation operationRoot = model.GetOperation(syntaxNode); // Workaround for unit tests designed to work on IBlockOperation with ConstructorBodyOperation/MethodBodyOperation parent. operationRoot = operationRoot.Kind == OperationKind.Block && (operationRoot.Parent?.Kind == OperationKind.ConstructorBodyOperation || operationRoot.Parent?.Kind == OperationKind.MethodBodyOperation) ? operationRoot.Parent : operationRoot; TestOperationVisitor.VerifySubTree(operationRoot); ControlFlowGraph graph; switch (operationRoot) { case IBlockOperation blockOperation: graph = ControlFlowGraph.Create(blockOperation); break; case IMethodBodyOperation methodBodyOperation: graph = ControlFlowGraph.Create(methodBodyOperation); break; case IConstructorBodyOperation constructorBodyOperation: graph = ControlFlowGraph.Create(constructorBodyOperation); break; case IFieldInitializerOperation fieldInitializerOperation: graph = ControlFlowGraph.Create(fieldInitializerOperation); break; case IPropertyInitializerOperation propertyInitializerOperation: graph = ControlFlowGraph.Create(propertyInitializerOperation); break; case IParameterInitializerOperation parameterInitializerOperation: graph = ControlFlowGraph.Create(parameterInitializerOperation); break; default: return(null); } Assert.NotNull(graph); Assert.Same(operationRoot, graph.OriginalOperation); return(graph); }
public void EmitControlFlowGraph(FunctionSymbol function) { var cfgStatement = program.Functions.SingleOrDefault(kvp => kvp.Key.Name == function.Name).Value; var cfg = ControlFlowGraph.Create(cfgStatement); var appPath = Environment.GetCommandLineArgs()[0]; var appDirectory = Path.GetDirectoryName(appPath); var cfgPath = Path.Combine(appDirectory, "cfg.dot"); using var streamWriter = new StreamWriter(cfgPath); cfg.WriteTo(streamWriter); }
private static ParameterValidationResultWithHazardousUsages GetOrComputeResult( IOperation topmostBlock, ISymbol owningSymbol, WellKnownTypeProvider wellKnownTypeProvider, Func <IBlockOperation, IMethodSymbol, ParameterValidationResultWithHazardousUsages> getOrComputeLocationAnalysisResultOpt, bool pessimisticAnalysis) { var cfg = ControlFlowGraph.Create(topmostBlock); var pointsToAnalysisResult = PointsToAnalysis.PointsToAnalysis.GetOrComputeResult(cfg, owningSymbol, wellKnownTypeProvider); var copyAnalysisResult = CopyAnalysis.CopyAnalysis.GetOrComputeResult(cfg, owningSymbol, wellKnownTypeProvider, pointsToAnalysisResultOpt: pointsToAnalysisResult); // Do another analysis pass to improve the results from PointsTo and Copy analysis. pointsToAnalysisResult = PointsToAnalysis.PointsToAnalysis.GetOrComputeResult(cfg, owningSymbol, wellKnownTypeProvider, pointsToAnalysisResult, copyAnalysisResult); return(GetOrComputeResult(cfg, owningSymbol, wellKnownTypeProvider, pointsToAnalysisResult, getOrComputeLocationAnalysisResultOpt, pessimisticAnalysis)); }