/// <summary> /// Analyzes the ownership of the given-up symbol in the candidate callee. /// </summary> protected override void AnalyzeOwnershipInCandidateCallee(GivenUpOwnershipSymbol givenUpSymbol, MethodSummary calleeSummary, ExpressionSyntax call, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { ArgumentListSyntax argumentList = AnalysisContext.GetArgumentList(call); if (argumentList is null) { return; } for (int idx = 0; idx < argumentList.Arguments.Count; idx++) { var argIdentifier = AnalysisContext.GetRootIdentifier(argumentList.Arguments[idx].Expression); if (argIdentifier is 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) && this.IsFieldAccessedInSuccessor(v.Key, statement.Summary, machine))) { this.ErrorReporter.ReportGivenUpFieldOwnershipError(trace, argSymbol); } } } }
/// <summary> /// Analyzes the ownership of the given-up symbol in the candidate callee. /// </summary> 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; } if (call is InvocationExpressionSyntax invocation) { this.AnalyzeOwnershipInExpression(givenUpSymbol, invocation.Expression, statement, model, trace); } ArgumentListSyntax argumentList = 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 (this.AnalysisContext.IsTypePassedByValueOrImmutable(argType)) { continue; } var argIdentifier = 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); this.ErrorReporter.ReportGivenUpOwnershipAccess(newTrace); } } var fieldSymbols = calleeSummary.SideEffectsInfo.FieldFlowParamIndexes.Where( v => v.Value.Contains(idx)).Select(v => v.Key); foreach (var fieldSymbol in fieldSymbols) { if (this.IsFieldAccessedInSuccessor(fieldSymbol, statement.Summary, machine)) { this.ErrorReporter.ReportGivenUpOwnershipFieldAssignment(trace, fieldSymbol); } } if (calleeSummary.SideEffectsInfo.GivesUpOwnershipParamIndexes.Contains(idx)) { this.ErrorReporter.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); this.ErrorReporter.ReportGivenUpOwnershipFieldAccess(newTrace, fieldAccess.Key); } } } }