コード例 #1
0
ファイル: DataFlowAnalysis.cs プロジェクト: huangpf/PSharp
        /// <summary>
        /// Returns true if the given expression flows in the target.
        /// </summary>
        /// <param name="expr">Expression</param>
        /// <param name="target">Target</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="targetSyntaxNode">Target syntaxNode</param>
        /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean</returns>
        internal static bool FlowsIntoTarget(ExpressionSyntax expr, ISymbol target,
            SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode, SyntaxNode targetSyntaxNode,
            ControlFlowGraphNode targetCfgNode, SemanticModel model, AnalysisContext context)
        {
            ISymbol reference = null;
            if (!context.TryGetSymbolFromExpression(out reference, expr, model))
            {
                return false;
            }

            return DataFlowAnalysis.FlowsIntoTarget(reference, target, syntaxNode,
                cfgNode, targetSyntaxNode, targetCfgNode);
        }
コード例 #2
0
        /// <summary>
        /// Returns true if the given expression resets when flowing from the
        /// target in the given loop body control flow graph nodes. The given
        /// control flow graph nodes must be equal.
        /// </summary>
        /// <param name="expr">Expression</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="targetSyntaxNode">Target syntaxNode</param>
        /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean value</returns>
        internal static bool DoesResetInLoop(ExpressionSyntax expr, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, SyntaxNode targetSyntaxNode,
            ControlFlowGraphNode targetCfgNode, SemanticModel model, AnalysisContext context)
        {
            ISymbol reference = null;
            if (!cfgNode.Equals(targetCfgNode) ||
                !context.TryGetSymbolFromExpression(out reference, expr, model))
            {
                return false;
            }

            return DataFlowAnalysis.DoesResetInLoop(reference, syntaxNode, cfgNode,
                targetSyntaxNode, targetCfgNode);
        }
コード例 #3
0
        /// <summary>
        /// Returns true if the given field symbol is being accessed
        /// before being reset.
        /// </summary>
        /// <param name="field">Field</param>
        /// <param name="summary">MethodSummary</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean value</returns>
        internal static bool IsAccessedBeforeBeingReset(ISymbol field, MethodSummary summary,
            AnalysisContext context)
        {
            StateTransitionGraphNode stateTransitionNode = null;
            if (!context.StateTransitionGraphs.ContainsKey(summary.Machine))
            {
                return true;
            }

            stateTransitionNode = context.StateTransitionGraphs[summary.Machine].
                GetGraphNodeForSummary(summary);
            if (stateTransitionNode == null)
            {
                return true;
            }

            var result = stateTransitionNode.VisitSelfAndSuccessors(IsAccessedBeforeBeingReset,
                new Tuple<MethodSummary, ISymbol>(summary, field));

            return false;
        }
コード例 #4
0
        /// <summary>
        /// Returns the data flow map for the given control flow graph.
        /// </summary>
        /// <param name="summary">MethodSummary</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>DataFlowMap</returns>
        internal static DataFlowMap AnalyseControlFlowGraph(MethodSummary summary, AnalysisContext context)
        {
            var dataFlowMap = new DataFlowMap();
            var model = context.Compilation.GetSemanticModel(summary.Method.SyntaxTree);

            foreach (var param in summary.Method.ParameterList.Parameters)
            {
                var declType = model.GetTypeInfo(param.Type).Type;
                if (context.IsTypeAllowedToBeSend(declType) ||
                    context.IsMachineType(declType, model))
                {
                    continue;
                }

                var paramSymbol = model.GetDeclaredSymbol(param);
                dataFlowMap.MapRefToSymbol(paramSymbol, paramSymbol, summary.Method.ParameterList,
                    summary.Node, false);
            }

            DataFlowAnalysis.AnalyseControlFlowGraphNode(summary.Node, summary.Node,
                summary.Method.ParameterList, dataFlowMap, model, context);

            return dataFlowMap;
        }
コード例 #5
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 private RuntimeOnlyDirectAccessAnalysis(AnalysisContext context)
 {
     this.AnalysisContext = context;
 }
コード例 #6
0
 /// <summary>
 /// Creates a new sanity checking analysis pass.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <returns>SanityCheckingAnalysis</returns>
 public static SanityCheckingAnalysis Create(AnalysisContext context)
 {
     return new SanityCheckingAnalysis(context);
 }
コード例 #7
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 private SanityCheckingAnalysis(AnalysisContext context)
 {
     this.AnalysisContext = context;
 }
コード例 #8
0
 /// <summary>
 /// Registers immutable types.
 /// </summary>
 private static void RegisterImmutableTypes(AnalysisContext context)
 {
     context.RegisterImmutableType(typeof(MachineId));
 }
コード例 #9
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <param name="summary">MethodSummary</param>
 internal ControlFlowGraphNode(AnalysisContext context, MethodSummary summary)
 {
     this.AnalysisContext = context;
     this.Id = ControlFlowGraphNode.IdCounter++;
     this.Summary = summary;
     this.SyntaxNodes = new List<SyntaxNode>();
     this.IPredecessors = new HashSet<ControlFlowGraphNode>();
     this.ISuccessors = new HashSet<ControlFlowGraphNode>();
     this.IsGivesUpNode = false;
     this.IsJumpNode = false;
     this.IsLoopHeadNode = false;
 }
コード例 #10
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 private MethodSummaryAnalysis(AnalysisContext context)
 {
     this.AnalysisContext = context;
 }
コード例 #11
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 private RespectsOwnershipAnalysis(AnalysisContext context)
 {
     this.AnalysisContext = context;
 }
コード例 #12
0
ファイル: MethodSummary.cs プロジェクト: ashwini-mnnit/PSharp
        /// <summary>
        /// Tries to get the method summary of the given invocation. Returns
        /// null if such summary cannot be found.
        /// </summary>
        /// <param name="call">Call</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>MethodSummary</returns>
        internal static MethodSummary TryGetSummary(InvocationExpressionSyntax call, SemanticModel model,
            AnalysisContext context)
        {
            var callSymbol = model.GetSymbolInfo(call).Symbol;
            if (callSymbol == null)
            {
                return null;
            }

            if (callSymbol.ContainingType.ToString().Equals("Microsoft.PSharp.Machine") ||
                callSymbol.ContainingType.ToString().Equals("Microsoft.PSharp.MachineState"))
            {
                return null;
            }

            var definition = SymbolFinder.FindSourceDefinitionAsync(callSymbol, context.Solution).Result;
            if (definition == null || definition.DeclaringSyntaxReferences.IsEmpty)
            {
                return null;
            }

            var invocationCall = definition.DeclaringSyntaxReferences.First().GetSyntax()
                as MethodDeclarationSyntax;
            return MethodSummary.Factory.Summarize(context, invocationCall);
        }
コード例 #13
0
ファイル: MethodSummary.cs プロジェクト: ashwini-mnnit/PSharp
        /// <summary>
        /// Tries to get the method summary of the given object creation. Returns
        /// null if such summary cannot be found.
        /// </summary>
        /// <param name="call">Call</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>MethodSummary</returns>
        internal static MethodSummary TryGetSummary(ObjectCreationExpressionSyntax call, SemanticModel model,
            AnalysisContext context)
        {
            var callSymbol = model.GetSymbolInfo(call).Symbol;
            if (callSymbol == null)
            {
                return null;
            }

            var definition = SymbolFinder.FindSourceDefinitionAsync(callSymbol, context.Solution).Result;
            if (definition == null)
            {
                return null;
            }

            if (definition.DeclaringSyntaxReferences.IsEmpty)
            {
                return null;
            }

            var constructorCall = definition.DeclaringSyntaxReferences.First().GetSyntax()
                as ConstructorDeclarationSyntax;
            return MethodSummary.Factory.Summarize(context, constructorCall);
        }
コード例 #14
0
ファイル: MethodSummary.cs プロジェクト: ashwini-mnnit/PSharp
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <param name="method">Method</param>
 /// <param name="machine">Machine</param>
 /// <param name="state">State</param>
 private MethodSummary(AnalysisContext context, BaseMethodDeclarationSyntax method,
     ClassDeclarationSyntax machine, ClassDeclarationSyntax state)
 {
     this.AnalysisContext = context;
     this.Method = method;
     this.Machine = machine;
     this.State = state;
     this.Initialize();
 }
コード例 #15
0
ファイル: MethodSummary.cs プロジェクト: ashwini-mnnit/PSharp
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <param name="method">Method</param>
 private MethodSummary(AnalysisContext context, BaseMethodDeclarationSyntax method)
 {
     this.AnalysisContext = context;
     this.Method = method;
     this.Machine = null;
     this.State = null;
     this.Initialize();
 }
コード例 #16
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <param name="configuration">Configuration</param>
 /// <param name="logger">ILogger</param>
 /// <param name="errorReporter">ErrorReporter</param>
 private RespectsOwnershipAnalysisPass(AnalysisContext context, Configuration configuration,
                                       ILogger logger, ErrorReporter errorReporter)
     : base(context, configuration, logger, errorReporter)
 {
 }
コード例 #17
0
 /// <summary>
 /// Creates a new respects ownership analysis pass.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <param name="configuration">Configuration</param>
 /// <param name="logger">ILogger</param>
 /// <param name="errorReporter">ErrorReporter</param>
 /// <returns>RespectsOwnershipAnalysisPass</returns>
 internal static RespectsOwnershipAnalysisPass Create(AnalysisContext context,
                                                      Configuration configuration, ILogger logger, ErrorReporter errorReporter)
 {
     return(new RespectsOwnershipAnalysisPass(context, configuration, logger, errorReporter));
 }
コード例 #18
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 private StateTransitionAnalysis(AnalysisContext context)
 {
     this.AnalysisContext = context;
 }
コード例 #19
0
 /// <summary>
 /// Creates a new state transition analysis pass.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <returns>StateTransitionAnalysis</returns>
 public static StateTransitionAnalysis Create(AnalysisContext context)
 {
     return new StateTransitionAnalysis(context);
 }
コード例 #20
0
ファイル: MethodSummary.cs プロジェクト: ashwini-mnnit/PSharp
            /// <summary>
            /// Returns the summary of the given method.
            /// </summary>
            /// <param name="context">AnalysisContext</param>
            /// <param name="method">Method</param>
            /// <param name="machine">Machine</param>
            /// <param name="state">State</param>
            /// <returns>MethodSummary</returns>
            internal static MethodSummary Summarize(AnalysisContext context, BaseMethodDeclarationSyntax method,
                ClassDeclarationSyntax machine, ClassDeclarationSyntax state)
            {
                if (context.Summaries.ContainsKey(method))
                {
                    return context.Summaries[method];
                }

                return new MethodSummary(context, method, machine, state);
            }
コード例 #21
0
 /// <summary>
 /// Creates a new respects ownership analysis pass.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <returns>RespectsOwnershipAnalysis</returns>
 public static RespectsOwnershipAnalysis Create(AnalysisContext context)
 {
     return new RespectsOwnershipAnalysis(context);
 }
コード例 #22
0
ファイル: InheritanceAnalysis.cs プロジェクト: huangpf/PSharp
        /// <summary>
        /// Tries to get the list of potential methods that can override the given virtual call.
        /// If it cannot find such methods then it returns false.
        /// </summary>
        /// <param name="overriders">List of overrider methods</param>
        /// <param name="virtualCall">Virtual call</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="originalMachine">Original machine</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean</returns>
        internal static bool TryGetPotentialMethodOverriders(out HashSet<MethodDeclarationSyntax> overriders,
            InvocationExpressionSyntax virtualCall, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode,
            ClassDeclarationSyntax originalMachine, SemanticModel model, AnalysisContext context)
        {
            overriders = new HashSet<MethodDeclarationSyntax>();

            ISymbol calleeSymbol = null;
            SimpleNameSyntax callee = null;
            bool isThis = false;

            if (virtualCall.Expression is MemberAccessExpressionSyntax)
            {
                var expr = virtualCall.Expression as MemberAccessExpressionSyntax;
                var identifier = expr.Expression.DescendantNodesAndSelf().
                    OfType<IdentifierNameSyntax>().Last();
                calleeSymbol = model.GetSymbolInfo(identifier).Symbol;
                
                if (expr.Expression is ThisExpressionSyntax ||
                    context.IsMachineType(identifier, model))
                {
                    callee = expr.Name;
                    isThis = true;
                }
            }
            else
            {
                callee = virtualCall.Expression as IdentifierNameSyntax;
                isThis = true;
            }

            if (isThis)
            {
                foreach (var nestedClass in originalMachine.ChildNodes().OfType<ClassDeclarationSyntax>())
                {
                    foreach (var method in nestedClass.ChildNodes().OfType<MethodDeclarationSyntax>())
                    {
                        if (method.Identifier.ToString().Equals(callee.Identifier.ToString()))
                        {
                            overriders.Add(method);
                            return true;
                        }
                    }
                }

                foreach (var method in originalMachine.ChildNodes().OfType<MethodDeclarationSyntax>())
                {
                    if (method.Identifier.ToString().Equals(callee.Identifier.ToString()))
                    {
                        overriders.Add(method);
                        return true;
                    }
                }

                return false;
            }

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

            Dictionary<ISymbol, HashSet<ITypeSymbol>> objectTypeMap = null;
            if (!cfgNode.Summary.DataFlowMap.TryGetObjectTypeMapForSyntaxNode(
                syntaxNode, cfgNode, out objectTypeMap))
            {
                return false;
            }

            if (!objectTypeMap.ContainsKey(calleeSymbol))
            {
                return false;
            }

            foreach (var objectType in objectTypeMap[calleeSymbol])
            {
                MethodDeclarationSyntax m = null;
                if (InheritanceAnalysis.TryGetMethodFromType(out m, objectType, virtualCall, context))
                {
                    overriders.Add(m);
                }
            }

            return true;
        }
コード例 #23
0
 /// <summary>
 /// Creates a new method summary analysis pass.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <returns>MethodSummaryAnalysis</returns>
 public static MethodSummaryAnalysis Create(AnalysisContext context)
 {
     return new MethodSummaryAnalysis(context);
 }
コード例 #24
0
ファイル: DataFlowAnalysis.cs プロジェクト: huangpf/PSharp
        /// <summary>
        /// Tries to capture a potential parameter acccess in the given expression.
        /// </summary>
        /// <param name="expr">Expression</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        private static void TryCaptureParameterAccess(ExpressionSyntax expr, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, DataFlowMap dataFlowMap, SemanticModel model,
            AnalysisContext context)
        {
            if (!(expr is MemberAccessExpressionSyntax))
            {
                return;
            }

            var name = (expr as MemberAccessExpressionSyntax).Name;
            var identifier = context.GetFirstNonMachineIdentifier(expr, model);
            if (identifier == null || name == null)
            {
                return;
            }

            var type = model.GetTypeInfo(identifier).Type;
            if (context.IsTypeAllowedToBeSend(type) ||
                context.IsMachineType(type, model) ||
                name.Equals(identifier))
            {
                return;
            }

            var symbol = model.GetSymbolInfo(identifier).Symbol;
            if (symbol == null)
            {
                return;
            }

            Dictionary<ISymbol, HashSet<ISymbol>> map = null;
            if (!dataFlowMap.TryGetMapForSyntaxNode(syntaxNode, cfgNode, out map))
            {
                return;
            }

            Dictionary<ISymbol, int> indexMap = new Dictionary<ISymbol, int>();
            var parameterList = cfgNode.Summary.Method.ParameterList.Parameters;
            for (int idx = 0; idx < parameterList.Count; idx++)
            {
                var paramSymbol = model.GetDeclaredSymbol(parameterList[idx]);
                indexMap.Add(paramSymbol, idx);
            }

            if (map.ContainsKey(symbol))
            {
                foreach (var reference in map[symbol])
                {
                    if (reference.Kind == SymbolKind.Parameter)
                    {
                        if (reference.Equals(symbol) && dataFlowMap.DoesSymbolReset(
                            reference, cfgNode.Summary.Node.SyntaxNodes.First(),
                            cfgNode.Summary.Node, syntaxNode, cfgNode, true))
                        {
                            continue;
                        }

                        int index = indexMap[reference];
                        if (cfgNode.Summary.AccessSet.ContainsKey(index))
                        {
                            cfgNode.Summary.AccessSet[index].Add(syntaxNode);
                        }
                        else
                        {
                            cfgNode.Summary.AccessSet.Add(index, new HashSet<SyntaxNode>());
                            cfgNode.Summary.AccessSet[index].Add(syntaxNode);
                        }
                    }
                }
            }
        }
コード例 #25
0
ファイル: InheritanceAnalysis.cs プロジェクト: huangpf/PSharp
        /// <summary>
        /// Tries to get the method from the given type and virtual call.
        /// </summary>
        /// <param name="method">Method</param>
        /// <param name="type">Type</param>
        /// <param name="virtualCall">Virtual call</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean</returns>
        private static bool TryGetMethodFromType(out MethodDeclarationSyntax method, ITypeSymbol type,
            InvocationExpressionSyntax virtualCall, AnalysisContext context)
        {
            method = null;

            var definition = SymbolFinder.FindSourceDefinitionAsync(type, context.Solution).Result;
            if (definition == null)
            {
                return false;
            }

            var calleeClass = definition.DeclaringSyntaxReferences.First().GetSyntax()
                as ClassDeclarationSyntax;
            foreach (var m in calleeClass.ChildNodes().OfType<MethodDeclarationSyntax>())
            {
                if (m.Identifier.ValueText.Equals(context.GetCallee(virtualCall)))
                {
                    method = m;
                    break;
                }
            }

            return true;
        }
コード例 #26
0
        /// <summary>
        /// Analyzes the given P# project.
        /// </summary>
        private void AnalyzeProject(Project project)
        {
            // Starts profiling the analysis.
            if (this.CompilationContext.Configuration.EnableProfiling)
            {
                this.Profiler.StartMeasuringExecutionTime();
            }

            // Create a state-machine static analysis context.
            var context = AnalysisContext.Create(project);

            this.PerformErrorChecking(context);

            RegisterImmutableTypes(context);
            RegisterGivesUpOwnershipOperations(context);

            // Creates and runs an analysis pass that computes the
            // summaries for every P# machine.
            ISet <StateMachine> machines = new HashSet <StateMachine>();

            try
            {
                // Creates summaries for each machine, which can be used for subsequent
                // analyses. Optionally performs data-flow analysis.
                MachineSummarizationPass.Create(context, this.CompilationContext.Configuration, this.Logger,
                                                this.ErrorReporter).Run(machines);

                // Creates and runs an analysis pass that detects if a machine contains
                // states that are declared as generic. This is not allowed by P#.
                NoGenericStatesAnalysisPass.Create(context, this.CompilationContext.Configuration, this.Logger,
                                                   this.ErrorReporter).Run(machines);

                // Creates and runs an analysis pass that finds if a machine exposes
                // any fields or methods to other machines.
                DirectAccessAnalysisPass.Create(context, this.CompilationContext.Configuration, this.Logger,
                                                this.ErrorReporter).Run(machines);

                if (this.CompilationContext.Configuration.AnalyzeDataRaces)
                {
                    // Creates and runs an analysis pass that detects if any method
                    // in each machine is erroneously giving up ownership.
                    GivesUpOwnershipAnalysisPass.Create(context, this.CompilationContext.Configuration, this.Logger,
                                                        this.ErrorReporter).Run(machines);

                    // Creates and runs an analysis pass that detects if all methods
                    // in each machine respect given up ownerships.
                    RespectsOwnershipAnalysisPass.Create(context, this.CompilationContext.Configuration, this.Logger,
                                                         this.ErrorReporter).Run(machines);
                }
            }
            catch (Exception ex)
            {
                if (this.CompilationContext.Configuration.ThrowInternalExceptions)
                {
#pragma warning disable CA2200 // Rethrow to preserve stack details.
                    throw ex;
#pragma warning restore CA2200 // Rethrow to preserve stack details.
                }

                this.Logger.WriteLine($"... Failed to analyze project '{project.Name}'");
                if (this.CompilationContext.Configuration.EnableDebugging)
                {
                    this.Logger.WriteLine(ex.ToString());
                }
            }
            finally
            {
                // Stops profiling the analysis.
                if (this.CompilationContext.Configuration.EnableProfiling)
                {
                    this.Profiler.StopMeasuringExecutionTime();
                    this.Logger.WriteLine("... Total static analysis runtime: '" +
                                          this.Profiler.Results() + "' seconds.");
                }
            }
        }
コード例 #27
0
ファイル: DataFlowAnalysis.cs プロジェクト: huangpf/PSharp
        /// <summary>
        /// Checks if the gives up call has a field symbol argument that is not
        /// already mapped and, if yes, maps it.
        /// </summary>
        /// <param name="call">Call</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        private static void CheckForNonMappedFieldSymbol(InvocationExpressionSyntax call,
            ControlFlowGraphNode cfgNode, DataFlowMap dataFlowMap, SemanticModel model,
            AnalysisContext context)
        {
            if (!cfgNode.IsGivesUpNode)
            {
                return;
            }

            List<MemberAccessExpressionSyntax> accesses;
            if (cfgNode.Summary.GivesUpSet.Count == 0 && call.Expression.DescendantNodesAndSelf().
                OfType<IdentifierNameSyntax>().Last().ToString().Equals("Send"))
            {
                accesses = call.ArgumentList.Arguments[1].DescendantNodesAndSelf().
                    OfType<MemberAccessExpressionSyntax>().ToList();
            }
            else
            {
                accesses = call.ArgumentList.DescendantNodesAndSelf().OfType<MemberAccessExpressionSyntax>().ToList();
            }

            foreach (var access in accesses)
            {
                IdentifierNameSyntax id = context.GetFirstNonMachineIdentifier(access, model);
                if (id == null)
                {
                    continue;
                }

                var accessSymbol = model.GetSymbolInfo(id).Symbol;
                dataFlowMap.MapSymbolIfNotExists(accessSymbol, cfgNode.SyntaxNodes[0], cfgNode);
            }
        }
コード例 #28
0
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <param name="machine">Machine</param>
 internal StateTransitionGraphNode(AnalysisContext context, ClassDeclarationSyntax state,
     ClassDeclarationSyntax machine)
 {
     this.AnalysisContext = context;
     this.Id = StateTransitionGraphNode.IdCounter++;
     this.State = state;
     this.Machine = machine;
     this.Actions = new HashSet<MethodSummary>();
     this.IPredecessors = new HashSet<StateTransitionGraphNode>();
     this.ISuccessors = new HashSet<StateTransitionGraphNode>();
     this.IsStartNode = false;
 }
コード例 #29
0
ファイル: DataFlowAnalysis.cs プロジェクト: huangpf/PSharp
        /// <summary>
        /// Tries to capture a potential field acccess in the given expression.
        /// </summary>
        /// <param name="expr">Expression</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        private static void TryCaptureFieldAccess(ExpressionSyntax expr, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, DataFlowMap dataFlowMap, SemanticModel model,
            AnalysisContext context)
        {
            if (!(expr is MemberAccessExpressionSyntax))
            {
                return;
            }

            var name = (expr as MemberAccessExpressionSyntax).Name;
            var identifier = context.GetFirstNonMachineIdentifier(expr, model);
            if (identifier == null || name == null)
            {
                return;
            }

            var type = model.GetTypeInfo(identifier).Type;
            if (context.IsTypeAllowedToBeSend(type) ||
                context.IsMachineType(type, model) ||
                name.Equals(identifier))
            {
                return;
            }

            var symbol = model.GetSymbolInfo(identifier).Symbol;
            var definition = SymbolFinder.FindSourceDefinitionAsync(symbol,
                context.Solution).Result;
            if (!(definition is IFieldSymbol))
            {
                return;
            }
            
            var fieldDecl = definition.DeclaringSyntaxReferences.First().GetSyntax().
                AncestorsAndSelf().OfType<FieldDeclarationSyntax>().First();
            if (dataFlowMap.DoesSymbolReset(symbol, cfgNode.Summary.Node.SyntaxNodes.First(),
                cfgNode.Summary.Node, syntaxNode, cfgNode, true))
            {
                return;
            }

            if (cfgNode.Summary.FieldAccessSet.ContainsKey(symbol as IFieldSymbol))
            {
                cfgNode.Summary.FieldAccessSet[symbol as IFieldSymbol].Add(syntaxNode);
            }
            else
            {
                cfgNode.Summary.FieldAccessSet.Add(symbol as IFieldSymbol, new HashSet<SyntaxNode>());
                cfgNode.Summary.FieldAccessSet[symbol as IFieldSymbol].Add(syntaxNode);
            }
        }
コード例 #30
0
 /// <summary>
 /// Creates a new runtime only direct access analysis pass.
 /// </summary>
 /// <param name="context">AnalysisContext</param>
 /// <returns>RuntimeOnlyDirectAccessAnalysis</returns>
 public static RuntimeOnlyDirectAccessAnalysis Create(AnalysisContext context)
 {
     return new RuntimeOnlyDirectAccessAnalysis(context);
 }
コード例 #31
0
ファイル: DataFlowAnalysis.cs プロジェクト: huangpf/PSharp
        /// <summary>
        /// Performs data flow analysis on the given control flow graph node.
        /// </summary>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="previousCfgNode">Previous controlFlowGraphNode</param>
        /// <param name="previousSyntaxNode">Previous syntaxNode</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean</returns>
        private static void AnalyseControlFlowGraphNode(ControlFlowGraphNode cfgNode, ControlFlowGraphNode previousCfgNode,
            SyntaxNode previousSyntaxNode, DataFlowMap dataFlowMap, SemanticModel model, AnalysisContext context)
        {
            if (!cfgNode.IsJumpNode && !cfgNode.IsLoopHeadNode)
            {
                foreach (var syntaxNode in cfgNode.SyntaxNodes)
                {
                    dataFlowMap.Transfer(previousSyntaxNode, previousCfgNode, syntaxNode, cfgNode);

                    var stmt = syntaxNode as StatementSyntax;
                    var localDecl = stmt.DescendantNodesAndSelf().OfType<LocalDeclarationStatementSyntax>().FirstOrDefault();
                    var expr = stmt.DescendantNodesAndSelf().OfType<ExpressionStatementSyntax>().FirstOrDefault();
                    var ret = stmt.DescendantNodesAndSelf().OfType<ReturnStatementSyntax>().FirstOrDefault();

                    if (localDecl != null)
                    {
                        var varDecl = (stmt as LocalDeclarationStatementSyntax).Declaration;
                        foreach (var variable in varDecl.Variables)
                        {
                            if (variable.Initializer == null)
                            {
                                continue;
                            }

                            DataFlowAnalysis.TryCaptureParameterAccess(variable.Initializer.Value,
                                syntaxNode, cfgNode, dataFlowMap, model, context);
                            DataFlowAnalysis.TryCaptureFieldAccess(variable.Initializer.Value,
                                syntaxNode, cfgNode, dataFlowMap, model, context);

                            ITypeSymbol declType = null;
                            if (variable.Initializer.Value is LiteralExpressionSyntax &&
                                variable.Initializer.Value.IsKind(SyntaxKind.NullLiteralExpression))
                            {
                                declType = model.GetTypeInfo(varDecl.Type).Type;
                            }
                            else
                            {
                                declType = model.GetTypeInfo(variable.Initializer.Value).Type;
                            }

                            if (context.IsTypeAllowedToBeSend(declType) ||
                                context.IsMachineType(declType, model))
                            {
                                continue;
                            }

                            var declSymbol = model.GetDeclaredSymbol(variable);

                            if (variable.Initializer.Value is IdentifierNameSyntax ||
                                variable.Initializer.Value is MemberAccessExpressionSyntax)
                            {
                                ISymbol varSymbol = null;
                                if (variable.Initializer.Value is IdentifierNameSyntax)
                                {
                                    varSymbol = model.GetSymbolInfo(variable.Initializer.Value
                                        as IdentifierNameSyntax).Symbol;
                                }
                                else if (variable.Initializer.Value is MemberAccessExpressionSyntax)
                                {
                                    varSymbol = model.GetSymbolInfo((variable.Initializer.Value
                                        as MemberAccessExpressionSyntax).Name).Symbol;
                                }

                                dataFlowMap.MapRefToSymbol(varSymbol, declSymbol, syntaxNode, cfgNode);

                                HashSet<ITypeSymbol> objectTypes = null;
                                if (DataFlowAnalysis.ResolveObjectType(out objectTypes, varSymbol, syntaxNode,
                                    cfgNode, dataFlowMap))
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(objectTypes, declSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (variable.Initializer.Value is LiteralExpressionSyntax &&
                                variable.Initializer.Value.IsKind(SyntaxKind.NullLiteralExpression))
                            {
                                dataFlowMap.ResetSymbol(declSymbol, syntaxNode, cfgNode);
                            }
                            else if (variable.Initializer.Value is InvocationExpressionSyntax)
                            {
                                var invocation = variable.Initializer.Value as InvocationExpressionSyntax;
                                var summary = MethodSummary.TryGetSummary(invocation, model, context);
                                var reachableSymbols = DataFlowAnalysis.ResolveSideEffectsInCall(invocation,
                                    summary, syntaxNode, cfgNode, model, dataFlowMap);
                                var returnSymbols = DataFlowAnalysis.GetReturnSymbols(invocation, summary, model);

                                if (returnSymbols.Count == 0)
                                {
                                    dataFlowMap.ResetSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                                else if (returnSymbols.Contains(declSymbol))
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, declSymbol, syntaxNode, cfgNode, false);
                                }
                                else
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, declSymbol, syntaxNode, cfgNode);
                                }

                                if (reachableSymbols.Count > 0)
                                {
                                    dataFlowMap.MapReachableFieldsToSymbol(reachableSymbols, declSymbol,
                                        syntaxNode, cfgNode);
                                }

                                if (summary != null && summary.ReturnTypeSet.Count > 0)
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(summary.ReturnTypeSet,
                                        declSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (variable.Initializer.Value is ObjectCreationExpressionSyntax)
                            {
                                var objCreation = variable.Initializer.Value as ObjectCreationExpressionSyntax;
                                var summary = MethodSummary.TryGetSummary(objCreation, model, context);
                                var reachableSymbols = DataFlowAnalysis.ResolveSideEffectsInCall(objCreation,
                                    summary, syntaxNode, cfgNode, model, dataFlowMap);
                                var returnSymbols = DataFlowAnalysis.GetReturnSymbols(objCreation, summary, model);

                                if (returnSymbols.Count == 0)
                                {
                                    dataFlowMap.ResetSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                                else if (returnSymbols.Contains(declSymbol))
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, declSymbol, syntaxNode, cfgNode, false);
                                }
                                else
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, declSymbol, syntaxNode, cfgNode);
                                }

                                if (reachableSymbols.Count > 0)
                                {
                                    dataFlowMap.MapReachableFieldsToSymbol(reachableSymbols, declSymbol,
                                        syntaxNode, cfgNode);
                                }

                                var typeSymbol = model.GetSymbolInfo(objCreation.Type).Symbol as ITypeSymbol;
                                if (typeSymbol != null)
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(new HashSet<ITypeSymbol> { typeSymbol },
                                        declSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                            }
                        }
                    }
                    else if (expr != null)
                    {
                        if (expr.Expression is BinaryExpressionSyntax)
                        {
                            var binaryExpr = expr.Expression as BinaryExpressionSyntax;

                            DataFlowAnalysis.TryCaptureParameterAccess(binaryExpr.Left,
                                syntaxNode, cfgNode, dataFlowMap, model, context);
                            DataFlowAnalysis.TryCaptureParameterAccess(binaryExpr.Right,
                                syntaxNode, cfgNode, dataFlowMap, model, context);
                            DataFlowAnalysis.TryCaptureFieldAccess(binaryExpr.Left,
                                syntaxNode, cfgNode, dataFlowMap, model, context);
                            DataFlowAnalysis.TryCaptureFieldAccess(binaryExpr.Right,
                                syntaxNode, cfgNode, dataFlowMap, model, context);

                            IdentifierNameSyntax lhs = null;
                            ISymbol lhsFieldSymbol = null;
                            if (binaryExpr.Left is IdentifierNameSyntax)
                            {
                                lhs = binaryExpr.Left as IdentifierNameSyntax;
                                var lhsType = model.GetTypeInfo(lhs).Type;
                                if (context.IsTypeAllowedToBeSend(lhsType) ||
                                    context.IsMachineType(lhsType, model))
                                {
                                    previousSyntaxNode = syntaxNode;
                                    previousCfgNode = cfgNode;
                                    continue;
                                }
                            }
                            else if (binaryExpr.Left is MemberAccessExpressionSyntax)
                            {
                                var name = (binaryExpr.Left as MemberAccessExpressionSyntax).Name;
                                var lhsType = model.GetTypeInfo(name).Type;
                                if (context.IsTypeAllowedToBeSend(lhsType) ||
                                    context.IsMachineType(lhsType, model))
                                {
                                    previousSyntaxNode = syntaxNode;
                                    previousCfgNode = cfgNode;
                                    continue;
                                }

                                lhs = context.GetFirstNonMachineIdentifier(binaryExpr.Left, model);
                                lhsFieldSymbol = model.GetSymbolInfo(name as IdentifierNameSyntax).Symbol;
                            }
                            else if (binaryExpr.Left is ElementAccessExpressionSyntax)
                            {
                                var memberAccess = (binaryExpr.Left as ElementAccessExpressionSyntax);
                                if (memberAccess.Expression is IdentifierNameSyntax)
                                {
                                    lhs = memberAccess.Expression as IdentifierNameSyntax;
                                    var lhsType = model.GetTypeInfo(lhs).Type;
                                    if (context.IsTypeAllowedToBeSend(lhsType) ||
                                        context.IsMachineType(lhsType, model))
                                    {
                                        previousSyntaxNode = syntaxNode;
                                        previousCfgNode = cfgNode;
                                        continue;
                                    }
                                }
                                else if (memberAccess.Expression is MemberAccessExpressionSyntax)
                                {
                                    var name = (memberAccess.Expression as MemberAccessExpressionSyntax).Name;
                                    var lhsType = model.GetTypeInfo(name).Type;
                                    if (context.IsTypeAllowedToBeSend(lhsType) ||
                                        context.IsMachineType(lhsType, model))
                                    {
                                        previousSyntaxNode = syntaxNode;
                                        previousCfgNode = cfgNode;
                                        continue;
                                    }

                                    lhs = context.GetFirstNonMachineIdentifier(memberAccess.Expression, model);
                                    lhsFieldSymbol = model.GetSymbolInfo(name as IdentifierNameSyntax).Symbol;
                                }
                            }

                            var leftSymbol = model.GetSymbolInfo(lhs).Symbol;

                            if (binaryExpr.Right is IdentifierNameSyntax ||
                                binaryExpr.Right is MemberAccessExpressionSyntax)
                            {
                                IdentifierNameSyntax rhs = null;
                                if (binaryExpr.Right is IdentifierNameSyntax)
                                {
                                    rhs = binaryExpr.Right as IdentifierNameSyntax;
                                }
                                else if (binaryExpr.Right is MemberAccessExpressionSyntax)
                                {
                                    rhs = context.GetFirstNonMachineIdentifier(binaryExpr.Right, model);
                                }

                                var rightSymbol = model.GetSymbolInfo(rhs).Symbol;
                                dataFlowMap.MapRefToSymbol(rightSymbol, leftSymbol, syntaxNode, cfgNode);
                                if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                {
                                    dataFlowMap.MapRefToSymbol(rightSymbol, lhsFieldSymbol, syntaxNode, cfgNode);
                                }

                                HashSet<ITypeSymbol> objectTypes = null;
                                if (DataFlowAnalysis.ResolveObjectType(out objectTypes, rightSymbol, syntaxNode,
                                    cfgNode, dataFlowMap))
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(objectTypes, leftSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(leftSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (binaryExpr.Right is LiteralExpressionSyntax &&
                                binaryExpr.Right.IsKind(SyntaxKind.NullLiteralExpression))
                            {
                                dataFlowMap.ResetSymbol(leftSymbol, syntaxNode, cfgNode);
                                if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                {
                                    dataFlowMap.ResetSymbol(lhsFieldSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (binaryExpr.Right is InvocationExpressionSyntax)
                            {
                                var invocation = binaryExpr.Right as InvocationExpressionSyntax;
                                var summary = MethodSummary.TryGetSummary(invocation, model, context);
                                var reachableSymbols = DataFlowAnalysis.ResolveSideEffectsInCall(invocation,
                                    summary, syntaxNode, cfgNode, model, dataFlowMap);
                                var returnSymbols = DataFlowAnalysis.GetReturnSymbols(invocation,
                                    summary, model);
                                DataFlowAnalysis.CheckForNonMappedFieldSymbol(invocation, cfgNode,
                                    dataFlowMap, model, context);

                                if (returnSymbols.Count == 0)
                                {
                                    dataFlowMap.ResetSymbol(leftSymbol, syntaxNode, cfgNode);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.ResetSymbol(lhsFieldSymbol, syntaxNode, cfgNode);
                                    }
                                }
                                else if (returnSymbols.Contains(leftSymbol))
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, leftSymbol, syntaxNode, cfgNode, false);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.MapRefsToSymbol(returnSymbols, lhsFieldSymbol,
                                            syntaxNode, cfgNode, false);
                                    }
                                }
                                else
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, leftSymbol, syntaxNode, cfgNode);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.MapRefsToSymbol(returnSymbols, lhsFieldSymbol,
                                            syntaxNode, cfgNode);
                                    }
                                }

                                if (lhsFieldSymbol != null && reachableSymbols.Count > 0)
                                {
                                    dataFlowMap.MapReachableFieldsToSymbol(reachableSymbols, lhsFieldSymbol,
                                        syntaxNode, cfgNode);
                                }

                                if (summary != null && summary.ReturnTypeSet.Count > 0)
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(summary.ReturnTypeSet,
                                        leftSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(leftSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (binaryExpr.Right is ObjectCreationExpressionSyntax)
                            {
                                var objCreation = binaryExpr.Right as ObjectCreationExpressionSyntax;
                                var summary = MethodSummary.TryGetSummary(objCreation, model, context);
                                var reachableSymbols = DataFlowAnalysis.ResolveSideEffectsInCall(objCreation,
                                    summary, syntaxNode, cfgNode, model, dataFlowMap);
                                var returnSymbols = DataFlowAnalysis.GetReturnSymbols(objCreation, summary, model);

                                if (returnSymbols.Count == 0)
                                {
                                    dataFlowMap.ResetSymbol(leftSymbol, syntaxNode, cfgNode);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.ResetSymbol(lhsFieldSymbol, syntaxNode, cfgNode);
                                    }
                                }
                                else if (returnSymbols.Contains(leftSymbol))
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, leftSymbol, syntaxNode, cfgNode, false);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.MapRefsToSymbol(returnSymbols, lhsFieldSymbol,
                                            syntaxNode, cfgNode, false);
                                    }
                                }
                                else
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, leftSymbol, syntaxNode, cfgNode);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.MapRefsToSymbol(returnSymbols, lhsFieldSymbol,
                                            syntaxNode, cfgNode);
                                    }
                                }

                                if (lhsFieldSymbol != null && reachableSymbols.Count > 0)
                                {
                                    dataFlowMap.MapReachableFieldsToSymbol(reachableSymbols, lhsFieldSymbol,
                                        syntaxNode, cfgNode);
                                }

                                var typeSymbol = model.GetSymbolInfo(objCreation.Type).Symbol as ITypeSymbol;
                                if (typeSymbol != null)
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(new HashSet<ITypeSymbol> { typeSymbol },
                                        leftSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(leftSymbol, syntaxNode, cfgNode);
                                }
                            }
                        }
                        else if (expr.Expression is InvocationExpressionSyntax)
                        {
                            var invocation = expr.Expression as InvocationExpressionSyntax;
                            var summary = MethodSummary.TryGetSummary(invocation, model, context);
                            DataFlowAnalysis.ResolveSideEffectsInCall(invocation, summary,
                                syntaxNode, cfgNode, model, dataFlowMap);
                            DataFlowAnalysis.GetReturnSymbols(invocation, summary, model);
                            DataFlowAnalysis.CheckForNonMappedFieldSymbol(invocation, cfgNode,
                                dataFlowMap, model, context);
                        }
                    }
                    else if (ret != null)
                    {
                        HashSet<ISymbol> returnSymbols = null;
                        if (ret.Expression is IdentifierNameSyntax ||
                            ret.Expression is MemberAccessExpressionSyntax)
                        {
                            IdentifierNameSyntax rhs = null;
                            if (ret.Expression is IdentifierNameSyntax)
                            {
                                rhs = ret.Expression as IdentifierNameSyntax;
                            }
                            else if (ret.Expression is MemberAccessExpressionSyntax)
                            {
                                rhs = context.GetFirstNonMachineIdentifier(ret.Expression, model);
                            }

                            var rightSymbol = model.GetSymbolInfo(rhs).Symbol;
                            returnSymbols = new HashSet<ISymbol> { rightSymbol };

                            HashSet<ITypeSymbol> objectTypes = null;
                            if (DataFlowAnalysis.ResolveObjectType(out objectTypes, rightSymbol,
                                syntaxNode, cfgNode, dataFlowMap))
                            {
                                foreach (var objectType in objectTypes)
                                {
                                    cfgNode.Summary.ReturnTypeSet.Add(objectType);
                                }
                            }
                        }
                        else if (ret.Expression is InvocationExpressionSyntax)
                        {
                            var invocation = ret.Expression as InvocationExpressionSyntax;
                            var summary = MethodSummary.TryGetSummary(invocation, model, context);
                            DataFlowAnalysis.ResolveSideEffectsInCall(invocation, summary,
                                syntaxNode, cfgNode, model, dataFlowMap);
                            returnSymbols = DataFlowAnalysis.GetReturnSymbols(invocation, summary, model);

                            if (summary != null)
                            {
                                foreach (var objectType in summary.ReturnTypeSet)
                                {
                                    cfgNode.Summary.ReturnTypeSet.Add(objectType);
                                }
                            }
                        }
                        else if (ret.Expression is ObjectCreationExpressionSyntax)
                        {
                            var objCreation = ret.Expression as ObjectCreationExpressionSyntax;
                            var summary = MethodSummary.TryGetSummary(objCreation, model, context);
                            DataFlowAnalysis.ResolveSideEffectsInCall(objCreation, summary,
                                syntaxNode, cfgNode, model, dataFlowMap);
                            returnSymbols = DataFlowAnalysis.GetReturnSymbols(objCreation, summary, model);

                            var objectType = model.GetSymbolInfo(objCreation.Type).Symbol as ITypeSymbol;
                            if (objectType != null)
                            {
                                cfgNode.Summary.ReturnTypeSet.Add(objectType);
                            }
                        }

                        DataFlowAnalysis.TryCaptureReturnSymbols(returnSymbols, syntaxNode,
                            cfgNode, model, dataFlowMap);
                    }

                    previousSyntaxNode = syntaxNode;
                    previousCfgNode = cfgNode;
                }
            }
            else
            {
                dataFlowMap.Transfer(previousSyntaxNode, previousCfgNode, cfgNode.SyntaxNodes[0], cfgNode);
                previousSyntaxNode = cfgNode.SyntaxNodes[0];
                previousCfgNode = cfgNode;
            }

            foreach (var successor in cfgNode.ISuccessors)
            {
                if (DataFlowAnalysis.ReachedFixpoint(previousSyntaxNode, cfgNode, successor, dataFlowMap))
                {
                    continue;
                }

                DataFlowAnalysis.AnalyseControlFlowGraphNode(successor, cfgNode,
                    previousSyntaxNode, dataFlowMap, model, context);
            }
        }
コード例 #32
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="methodDecl">MethodDeclarationSyntax</param>
 /// <param name="state">MachineState</param>
 /// <param name="context">AnalysisContext</param>
 internal OnEntryMachineAction(MethodDeclarationSyntax methodDecl, MachineState state,
                               AnalysisContext context)
     : base(methodDecl, state, context)
 {
 }