/// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="node">IControlFlowNode</param>
 /// <param name="summary">MethodSummary</param>
 private Statement(SyntaxNode syntaxNode, IControlFlowNode node,
                   MethodSummary summary)
 {
     this.SyntaxNode      = syntaxNode;
     this.ControlFlowNode = node;
     this.Summary         = summary;
 }
Beispiel #2
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="node">IControlFlowNode</param>
 /// <param name="summary">MethodSummary</param>
 private Statement(SyntaxNode syntaxNode, IControlFlowNode node,
     MethodSummary summary)
 {
     this.SyntaxNode = syntaxNode;
     this.ControlFlowNode = node;
     this.Summary = summary;
 }
Beispiel #3
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="cfg">ControlFlowGraph</param>
 /// <param name="summary">MethodSummary</param>
 /// <param name="loopExitNode">ControlFlowNode</param>
 internal LoopHeadControlFlowNode(IGraph <IControlFlowNode> cfg,
                                  MethodSummary summary, ControlFlowNode loopExitNode)
     : base(cfg, summary)
 {
     this.LoopExitNode = loopExitNode;
 }
Beispiel #4
0
 /// <summary>
 /// Creates a new statement.
 /// </summary>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="node">IControlFlowNode</param>
 /// <param name="summary">MethodSummary</param>
 /// <returns>Statement</returns>
 public static Statement Create(SyntaxNode syntaxNode, IControlFlowNode node,
     MethodSummary summary)
 {
     return new Statement(syntaxNode, node, summary);
 }
        /// <summary>
        /// Returns true if the field symbol is being accessed
        /// in a successor summary.
        /// </summary>
        /// <param name="fieldSymbol">IFieldSymbol</param>
        /// <param name="summary">MethodSummary</param>
        /// <param name="machine">StateMachine</param>
        /// <returns>Boolean</returns>
        protected bool IsFieldAccessedInSuccessor(IFieldSymbol fieldSymbol, MethodSummary summary,
            StateMachine machine)
        {
            if (!base.Configuration.DoStateTransitionAnalysis)
            {
                return true;
            }

            var successors = machine.GetSuccessorSummaries(summary);

            foreach (var successor in successors)
            {
                if (successor.SideEffectsInfo.FieldAccesses.ContainsKey(fieldSymbol))
                {
                    return true;
                }
            }

            return false;
        }
 /// <summary>
 /// Analyzes the ownership of the given-up symbol
 /// in the candidate callee.
 /// </summary>
 /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param>
 /// <param name="calleeSummary">MethodSummary</param>
 /// <param name="call">ExpressionSyntax</param>
 /// <param name="statement">Statement</param>
 /// <param name="machine">StateMachine</param>
 /// <param name="model">SemanticModel</param>
 /// <param name="trace">TraceInfo</param>
 protected abstract void AnalyzeOwnershipInCandidateCallee(GivenUpOwnershipSymbol givenUpSymbol,
     MethodSummary calleeSummary, ExpressionSyntax call, Statement statement,
     StateMachine machine, SemanticModel model, TraceInfo trace);
Beispiel #7
0
        /// <summary>
        /// Returns all the successor summaries.
        /// </summary>
        /// <param name="summary">MethodSummary</param>
        /// <returns>MethodSummarys</returns>
        internal ISet<MethodSummary> GetSuccessorSummaries(MethodSummary summary)
        {
            var summaries = new HashSet<MethodSummary>();
            if (this.MethodSummaries.Count == 0)
            {
                return summaries;
            }

            var fromStates = new HashSet<MachineState>();
            foreach (var state in this.MachineStates)
            {
                var summaryActions = state.MachineActions.FindAll(action
                    => action.MethodDeclaration.Equals(summary.Method));
                if (summaryActions.Count == 0)
                {
                    continue;
                }

                foreach (var summaryAction in summaryActions)
                {
                    if (!(summaryAction is OnExitMachineAction))
                    {
                        summaries.UnionWith(state.MachineActions.FindAll(action
                            => action is OnEventDoMachineAction || action is OnEventGotoMachineAction ||
                            action is OnEventPushMachineAction || action is OnExitMachineAction).
                            Select(action => action.MethodDeclaration).
                            Select(method => this.MethodSummaries[method]));
                    }
                }

                fromStates.Add(state);
            }

            foreach (var state in fromStates)
            {
                foreach (var successor in state.GetSuccessorStates())
                {
                    summaries.UnionWith(successor.MachineActions.FindAll(action
                        => action is OnEntryMachineAction || action is OnEventDoMachineAction ||
                        action is OnEventGotoMachineAction || action is OnEventPushMachineAction ||
                        action is OnExitMachineAction).
                        Select(action => action.MethodDeclaration).
                        Select(method => this.MethodSummaries[method]));
                }
            }

            return summaries;
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="cfg">ControlFlowGraph</param>
 /// <param name="summary">MethodSummary</param>
 /// <param name="loopExitNode">ControlFlowNode</param>
 internal LoopHeadControlFlowNode(IGraph<IControlFlowNode> cfg,
     MethodSummary summary, ControlFlowNode loopExitNode)
     : base(cfg, summary)
 {
     this.LoopExitNode = loopExitNode;
 }
        /// <summary>
        /// Analyzes the ownership of the given-up symbol
        /// in the candidate callee.
        /// </summary>
        /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param>
        /// <param name="calleeSummary">MethodSummary</param>
        /// <param name="call">ExpressionSyntax</param>
        /// <param name="statement">Statement</param>
        /// <param name="machine">StateMachine</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="trace">TraceInfo</param>
        protected override void AnalyzeOwnershipInCandidateCallee(GivenUpOwnershipSymbol givenUpSymbol,
            MethodSummary calleeSummary, ExpressionSyntax call, Statement statement,
            StateMachine machine, SemanticModel model, TraceInfo trace)
        {
            if (statement.Equals(givenUpSymbol.Statement) &&
                !statement.ControlFlowNode.IsSuccessorOf(
                    givenUpSymbol.Statement.ControlFlowNode))
            {
                return;
            }

            var invocation = call as InvocationExpressionSyntax;
            if (invocation != null)
            {
                this.AnalyzeOwnershipInExpression(givenUpSymbol, invocation.Expression, statement,
                    machine, model, trace);
            }

            ArgumentListSyntax argumentList = base.AnalysisContext.GetArgumentList(call);
            if (argumentList != null)
            {
                for (int idx = 0; idx < argumentList.Arguments.Count; idx++)
                {
                    var argType = model.GetTypeInfo(argumentList.Arguments[idx].Expression).Type;
                    if (base.AnalysisContext.IsTypePassedByValueOrImmutable(argType))
                    {
                        continue;
                    }

                    var argIdentifier = base.AnalysisContext.GetRootIdentifier(
                        argumentList.Arguments[idx].Expression);
                    ISymbol argSymbol = model.GetSymbolInfo(argIdentifier).Symbol;

                    if (statement.Summary.DataFlowAnalysis.FlowsIntoSymbol(argSymbol,
                        givenUpSymbol.ContainingSymbol, statement, givenUpSymbol.Statement))
                    {
                        if (calleeSummary.SideEffectsInfo.ParameterAccesses.ContainsKey(idx))
                        {
                            foreach (var access in calleeSummary.SideEffectsInfo.ParameterAccesses[idx])
                            {
                                TraceInfo newTrace = new TraceInfo();
                                newTrace.Merge(trace);
                                newTrace.AddErrorTrace(access.SyntaxNode);

                                AnalysisErrorReporter.ReportGivenUpOwnershipAccess(newTrace);
                            }
                        }

                        var fieldSymbols = calleeSummary.SideEffectsInfo.FieldFlowParamIndexes.Where(
                            v => v.Value.Contains(idx)).Select(v => v.Key);
                        foreach (var fieldSymbol in fieldSymbols)
                        {
                            if (base.IsFieldAccessedInSuccessor(fieldSymbol, statement.Summary, machine))
                            {
                                AnalysisErrorReporter.ReportGivenUpOwnershipFieldAssignment(trace, fieldSymbol);
                            }
                        }

                        if (calleeSummary.SideEffectsInfo.GivesUpOwnershipParamIndexes.Contains(idx))
                        {
                            AnalysisErrorReporter.ReportGivenUpOwnershipSending(trace, argSymbol);
                        }
                    }
                }
            }

            foreach (var fieldAccess in calleeSummary.SideEffectsInfo.FieldAccesses)
            {
                foreach (var access in fieldAccess.Value)
                {
                    if (statement.Summary.DataFlowAnalysis.FlowsIntoSymbol(givenUpSymbol.ContainingSymbol,
                        fieldAccess.Key, givenUpSymbol.Statement, statement))
                    {
                        TraceInfo newTrace = new TraceInfo();
                        newTrace.Merge(trace);
                        newTrace.AddErrorTrace(access.SyntaxNode);

                        AnalysisErrorReporter.ReportGivenUpOwnershipFieldAccess(newTrace, fieldAccess.Key);
                    }
                }
            }
        }
Beispiel #10
0
 /// <summary>
 /// Creates a new statement.
 /// </summary>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="node">IControlFlowNode</param>
 /// <param name="summary">MethodSummary</param>
 /// <returns>Statement</returns>
 public static Statement Create(SyntaxNode syntaxNode, IControlFlowNode node,
                                MethodSummary summary)
 {
     return(new Statement(syntaxNode, node, summary));
 }
        /// <summary>
        /// Analyzes the ownership of the given-up symbol
        /// in the candidate callee.
        /// </summary>
        /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param>
        /// <param name="calleeSummary">MethodSummary</param>
        /// <param name="call">ExpressionSyntax</param>
        /// <param name="statement">Statement</param>
        /// <param name="machine">StateMachine</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="trace">TraceInfo</param>
        protected override void AnalyzeOwnershipInCandidateCallee(GivenUpOwnershipSymbol givenUpSymbol,
            MethodSummary calleeSummary, ExpressionSyntax call, Statement statement,
            StateMachine machine, SemanticModel model, TraceInfo trace)
        {
            ArgumentListSyntax argumentList = base.AnalysisContext.GetArgumentList(call);
            if (argumentList == null)
            {
                return;
            }

            for (int idx = 0; idx < argumentList.Arguments.Count; idx++)
            {
                var argIdentifier = base.AnalysisContext.GetRootIdentifier(
                    argumentList.Arguments[idx].Expression);
                if (argIdentifier == null)
                {
                    continue;
                }

                ISymbol argSymbol = model.GetSymbolInfo(argIdentifier).Symbol;
                if (statement.Summary.DataFlowAnalysis.FlowsIntoSymbol(argSymbol,
                    givenUpSymbol.ContainingSymbol, statement, givenUpSymbol.Statement))
                {
                    if (calleeSummary.SideEffectsInfo.FieldFlowParamIndexes.Any(v => v.Value.Contains(idx) &&
                        base.IsFieldAccessedInSuccessor(v.Key, statement.Summary, machine)))
                    {
                        AnalysisErrorReporter.ReportGivenUpFieldOwnershipError(trace, argSymbol);
                    }
                }
            }
        }