/// <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; }
/// <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; }
/// <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> /// 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);
/// <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); } } } }
/// <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); } } } }