Пример #1
0
    public void _EntryAndExitPoints()
    {
        var tree = CSharpSyntaxTree.ParseText(@"
        class C
        {
            void M(int x)
            {
                L1: ; // 1
                if (x == 0) goto L1;    //firstIf
                if (x == 1) goto L2;
                if (x == 3) goto L3;
                L3: ;                   //label3
                L2: ; // 2
                if(x == 4) goto L3;
            }
        }
        ");

        var Mscorlib    = PortableExecutableReference.CreateFromFile(typeof(object).Assembly.Location);
        var compilation = CSharpCompilation.Create("MyCompilation",
                                                   syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
        var model = compilation.GetSemanticModel(tree);

        //Choose first and last statements
        var firstIf = tree.GetRoot().DescendantNodes().OfType <IfStatementSyntax>().First();
        var label3  = tree.GetRoot().DescendantNodes().OfType <LabeledStatementSyntax>().Skip(1).Take(1).Single();

        ControlFlowAnalysis result = model.AnalyzeControlFlow(firstIf, label3);
        //DebugLogger.Instance.WriteLine(result.EntryPoints);      //1 - L3: ; //Label 3 is a candidate entry point within these statements
        //DebugLogger.Instance.WriteLine(result.ExitPoints);       //2 - goto L1;,goto L2; //goto L1 and goto L2 and candidate exit points
    }
Пример #2
0
    public void _UnreachableCode()
    {
        var tree = CSharpSyntaxTree.ParseText(@"
            class C
            {
                void M(int x)
                {
                    return;
                    if(x == 0)                                  //-+     Start is unreachable
                        System.//DebugLogger.Instance.WriteLine(""Hello"");    // |
                    L1:                                            //-+    End is unreachable
                }
            }
        ");

        var Mscorlib    = PortableExecutableReference.CreateFromFile(typeof(object).Assembly.Location);
        var compilation = CSharpCompilation.Create("MyCompilation",
                                                   syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
        var model = compilation.GetSemanticModel(tree);

        //Choose first and last statements
        var firstIf = tree.GetRoot().DescendantNodes().OfType <IfStatementSyntax>().Single();
        var label1  = tree.GetRoot().DescendantNodes().OfType <LabeledStatementSyntax>().Single();

        ControlFlowAnalysis result = model.AnalyzeControlFlow(firstIf, label1);
        //DebugLogger.Instance.WriteLine(result.StartPointIsReachable);    //False
        //DebugLogger.Instance.WriteLine(result.EndPointIsReachable);      //False
    }
Пример #3
0
        public MethodBody Execute()
        {
            MethodBody bytecodeBody = new MethodBody(MethodBodyKind.Bytecode);

            bytecodeBody.Parameters.AddRange(_tacBody.Parameters);
            bytecodeBody.LocalVariables.AddRange(_tacBody.LocalVariables);
            //bytecodeBody.ExceptionInformation.AddRange(_tacBody.ExceptionInformation);
            bytecodeBody.MaxStack = 0;

            if (_tacBody.Instructions.Count > 0)
            {
                InstructionConverter instructionConverter = new InstructionConverter();
                ControlFlowAnalysis  cfanalysis           = new ControlFlowAnalysis(_tacBody);
                // exceptions disabled for now
                ControlFlowGraph cfg = cfanalysis.GenerateNormalControlFlow();

                //FillExceptionHandlersStart();
                foreach (CFGNode node in cfg.ForwardOrder)
                {
                    ProcessBasicBlock(bytecodeBody, node, instructionConverter);
                }

                bytecodeBody.Instructions.AddRange(instructionConverter.Result);
            }

            return(bytecodeBody);
        }
        // this function applies analysis-net analyses on the method defined in our assembly (methodDefinition)
        // the result is a typed stackless three address code representation of the orignal method definition body
        // you can 'out' the control flow graph because it can be reused for another analysis
        public static MethodBody ThreeAddressCode(IMethodDefinition methodDefinition, MetadataReaderHost host, out ControlFlowGraph cfg)
        {
            if (methodDefinition.IsAbstract || methodDefinition.IsExternal)
            {
                cfg = null;
                return(null);
            }

            var disassembler = new Disassembler(host, methodDefinition, null);
            var methodBody   = disassembler.Execute();

            var cfAnalysis = new ControlFlowAnalysis(methodBody);

            //var cfg = cfAnalysis.GenerateNormalControlFlow();
            cfg = cfAnalysis.GenerateExceptionalControlFlow();

            var splitter = new WebAnalysis(cfg, methodDefinition);

            splitter.Analyze();
            splitter.Transform();

            methodBody.UpdateVariables();

            var typeAnalysis = new TypeInferenceAnalysis(cfg, methodDefinition.Type);

            typeAnalysis.Analyze();

            methodBody.UpdateVariables();

            return(methodBody);
        }
Пример #5
0
        public void AnalyzeRegionControlFlow()
        {
            TestCode        testCode = new TestCode(@"
class C {
    public void F()
    {
        goto L1; // 1
/*start*/
        L1: ;
        if (false) return;
/*end*/
        goto L1; // 2
    }
}");
            StatementSyntax firstStatement, lastStatement;

            testCode.GetStatementsBetweenMarkers(out firstStatement, out lastStatement);
            ControlFlowAnalysis regionControlFlowAnalysis =
                testCode.SemanticModel.AnalyzeControlFlow(firstStatement, lastStatement);

            Assert.AreEqual(1, regionControlFlowAnalysis.EntryPoints.Count());
            Assert.AreEqual(1, regionControlFlowAnalysis.ExitPoints.Count());
            Assert.IsTrue(regionControlFlowAnalysis.EndPointIsReachable);

            BlockSyntax methodBody = testCode.SyntaxTree
                                     .GetRoot()
                                     .DescendantNodes()
                                     .OfType <MethodDeclarationSyntax>()
                                     .First()
                                     .Body;

            regionControlFlowAnalysis = testCode.SemanticModel.AnalyzeControlFlow(methodBody, methodBody);

            Assert.IsFalse(regionControlFlowAnalysis.EndPointIsReachable);
        }
Пример #6
0
    public void _BasicControlFlow()
    {
        var tree = CSharpSyntaxTree.ParseText(@"
            class C
            {
                void M()
                {
        
                    for (int i = 0; i < 10; i++)
                    {
                        if (i == 3)
                            continue;
                        if (i == 8)
                            break;
                    }
                }
            }
        ");

        var Mscorlib    = PortableExecutableReference.CreateFromFile(typeof(object).Assembly.Location);
        var compilation = CSharpCompilation.Create("MyCompilation",
                                                   syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
        var model = compilation.GetSemanticModel(tree);

        var firstFor = tree.GetRoot().DescendantNodes().OfType <ForStatementSyntax>().Single();
        ControlFlowAnalysis result = model.AnalyzeControlFlow(firstFor.Statement);

        //DebugLogger.Instance.WriteLine(result.Succeeded);            //True
        //DebugLogger.Instance.WriteLine(result.ExitPoints.Count());    //2 - continue, and break
    }
        public static async Task ComputeRefactoringAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration)
        {
            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMethodReturnTypeToVoid) &&
                methodDeclaration.ReturnType?.IsVoid() == false &&
                methodDeclaration.Body?.Statements.Count > 0 &&
                !methodDeclaration.IsIterator() &&
                context.SupportsSemanticModel)
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                if (!IsAsyncMethodThatReturnsTask(methodDeclaration, semanticModel, context.CancellationToken))
                {
                    ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(methodDeclaration.Body);

                    if (analysis.Succeeded &&
                        analysis.ReturnStatements.All(node => IsReturnStatementWithoutExpression(node)))
                    {
                        context.RegisterRefactoring(
                            "Change return type to 'void'",
                            cancellationToken =>
                        {
                            return(ChangeTypeRefactoring.ChangeTypeAsync(
                                       context.Document,
                                       methodDeclaration.ReturnType,
                                       CSharpFactory.VoidType(),
                                       cancellationToken));
                        });
                    }
                }
            }
        }
Пример #8
0
 MethodBlockAnalysis(MethodDeclarationSyntax methodDeclarationSyntax, BlockSyntax methodBodySyntax, SemanticModel semanticModel, ControlFlowAnalysis controlFlow, DataFlowAnalysis dataFlow)
 {
     MethodDeclarationSyntax = methodDeclarationSyntax;
     SemanticModel           = semanticModel;
     ControlFlowAnalysis     = controlFlow;
     DataFlowAnalysis        = dataFlow;
     BodyBlock = methodBodySyntax;
 }
Пример #9
0
        public static TypeSyntax GetReturnType(BlockSyntax code, SemanticModel model)
        {
            if (code == null)
            {
                return(@void);
            }

            ControlFlowAnalysis cfa = model.AnalyzeControlFlow(code);

            if (!cfa.ReturnStatements.Any())
            {
                return(@void);
            }

            ITypeSymbol rt = null;

            foreach (var rs in cfa.ReturnStatements)
            {
                ReturnStatementSyntax rss  = (ReturnStatementSyntax)rs;
                ITypeSymbol           type = model.GetSpeculativeTypeInfo(rss.Expression.SpanStart, rss.Expression, SpeculativeBindingOption.BindAsExpression).Type;

                if (type == null)
                {
                    continue;
                }

                if (type.TypeKind == TypeKind.Error)
                {
                    rt = null;
                    break;
                }

                if (rt == null)
                {
                    rt = type;
                }
                else if (rt != type)
                {
                    rt = null;
                    break;
                }
            }

            if (rt == null)
            {
                return(@object);
            }

            var syntaxReference = rt.DeclaringSyntaxReferences.SingleOrDefault();

            return(CSharp.ParseTypeName(rt.ToString()));
        }
Пример #10
0
        public void GenerateCFG(MethodDefinition method)
        {
            var methodInfo = programInfo.GetOrAdd(method);

            //GenerateIL(method);
            GenerateTAC(method);

            if (!methodInfo.Contains("CFG"))
            {
                // Control-flow
                var cfAnalysis = new ControlFlowAnalysis(method.Body);
                var cfg        = cfAnalysis.GenerateNormalControlFlow();
                //var cfg = cfAnalysis.GenerateExceptionalControlFlow();

                var domAnalysis = new DominanceAnalysis(cfg);
                domAnalysis.Analyze();
                domAnalysis.GenerateDominanceTree();

                //// Optional
                //var loopAnalysis = new NaturalLoopAnalysis(cfg);
                //loopAnalysis.Analyze();

                var domFrontierAnalysis = new DominanceFrontierAnalysis(cfg);
                domFrontierAnalysis.Analyze();

                var pdomAnalysis = new PostDominanceAnalysis(cfg);
                pdomAnalysis.Analyze();
                pdomAnalysis.GeneratePostDominanceTree();

                var pdomFrontierAnalysis = new PostDominanceFrontierAnalysis(cfg);
                pdomFrontierAnalysis.Analyze();

                var controlDependenceAnalysis = new ControlDependenceAnalysis(cfg);
                controlDependenceAnalysis.Analyze();

                var text = DGMLSerializer.Serialize(cfg);

                methodInfo.Add("CFG", cfg);
                methodInfo.Add("CFG_TEXT", text);

                text = DGMLSerializer.SerializeDominanceTree(cfg);
                methodInfo.Add("DT_TEXT", text);

                text = DGMLSerializer.SerializePostDominanceTree(cfg);
                methodInfo.Add("PDT_TEXT", text);

                text = DGMLSerializer.SerializeControlDependenceGraph(cfg);
                methodInfo.Add("CDG_TEXT", text);
            }
        }
Пример #11
0
        public void Execute()
        {
            var disassembler = new Backend.Transformations.Disassembler(host, methodDefinition, sourceLocationProvider);
            var methodBody   = disassembler.Execute();

            MethodBody = methodBody;

            var cfAnalysis = new ControlFlowAnalysis(methodBody);

            ControlFlowGraph = cfAnalysis.GenerateExceptionalControlFlow();

            var splitter = new WebAnalysis(ControlFlowGraph, methodBody.MethodDefinition);

            splitter.Analyze();
            splitter.Transform();

            methodBody.UpdateVariables();

            var typeAnalysis = new TypeInferenceAnalysis(ControlFlowGraph, methodBody.MethodDefinition.Type);

            typeAnalysis.Analyze();

            //var forwardCopyAnalysis = new ForwardCopyPropagationAnalysis(Traverser.CFG);
            //forwardCopyAnalysis.Analyze();
            //forwardCopyAnalysis.Transform(methodBody);

            //var backwardCopyAnalysis = new BackwardCopyPropagationAnalysis(Traverser.CFG);
            //backwardCopyAnalysis.Analyze();
            //backwardCopyAnalysis.Transform(methodBody);

            // TinyBCT transformations

            var fieldInitialization = new FieldInitialization(methodBody);

            fieldInitialization.Transform();

            if (!Settings.AddressesEnabled())
            {
                var refAlias = new RefAlias(methodBody);
                refAlias.Transform();
            }

            // execute this after RefAlias!
            var immutableArguments = new ImmutableArguments(methodBody);

            immutableArguments.Transform();

            methodBody.RemoveUnusedLabels();
        }
            protected override async Task <Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
            {
                var semanticModel = await _document.GetSemanticModelAsync(cancellationToken)
                                    .ConfigureAwait(false);

                if (semanticModel == null || cancellationToken.IsCancellationRequested)
                {
                    return(_document);
                }

                var pxContext = new PXContext(semanticModel.Compilation);
                var oldRoot   = await _document.GetSyntaxRootAsync(cancellationToken)
                                .ConfigureAwait(false);

                if (oldRoot == null || cancellationToken.IsCancellationRequested)
                {
                    return(_document);
                }

                var newRoot           = oldRoot;
                var generator         = SyntaxGenerator.GetGenerator(_document);
                var newReturnType     = GetNewReturnType(generator, semanticModel, cancellationToken);
                var newParametersList = GetNewParametersList(generator, pxContext, cancellationToken);

                if (newReturnType == null || newParametersList == null || cancellationToken.IsCancellationRequested)
                {
                    return(_document);
                }

                var newMethod = _method.WithReturnType(newReturnType)
                                .WithParameterList(newParametersList);

                ControlFlowAnalysis controlFlow = semanticModel.AnalyzeControlFlow(_method.Body);

                if (controlFlow != null && controlFlow.Succeeded && controlFlow.ReturnStatements.IsEmpty)
                {
                    newMethod = AddReturnStatement(newMethod, generator);
                }

                newRoot = newRoot.ReplaceNode(_method, newMethod);
                newRoot = AddCollectionsUsing(newRoot, generator, cancellationToken);

                if (cancellationToken.IsCancellationRequested)
                {
                    return(_document);
                }

                return(_document.WithSyntaxRoot(newRoot));
            }
Пример #13
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, MethodDeclarationSyntax methodDeclaration)
        {
            if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeMethodReturnTypeToVoid))
            {
                TypeSyntax returnType = methodDeclaration.ReturnType;

                if (returnType?.IsVoid() == false)
                {
                    BlockSyntax body = methodDeclaration.Body;

                    if (body != null)
                    {
                        SyntaxList <StatementSyntax> statements = body.Statements;

                        if (statements.Any() &&
                            !ContainsOnlyThrowStatement(statements) &&
                            !methodDeclaration.ContainsYield())
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, context.CancellationToken);

                            if (methodSymbol?.IsOverride == false &&
                                !methodSymbol.ImplementsInterfaceMember() &&
                                !IsAsyncMethodThatReturnsTask(methodSymbol, semanticModel))
                            {
                                ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(body);

                                if (analysis.Succeeded &&
                                    analysis.ReturnStatements.All(IsReturnStatementWithoutExpression))
                                {
                                    context.RegisterRefactoring(
                                        "Change return type to 'void'",
                                        cancellationToken =>
                                    {
                                        return(ChangeTypeRefactoring.ChangeTypeAsync(
                                                   context.Document,
                                                   returnType,
                                                   CSharpFactory.VoidType(),
                                                   cancellationToken));
                                    });
                                }
                            }
                        }
                    }
                }
            }
        }
            protected bool IsReacheableByControlFlow(StatementSyntax statement)
            {
                ControlFlowAnalysis controlFlow = null;

                try
                {
                    controlFlow = SemanticModel.AnalyzeControlFlow(statement);
                }
                catch
                {
                    //If there was some kind of error during analysis we should assume the worst case - that assignment is reacheable
                    return(true);
                }

                return(controlFlow?.Succeeded != true || controlFlow.EndPointIsReachable);
            }
Пример #15
0
        static void Main(string[] args)
        {
            string parseText = @"
    class MyClass
    {
        void MyMethod()
        {

            for (int i = 0; i < 10; i++)
            {
                if (i == 3)
                    continue;
                if (i == 8)
                    break;
            }
        }
    }
";

            if (args.Any())
            {
                var path = args[0];
                if (File.Exists(path))
                {
                    parseText = File.ReadAllText(path);
                }
            }

            var tree = CSharpSyntaxTree.ParseText(parseText);

            var Mscorlib    = MetadataReference.CreateFromFile(Assembly.GetExecutingAssembly().Location);
            var compilation = CSharpCompilation.Create("MyCompilation",
                                                       syntaxTrees: new[] { tree }, references: new[] { Mscorlib });
            var model = compilation.GetSemanticModel(tree);

            // control flow analysis of for statement
            var firstFor = tree.GetRoot().DescendantNodes().OfType <ForStatementSyntax>().Single();
            ControlFlowAnalysis result = model.AnalyzeControlFlow(firstFor.Statement);

            Console.WriteLine("Succeeded: " + result.Succeeded);
            Console.WriteLine("Exit Points:");
            foreach (var exitPoint in result.ExitPoints)
            {
                Console.WriteLine("\t" + exitPoint.Kind().ToString());
            }
            Console.ReadKey();
        }
Пример #16
0
        public static TypeSyntax GetReturnType(BlockSyntax code, SemanticModel model)
        {
            ControlFlowAnalysis cfa = model.AnalyzeControlFlow(code);

            if (!cfa.ReturnStatements.Any())
            {
                return(@void);
            }

            ITypeSymbol rt = null;

            foreach (var rs in cfa.ReturnStatements)
            {
                ReturnStatementSyntax rss  = (ReturnStatementSyntax)rs;
                ITypeSymbol           type = model.GetSpeculativeTypeInfo(rss.Expression.SpanStart, rss.Expression, SpeculativeBindingOption.BindAsExpression).Type;

                if (type == null)
                {
                    continue;
                }

                if (type.TypeKind == TypeKind.Error)
                {
                    rt = null;
                    break;
                }

                if (rt == null)
                {
                    rt = type;
                }
                else if (rt != type)
                {
                    rt = null;
                    break;
                }
            }

            if (rt == null)
            {
                return(@dynamic);
            }

            return(CSharp.ParseTypeName(rt.Name));
        }
Пример #17
0
        internal string CalcTryUsingFuncInfo(DataFlowAnalysis dataFlow, ControlFlowAnalysis ctrlFlow, out List <string> inputs, out List <string> outputs, out string paramsStr)
        {
            var sbIn  = new StringBuilder();
            var sbOut = new StringBuilder();

            inputs  = new List <string>();
            outputs = new List <string>();
            string prestrIn  = string.Empty;
            string prestrOut = string.Empty;

            if (ctrlFlow.ReturnStatements.Length > 0 && !string.IsNullOrEmpty(ReturnVarName))
            {
                sbIn.Append(ReturnVarName);
                prestrIn = ", ";
                sbOut.Append(ReturnVarName);
                prestrOut = ", ";
            }
            foreach (var v in dataFlow.DataFlowsIn)
            {
                if (v.Name == "this")
                {
                    continue;
                }
                inputs.Add(v.Name);
                sbIn.Append(prestrIn);
                sbIn.Append(v.Name);
                prestrIn = ", ";
            }
            foreach (var v in dataFlow.DataFlowsOut)
            {
                outputs.Add(v.Name);
                if (!inputs.Contains(v.Name))
                {
                    sbIn.Append(prestrIn);
                    sbIn.Append(v.Name);
                    prestrIn = ", ";
                }
                sbOut.Append(prestrOut);
                sbOut.Append(v.Name);
                prestrOut = ", ";
            }
            paramsStr = sbIn.ToString();
            return(sbOut.ToString());
        }
        private static void ComputeRefactoring(
            RefactoringContext context,
            IMethodSymbol methodSymbol,
            SemanticModel semanticModel,
            BlockSyntax body,
            TypeSyntax returnType)
        {
            if (methodSymbol?.IsOverride != false)
            {
                return;
            }

            if (methodSymbol.ImplementsInterfaceMember())
            {
                return;
            }

            if (methodSymbol.IsAsync &&
                methodSymbol.ReturnType.HasMetadataName(MetadataNames.System_Threading_Tasks_Task))
            {
                return;
            }

            ControlFlowAnalysis analysis = semanticModel.AnalyzeControlFlow(body);

            if (!analysis.Succeeded)
            {
                return;
            }

            if (!analysis.ReturnStatements.All(f => (f as ReturnStatementSyntax)?.Expression == null))
            {
                return;
            }

            Document document = context.Document;

            context.RegisterRefactoring(
                "Change return type to 'void'",
                ct => document.ReplaceNodeAsync(returnType, CSharpFactory.VoidType().WithTriviaFrom(returnType), ct),
                RefactoringDescriptors.ChangeMethodReturnTypeToVoid);
        }
            public bool CatchClauseCatchesCoroutineStopped(CatchClauseSyntax catchClause,
                                                           SemanticModel model, out bool rethrows)
            {
                rethrows = false;
                if (catchClause.Declaration != null)
                {
                    INamedTypeSymbol exceptionSymbol =
                        model.GetSymbolInfo(catchClause.Declaration.Type).Symbol as
                        INamedTypeSymbol;

                    if (exceptionSymbol == null)
                    {
                        return(false);
                    }

                    if (exceptionSymbol != ExceptionType &&
                        exceptionSymbol != CoroutineStoppedExceptionType)
                    {
                        return(false);
                    }

                    if (RethrowsCoroutineStoppedException(catchClause, model))
                    {
                        rethrows = true;
                        return(true);
                    }
                }

                ControlFlowAnalysis controlFlowResult =
                    model.AnalyzeControlFlow(catchClause.Block);

                // Check if this catch always rethrows
                if (controlFlowResult.Succeeded &&
                    !controlFlowResult.EndPointIsReachable &&
                    controlFlowResult.ExitPoints.Length == 0 &&
                    controlFlowResult.ReturnStatements.Length == 0)
                {
                    rethrows = true;
                }

                return(true);
            }
Пример #20
0
        private void AnalyzeCatchBlock(SyntaxNodeAnalysisContext context)
        {
            // As always skip generated code.
            if (context.IsGeneratedOrNonUserCode())
            {
                return;
            }

            CatchClauseSyntax theCatch = (CatchClauseSyntax)context.Node;

            // I want to be smart about how I look at the catch blocks as the control flow could
            // be slow on very large blocks. Consequently, I only want to look at those blocks
            // that don't have any diagnostics (errors) in them.
            TextSpan span           = theCatch.GetLocation().SourceSpan;
            var      allDiagnostics = context.SemanticModel.Compilation.GetDiagnostics();

            for (Int32 i = 0; i < allDiagnostics.Length; i++)
            {
                if (allDiagnostics[i].Location.SourceSpan.IntersectsWith(span))
                {
                    return;
                }
            }

            // Take a look at the control flow.
            ControlFlowAnalysis flowAnalysis = context.SemanticModel.AnalyzeControlFlow(theCatch.Block);

            if (flowAnalysis.Succeeded)
            {
                if ((flowAnalysis.ReturnStatements.Length == 0) &&
                    (flowAnalysis.EndPointIsReachable == false) &&
                    (flowAnalysis.EntryPoints.Length == 0))
                {
                    return;
                }

                // Now we know this catch block either eats the exception or has a return.
                var diagnostic = Diagnostic.Create(Rule, theCatch.GetLocation());
                context.ReportDiagnostic(diagnostic);
            }
        }
Пример #21
0
        public static void transformBody(MethodBody methodBody)
        {
            var cfAnalysis = new ControlFlowAnalysis(methodBody);

            //var cfg = cfAnalysis.GenerateNormalControlFlow();
            Traverser.CFG = cfAnalysis.GenerateExceptionalControlFlow();

            var splitter = new WebAnalysis(Traverser.CFG, methodBody.MethodDefinition);

            splitter.Analyze();
            splitter.Transform();

            methodBody.UpdateVariables();

            var typeAnalysis = new TypeInferenceAnalysis(Traverser.CFG, methodBody.MethodDefinition.Type);

            typeAnalysis.Analyze();

            //var forwardCopyAnalysis = new ForwardCopyPropagationAnalysis(Traverser.CFG);
            //forwardCopyAnalysis.Analyze();
            //forwardCopyAnalysis.Transform(methodBody);

            //var backwardCopyAnalysis = new BackwardCopyPropagationAnalysis(Traverser.CFG);
            //backwardCopyAnalysis.Analyze();
            //backwardCopyAnalysis.Transform(methodBody);

            // TinyBCT transformations

            if (!Settings.NewAddrModelling)
            {
                var refAlias = new RefAlias(methodBody);
                refAlias.Transform();

                var immutableArguments = new ImmutableArguments(methodBody);
                immutableArguments.Transform();

                var fieldInitialization = new FieldInitialization(methodBody);
                fieldInitialization.Transform();
            }
            methodBody.RemoveUnusedLabels();
        }
Пример #22
0
        private IEnumerable <MutantInfo> DeleteStatement(SyntaxNode node)
        {
            var _semanticModel = _compiler.GetSemanticModel(node.SyntaxTree);
            // Note: Roslyn does not seem to like empty block statements.
            StatementSyntax     nop         = SyntaxFactory.ParseStatement(";");
            DataFlowAnalysis    dataFlow    = _semanticModel.AnalyzeDataFlow(node);
            ControlFlowAnalysis controlFlow = _semanticModel.AnalyzeControlFlow(node);

            // statements with only side effects and no returns or exceptions trivially can be erased
            if (!controlFlow.ExitPoints.Any() && controlFlow.EndPointIsReachable)
            {
                if (!dataFlow.VariablesDeclared.Any() || node is BlockSyntax) // || !dataFlow.ReadOutside.Any())
                {
                    yield return(new MutantInfo(lineID, node, nop, "Deleted statement executed by test"));
                }
            }

            if (node is ForStatementSyntax && controlFlow.EndPointIsReachable)
            {
                yield return(new MutantInfo(lineID, node, nop, "Deleted entire for loop"));
            }
        }
        public override SyntaxNode VisitBlock(BlockSyntax node)
        {
            SyntaxList <StatementSyntax> statements = node.Statements;

            // eliminate unreachable statements (cosmetic)
            List <int> remove = new List <int>();

            for (int i = 0; i < statements.Count; i++)
            {
                try
                {
                    ControlFlowAnalysis cfa = semanticModel.AnalyzeControlFlow(statements[i]);
                    if (!cfa.StartPointIsReachable)
                    {
                        remove.Add(i);
                    }
                }
                catch (ArgumentException)
                {
                    // probably node not in tree (because we rewrote it)
                    // do nothing and come back next time
                    Debug.Assert(Changed);
                    break;
                }
            }
            if (remove.Count != 0)
            {
                Changed = true;
                for (int i = remove.Count - 1; i >= 0; i--)
                {
                    statements = statements.RemoveAt(remove[i]);
                }
                node = node.WithStatements(statements);
            }

            return(base.VisitBlock(node));
        }
Пример #24
0
        public void AnalysisOnForCycle()
        {
            var source = @"
    class C
    {
        void M()
        {
            for (int i = 0; i < 10; i++)
            {
                if (i == 3)
                    continue;
                return;
                if (i == 8)
                    break;
            }
        }
    }
";
            var tree   = CSharpSyntaxTree.ParseText(source);
            var model  = GetSemanticModel(tree);

            var firstFor = tree.GetRoot().DescendantNodes().OfType <ForStatementSyntax>().Single();
            ControlFlowAnalysis result = model.AnalyzeControlFlow(firstFor.Statement);

            Trace.WriteLine(source);
            Trace.WriteLine("");
            Trace.WriteLine($"Is start point reachable: {result.StartPointIsReachable}");
            Trace.WriteLine($"Is end point reachable: {result.EndPointIsReachable}");
            foreach (var exitPoint in result.ExitPoints)
            {
                Trace.WriteLine($"Exit points: {exitPoint}");
            }
            foreach (var returnStatements in result.ReturnStatements)
            {
                Trace.WriteLine($"Resturnt statements: {returnStatements}");
            }
        }
Пример #25
0
        public static void TransformToTac(MethodDefinition method)
        {
            Disassembler disassembler = new Disassembler(method);
            MethodBody   methodBody   = disassembler.Execute();

            method.Body = methodBody;

            ControlFlowAnalysis cfAnalysis = new ControlFlowAnalysis(method.Body);

            //var cfg = cfAnalysis.GenerateNormalControlFlow();
            Backend.Model.ControlFlowGraph cfg = cfAnalysis.GenerateExceptionalControlFlow();

            WebAnalysis splitter = new WebAnalysis(cfg);

            splitter.Analyze();
            splitter.Transform();

            methodBody.UpdateVariables();

            TypeInferenceAnalysis typeAnalysis = new TypeInferenceAnalysis(cfg, method.ReturnType);

            typeAnalysis.Analyze();

            // Copy Propagation
            ForwardCopyPropagationAnalysis forwardCopyAnalysis = new ForwardCopyPropagationAnalysis(cfg);

            forwardCopyAnalysis.Analyze();
            forwardCopyAnalysis.Transform(methodBody);

            BackwardCopyPropagationAnalysis backwardCopyAnalysis = new BackwardCopyPropagationAnalysis(cfg);

            backwardCopyAnalysis.Analyze();
            backwardCopyAnalysis.Transform(methodBody);

            methodBody.UpdateVariables();
        }
Пример #26
0
        public MethodCfgAndTac AnalyzeIntraProcedural(IMethodDefinition methodDefinition)
        {
            // System.Console.WriteLine("Traversing: {0}", methodDefinition.GetName());
            if (Stubber.SuppressM(methodDefinition))
            {
                return(null);
            }
            if (methodDefinition.IsExternal)
            {
                return(null);
            }
            if (methodDefinition.IsAbstract)
            {
                return(null);
            }

            ITypeDefinition         containingDefn         = methodDefinition.ContainingTypeDefinition;
            ISourceLocationProvider sourceLocationProvider = null;

            if (containingDefn != null)
            {
                IModule mod = TypeHelper.GetDefiningUnit(containingDefn) as IModule;
                if (moduleToPdbMap.ContainsKey(mod))
                {
                    sourceLocationProvider = moduleToPdbMap[mod];
                }
                else
                {
                    if (!(mod == null || mod == Dummy.Module || mod == Dummy.Assembly))
                    {
                        sourceLocationProvider = GetPdbReader(mod.Location);
                        moduleToPdbMap[mod]    = sourceLocationProvider;
                    }
                }
            }
            var disassembler = new Disassembler(host, methodDefinition, sourceLocationProvider);
            var methodBody   = disassembler.Execute();

            var cfAnalysis = new ControlFlowAnalysis(methodBody);
            // var cfg = cfAnalysis.GenerateNormalControlFlow();
            var cfg = cfAnalysis.GenerateExceptionalControlFlow();

            var domAnalysis = new DominanceAnalysis(cfg);

            domAnalysis.Analyze();
            domAnalysis.GenerateDominanceTree();

            var loopAnalysis = new NaturalLoopAnalysis(cfg);

            loopAnalysis.Analyze();

            var domFrontierAnalysis = new DominanceFrontierAnalysis(cfg);

            domFrontierAnalysis.Analyze();

            var splitter = new WebAnalysis(cfg, methodDefinition);

            splitter.Analyze();
            splitter.Transform();

            methodBody.UpdateVariables();

            var typeAnalysis = new TypeInferenceAnalysis(cfg, methodDefinition.Type);

            typeAnalysis.Analyze();

            var forwardCopyAnalysis = new ForwardCopyPropagationAnalysis(cfg);

            forwardCopyAnalysis.Analyze();
            forwardCopyAnalysis.Transform(methodBody);

            // backwardCopyAnalysis is buggy - it says so in the source file - see notes in src/test
            // var backwardCopyAnalysis = new BackwardCopyPropagationAnalysis(cfg);
            // backwardCopyAnalysis.Analyze();
            // backwardCopyAnalysis.Transform(methodBody);

            var liveVariables = new LiveVariablesAnalysis(cfg);

            liveVariables.Analyze();

            var ssa = new StaticSingleAssignment(methodBody, cfg);

            ssa.Transform();
            ssa.Prune(liveVariables);

            methodBody.UpdateVariables();

            MethodCfgAndTac mct = new MethodCfgAndTac(cfg, methodBody);

            foreach (IExceptionHandlerBlock ehInfo in disassembler.GetExceptionHandlers())
            {
                if (ehInfo is CatchExceptionHandler)
                {
                    mct.ehInfoList.Add(ehInfo as CatchExceptionHandler);
                }
            }
            return(mct);
        }
Пример #27
0
        internal string CalcTryUsingFuncOptions(DataFlowAnalysis dataFlow, ControlFlowAnalysis ctrlFlow, List <string> inputs, List <string> outputs)
        {
            string returnType         = "System.Int32";
            string returnTypeKind     = "TypeKind.Struct";
            bool   returnTypeIsExtern = false;

            var sb = new StringBuilder();

            sb.AppendFormat("needfuncinfo({0}), rettype(return, {1}, {2}, 0, true)", NeedFuncInfo ? "true" : "false", returnType, returnTypeKind);
            if (ctrlFlow.ReturnStatements.Length > 0 && !string.IsNullOrEmpty(ReturnVarName))
            {
                returnType = ClassInfo.GetFullName(SemanticInfo.ReturnType);
                if (string.IsNullOrEmpty(returnType))
                {
                    returnType = "null";
                }
                returnTypeKind     = "TypeKind." + SemanticInfo.ReturnType.TypeKind.ToString();
                returnTypeIsExtern = !SymbolTable.Instance.IsCs2DslSymbol(SemanticInfo.ReturnType);
                sb.Append(", ");
                sb.AppendFormat("rettype({0}, {1}, {2}, 1, {3})", ReturnVarName, returnType, returnTypeKind, returnTypeIsExtern ? "true" : "false");
            }
            foreach (var v in dataFlow.DataFlowsOut)
            {
                sb.Append(", ");
                int refOrOut = 2;
                if (inputs.Contains(v.Name))
                {
                    refOrOut = 1;
                }
                var psym = v as IParameterSymbol;
                var lsym = v as ILocalSymbol;
                if (null != psym)
                {
                    var  type     = ClassInfo.GetFullName(psym.Type);
                    var  typeKind = psym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(psym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("rettype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
                else if (null != lsym)
                {
                    var  type     = ClassInfo.GetFullName(lsym.Type);
                    var  typeKind = lsym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(lsym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("rettype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
            }
            if (ctrlFlow.ReturnStatements.Length > 0 && !string.IsNullOrEmpty(ReturnVarName))
            {
                sb.Append(", ");
                sb.AppendFormat("paramtype({0}, {1}, {2}, 1, {3})", ReturnVarName, returnType, returnTypeKind, returnTypeIsExtern ? "true" : "false");
            }
            foreach (var v in dataFlow.DataFlowsIn)
            {
                if (v.Name == "this")
                {
                    continue;
                }
                sb.Append(", ");
                int refOrOut = 0;
                if (outputs.Contains(v.Name))
                {
                    refOrOut = 1;
                }
                var psym = v as IParameterSymbol;
                var lsym = v as ILocalSymbol;
                if (null != psym)
                {
                    var  type     = ClassInfo.GetFullName(psym.Type);
                    var  typeKind = psym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(psym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("paramtype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
                else if (null != lsym)
                {
                    var  type     = ClassInfo.GetFullName(lsym.Type);
                    var  typeKind = lsym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(lsym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("paramtype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
            }
            foreach (var v in dataFlow.DataFlowsOut)
            {
                sb.Append(", ");
                int refOrOut = 2;
                if (inputs.Contains(v.Name))
                {
                    refOrOut = 1;
                }
                var psym = v as IParameterSymbol;
                var lsym = v as ILocalSymbol;
                if (null != psym)
                {
                    var  type     = ClassInfo.GetFullName(psym.Type);
                    var  typeKind = psym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(psym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("paramtype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
                else if (null != lsym)
                {
                    var  type     = ClassInfo.GetFullName(lsym.Type);
                    var  typeKind = lsym.Type.TypeKind.ToString();
                    bool isExtern = !SymbolTable.Instance.IsCs2DslSymbol(lsym.Type);
                    if (string.IsNullOrEmpty(type))
                    {
                        type = "null";
                    }
                    sb.AppendFormat("paramtype({0}, {1}, {2}, {3}, {4})", v.Name, type, typeKind, refOrOut, isExtern ? "true" : "false");
                }
            }
            return(sb.ToString());
        }
Пример #28
0
        public static ControlFlowGraph DoAnalysisPhases(this IMethodDefinition method, IMetadataHost host, ISourceLocationProvider locationProvider,
                                                        IEnumerable <IMethodReference> methodsToTryToInline = null)
        {
            AnalysisStats.extraAnalysisOverHead.Start();
            var disassembler = new Disassembler(host, method, locationProvider);

            var methodBody = disassembler.Execute();

            MethodBodyProvider.Instance.AddBody(method, methodBody);

            if (methodsToTryToInline != null)
            {
                DoInlining(method, host, methodBody, locationProvider, methodsToTryToInline);
            }

            var cfAnalysis = new ControlFlowAnalysis(methodBody);
            //var cfg = cfAnalysis.GenerateExceptionalControlFlow();
            var cfg = cfAnalysis.GenerateNormalControlFlow();

            var domAnalysis = new DominanceAnalysis(cfg);

            domAnalysis.Analyze();
            domAnalysis.GenerateDominanceTree();

            var loopAnalysis = new NaturalLoopAnalysis(cfg);

            loopAnalysis.Analyze();

            var domFrontierAnalysis = new DominanceFrontierAnalysis(cfg);

            domFrontierAnalysis.Analyze();

            var splitter = new WebAnalysis(cfg, method);

            splitter.Analyze();
            splitter.Transform();

            methodBody.UpdateVariables();


            var analysis = new TypeInferenceAnalysis(cfg, methodBody.MethodDefinition.Type);

            analysis.Analyze();

            var copyProgapagtion = new ForwardCopyPropagationAnalysis(cfg);

            copyProgapagtion.Analyze();
            copyProgapagtion.Transform(methodBody);

            //var backwardCopyProgapagtion = new BackwardCopyPropagationAnalysis(cfg);
            //backwardCopyProgapagtion.Analyze();
            //backwardCopyProgapagtion.Transform(methodBody);

            var liveVariables = new LiveVariablesAnalysis(cfg);
            var resultLiveVar = liveVariables.Analyze();


            var ssa = new StaticSingleAssignment(methodBody, cfg);

            ssa.Transform();
            ssa.Prune(liveVariables);
            methodBody.UpdateVariables();
            AnalysisStats.extraAnalysisOverHead.Stop();
            return(cfg);
        }
Пример #29
0
        //string _code = String.Empty;

        /// <summary>
        /// For a given methodDefinition, create a CFG and run basic analyses such as
        /// stack removal, SSA transformation, live-variables analysis, and copy-propagation.
        /// </summary>
        /// <param name="methodDefinition"></param>
        /// <returns></returns>
        private ControlFlowGraph PrepareMethod(IMethodDefinition methodDefinition)
        {
            var sw2 = new Stopwatch();

            sw2.Start();
            var disassembler = new Disassembler(mhost, methodDefinition, sourceLocationProvider);
            var methodBody   = disassembler.Execute();

            var cfAnalysis = new ControlFlowAnalysis(methodBody);
            var cfg        = cfAnalysis.GenerateNormalControlFlow();

            var domAnalysis = new DominanceAnalysis(cfg);

            domAnalysis.Analyze();
            domAnalysis.GenerateDominanceTree();

            var loopAnalysis = new NaturalLoopAnalysis(cfg);

            loopAnalysis.Analyze();

            var domFrontierAnalysis = new DominanceFrontierAnalysis(cfg);

            domFrontierAnalysis.Analyze();

            var splitter = new WebAnalysis(cfg, methodDefinition);

            splitter.Analyze();
            splitter.Transform();

            methodBody.UpdateVariables();

            var analysis = new TypeInferenceAnalysis(cfg, methodBody.MethodDefinition.Type);

            analysis.Analyze();

            var copyProgapagtion = new ForwardCopyPropagationAnalysis(cfg);

            copyProgapagtion.Analyze();
            copyProgapagtion.Transform(methodBody);

            var backwardCopyProgapagtion = new BackwardCopyPropagationAnalysis(cfg);

            backwardCopyProgapagtion.Analyze();
            backwardCopyProgapagtion.Transform(methodBody);

            var liveVariables = new LiveVariablesAnalysis(cfg);
            var resultLiveVar = liveVariables.Analyze();

            var ssa = new StaticSingleAssignment(methodBody, cfg);

            ssa.Transform();
            ssa.Prune(liveVariables);
            methodBody.UpdateVariables();
            sw2.Stop();
            this.nonAnalysisOverhead = sw2.Elapsed;
            return(cfg);

            //var cfg = ControlFlowGraph.GenerateNormalControlFlow(methodBody);
            //ControlFlowGraph.ComputeDominators(cfg);
            //ControlFlowGraph.IdentifyLoops(cfg);

            //ControlFlowGraph.ComputeDominatorTree(cfg);
            //ControlFlowGraph.ComputeDominanceFrontiers(cfg);

            //// Uniquely rename stack variables.
            //var splitter = new WebAnalysis(cfg);
            //splitter.Analyze();
            //splitter.Transform();

            //methodBody.UpdateVariables();

            //// Infer types for stack variables.
            //var typeAnalysis = new TypeInferenceAnalysis(cfg);
            //typeAnalysis.Analyze();

            //var backwardCopyAnalysis = new BackwardCopyPropagationAnalysis(cfg);
            //backwardCopyAnalysis.Analyze();
            //backwardCopyAnalysis.Transform(methodBody);

            //var lva = new LiveVariablesAnalysis(cfg);
            //lva.Analyze();

            //var ssa = new StaticSingleAssignmentAnalysis(methodBody, cfg);
            //ssa.Transform();
            //ssa.Prune(lva);

            //methodBody.UpdateVariables();

            ////_code = methodBody.ToString();
            //return cfg;
        }
Пример #30
0
        private void ComputeDependencyGraph(ControlFlowAnalysis cfg)
        {
            //var dependencyGraph = new DependencyGraph();

            //foreach (var cfgNode in cfg.ForwardOrder)
            //{
            //    var ptg = result[cfgNode.Id].Output;
            //    foreach (var instruction in cfgNode.Instructions)
            //    {
            //        var uses = instruction.UsedVariables;
            //        var defs = instruction.ModifiedVariables;
            //        var access = "";
            //        //if (instruction is StoreInstruction)
            //        //{
            //        //    var store = instruction as StoreInstruction;
            //        //    if (store.Result is InstanceFieldAccess)
            //        //    {
            //        //        var fieldAccess = store.Result as InstanceFieldAccess;
            //        //        access = fieldAccess.FieldName;
            //        //        defs.Add(store.Operand);
            //        //        LastDefSet(store.Operand, fieldAccess.Field, cfgNode.Id, ptg);
            //        //    }

            //        //}
            //        //else
            //        //{

            //        //}
            //        //// TODO: Complete
            //        foreach (var def in defs)
            //        {
            //            var v = def.Variables.Single();
            //            if (ptg.Variables.Contains(v))
            //            {
            //                var ptgNodes = ptg.GetTargets(v);
            //                foreach (var ptgNode in ptgNodes)
            //                {
            //                    var depNode = new DependencyInfo(ptgNode, access);
            //                    dependencyGraph.AddVertex(depNode);
            //                    var useAccess = "";
            //                    if (instruction is LoadInstruction)
            //                    {
            //                        var load = instruction as LoadInstruction;
            //                        if (load.Operand is InstanceFieldAccess)
            //                        {
            //                            var fieldAccess = load.Operand as InstanceFieldAccess;
            //                            useAccess = fieldAccess.FieldName;
            //                            uses.Add(load.Result);
            //                        }
            //                    }

            //                    foreach (var use in uses)
            //                    {
            //                        var v2 = use.Variables.Single();
            //                        if (ptg.Variables.Contains(v2))
            //                        {
            //                            var ptgUseNodes = ptg.GetTargets(v2);
            //                            foreach (var ptgNode2 in ptgUseNodes)
            //                            {
            //                                var useNode = new DependencyInfo(ptgNode2, useAccess);
            //                                dependencyGraph.ConnectVertex(depNode, useNode);
            //                            }
            //                        }
            //                    }
            //                }
            //            }
            //        }
            //   }
            //}
            //System.Console.WriteLine(dependencyGraph);
        }