/// <summary> /// Analyzes the ownership of the given-up symbol /// in the control-flow graph node. /// </summary> protected void AnalyzeOwnershipInStatement(GivenUpOwnershipSymbol givenUpSymbol, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { var localDecl = statement.SyntaxNode.DescendantNodesAndSelf(). OfType <LocalDeclarationStatementSyntax>().FirstOrDefault(); var expr = statement.SyntaxNode.DescendantNodesAndSelf(). OfType <ExpressionStatementSyntax>().FirstOrDefault(); if (localDecl != null) { var varDecl = localDecl.Declaration; this.AnalyzeOwnershipInLocalDeclaration(givenUpSymbol, varDecl, statement, machine, model, trace); } else if (expr != null) { if (expr.Expression is AssignmentExpressionSyntax) { var assignment = expr.Expression as AssignmentExpressionSyntax; this.AnalyzeOwnershipInAssignment(givenUpSymbol, assignment, statement, machine, model, trace); } else if (expr.Expression is InvocationExpressionSyntax || expr.Expression is ObjectCreationExpressionSyntax) { trace.InsertCall(statement.Summary.Method, expr.Expression); this.AnalyzeOwnershipInCall(givenUpSymbol, expr.Expression, statement, machine, model, trace); } } }
/// <summary> /// Analyzes the ownership of the given-up symbol /// in the expression. /// </summary> /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param> /// <param name="expr">ExpressionSyntax</param> /// <param name="statement">Statement</param> /// <param name="machine">StateMachine</param> /// <param name="model">SemanticModel</param> /// <param name="trace">TraceInfo</param> private void AnalyzeOwnershipInExpression(GivenUpOwnershipSymbol givenUpSymbol, ExpressionSyntax expr, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { if (expr is IdentifierNameSyntax || expr is MemberAccessExpressionSyntax) { IdentifierNameSyntax rightIdentifier = base.AnalysisContext.GetRootIdentifier(expr); if (rightIdentifier != null) { var rightSymbol = model.GetSymbolInfo(rightIdentifier).Symbol; this.AnalyzeGivingUpFieldOwnership(givenUpSymbol, rightSymbol, statement, machine, trace); } } else if (expr is InvocationExpressionSyntax || expr is ObjectCreationExpressionSyntax) { trace.InsertCall(statement.Summary.Method, expr); HashSet <ISymbol> returnSymbols = base.AnalyzeOwnershipInCall(givenUpSymbol, expr, statement, machine, model, trace); foreach (var returnSymbol in returnSymbols) { this.AnalyzeGivingUpFieldOwnership(givenUpSymbol, returnSymbol, statement, machine, trace); } } }
/// <summary> /// Analyzes the ownership of the given-up symbol /// in the assignment expression. /// </summary> /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param> /// <param name="assignment">AssignmentExpressionSyntax</param> /// <param name="statement">Statement</param> /// <param name="machine">StateMachine</param> /// <param name="model">SemanticModel</param> /// <param name="trace">TraceInfo</param> protected override void AnalyzeOwnershipInAssignment(GivenUpOwnershipSymbol givenUpSymbol, AssignmentExpressionSyntax assignment, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { var leftIdentifier = base.AnalysisContext.GetRootIdentifier(assignment.Left); ISymbol leftSymbol = model.GetSymbolInfo(leftIdentifier).Symbol; if (assignment.Right is IdentifierNameSyntax) { var rightIdentifier = base.AnalysisContext.GetRootIdentifier(assignment.Right); ISymbol rightSymbol = model.GetSymbolInfo(rightIdentifier).Symbol; if (statement.Summary.DataFlowAnalysis.FlowsIntoSymbol(rightSymbol, givenUpSymbol.ContainingSymbol, statement, givenUpSymbol.Statement)) { var type = model.GetTypeInfo(assignment.Right).Type; if (leftSymbol != null && leftSymbol.Kind == SymbolKind.Field && base.IsFieldAccessedInSuccessor(leftSymbol as IFieldSymbol, statement.Summary, machine) && !base.AnalysisContext.IsTypePassedByValueOrImmutable(type)) { TraceInfo newTrace = new TraceInfo(); newTrace.Merge(trace); newTrace.AddErrorTrace(statement.SyntaxNode); AnalysisErrorReporter.ReportGivenUpOwnershipFieldAssignment(newTrace, leftSymbol); } return; } } else if (assignment.Right is MemberAccessExpressionSyntax) { this.AnalyzeOwnershipInExpression(givenUpSymbol, assignment.Right, statement, machine, model, trace); } else if (assignment.Right is InvocationExpressionSyntax || assignment.Right is ObjectCreationExpressionSyntax) { trace.InsertCall(statement.Summary.Method, assignment.Right); base.AnalyzeOwnershipInCall(givenUpSymbol, assignment.Right, statement, machine, model, trace); } if (assignment.Left is MemberAccessExpressionSyntax) { ISymbol outerLeftMemberSymbol = model.GetSymbolInfo(assignment.Left).Symbol; if (!outerLeftMemberSymbol.Equals(leftSymbol) && statement.Summary.DataFlowAnalysis.FlowsIntoSymbol(givenUpSymbol.ContainingSymbol, leftSymbol, givenUpSymbol.Statement, statement)) { TraceInfo newTrace = new TraceInfo(); newTrace.Merge(trace); newTrace.AddErrorTrace(statement.SyntaxNode); AnalysisErrorReporter.ReportGivenUpOwnershipAccess(newTrace); } } }
/// <summary> /// Analyzes the ownership of the given-up symbol in the variable declaration. /// </summary> protected override void AnalyzeOwnershipInLocalDeclaration(GivenUpOwnershipSymbol givenUpSymbol, VariableDeclarationSyntax varDecl, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { foreach (var variable in varDecl.Variables.Where(v => v.Initializer != null)) { var expr = variable.Initializer.Value; if (expr is IdentifierNameSyntax || expr is MemberAccessExpressionSyntax) { this.AnalyzeOwnershipInExpression(givenUpSymbol, expr, statement, model, trace); } else if (expr is InvocationExpressionSyntax || expr is ObjectCreationExpressionSyntax) { trace.InsertCall(statement.Summary.Method, expr); this.AnalyzeOwnershipInCall(givenUpSymbol, expr, statement, machine, model, trace); } } }
/// <summary> /// Analyzes the ownership of the given-up symbol /// in the control-flow graph node. /// </summary> /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param> /// <param name="statement">Statement</param> /// <param name="machine">StateMachine</param> /// <param name="model">SemanticModel</param> /// <param name="trace">TraceInfo</param> protected void AnalyzeOwnershipInStatement(GivenUpOwnershipSymbol givenUpSymbol, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { var localDecl = statement.SyntaxNode.DescendantNodesAndSelf(). OfType<LocalDeclarationStatementSyntax>().FirstOrDefault(); var expr = statement.SyntaxNode.DescendantNodesAndSelf(). OfType<ExpressionStatementSyntax>().FirstOrDefault(); if (localDecl != null) { var varDecl = localDecl.Declaration; this.AnalyzeOwnershipInLocalDeclaration(givenUpSymbol, varDecl, statement, machine, model, trace); } else if (expr != null) { if (expr.Expression is AssignmentExpressionSyntax) { var assignment = expr.Expression as AssignmentExpressionSyntax; this.AnalyzeOwnershipInAssignment(givenUpSymbol, assignment, statement, machine, model, trace); } else if (expr.Expression is InvocationExpressionSyntax || expr.Expression is ObjectCreationExpressionSyntax) { trace.InsertCall(statement.Summary.Method, expr.Expression); this.AnalyzeOwnershipInCall(givenUpSymbol, expr.Expression, statement, machine, model, trace); } } }
/// <summary> /// Analyzes the ownership of the given-up symbol /// in the assignment expression. /// </summary> /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param> /// <param name="assignment">AssignmentExpressionSyntax</param> /// <param name="statement">Statement</param> /// <param name="machine">StateMachine</param> /// <param name="model">SemanticModel</param> /// <param name="trace">TraceInfo</param> protected override void AnalyzeOwnershipInAssignment(GivenUpOwnershipSymbol givenUpSymbol, AssignmentExpressionSyntax assignment, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { var leftIdentifier = base.AnalysisContext.GetRootIdentifier(assignment.Left); ISymbol leftSymbol = model.GetSymbolInfo(leftIdentifier).Symbol; if (assignment.Right is IdentifierNameSyntax) { var rightIdentifier = base.AnalysisContext.GetRootIdentifier(assignment.Right); ISymbol rightSymbol = model.GetSymbolInfo(rightIdentifier).Symbol; if (statement.Summary.DataFlowAnalysis.FlowsIntoSymbol(rightSymbol, givenUpSymbol.ContainingSymbol, statement, givenUpSymbol.Statement)) { var type = model.GetTypeInfo(assignment.Right).Type; if (leftSymbol != null && leftSymbol.Kind == SymbolKind.Field && base.IsFieldAccessedInSuccessor(leftSymbol as IFieldSymbol, statement.Summary, machine) && !base.AnalysisContext.IsTypePassedByValueOrImmutable(type)) { TraceInfo newTrace = new TraceInfo(); newTrace.Merge(trace); newTrace.AddErrorTrace(statement.SyntaxNode); AnalysisErrorReporter.ReportGivenUpOwnershipFieldAssignment(newTrace, leftSymbol); } return; } } else if (assignment.Right is MemberAccessExpressionSyntax) { this.AnalyzeOwnershipInExpression(givenUpSymbol, assignment.Right, statement, machine, model, trace); } else if (assignment.Right is InvocationExpressionSyntax || assignment.Right is ObjectCreationExpressionSyntax) { trace.InsertCall(statement.Summary.Method, assignment.Right); base.AnalyzeOwnershipInCall(givenUpSymbol, assignment.Right, statement, machine, model, trace); } if (assignment.Left is MemberAccessExpressionSyntax) { ISymbol outerLeftMemberSymbol = model.GetSymbolInfo(assignment.Left).Symbol; if (!outerLeftMemberSymbol.Equals(leftSymbol) && statement.Summary.DataFlowAnalysis.FlowsIntoSymbol(givenUpSymbol.ContainingSymbol, leftSymbol, givenUpSymbol.Statement, statement)) { TraceInfo newTrace = new TraceInfo(); newTrace.Merge(trace); newTrace.AddErrorTrace(statement.SyntaxNode); AnalysisErrorReporter.ReportGivenUpOwnershipAccess(newTrace); } } }
/// <summary> /// Analyzes the ownership of the given-up symbol /// in the variable declaration. /// </summary> /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param> /// <param name="varDecl">VariableDeclarationSyntax</param> /// <param name="statement">Statement</param> /// <param name="machine">StateMachine</param> /// <param name="model">SemanticModel</param> /// <param name="trace">TraceInfo</param> protected override void AnalyzeOwnershipInLocalDeclaration(GivenUpOwnershipSymbol givenUpSymbol, VariableDeclarationSyntax varDecl, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { foreach (var variable in varDecl.Variables.Where(v => v.Initializer != null)) { var expr = variable.Initializer.Value; if (expr is IdentifierNameSyntax || expr is MemberAccessExpressionSyntax) { this.AnalyzeOwnershipInExpression(givenUpSymbol, expr, statement, machine, model, trace); } else if (expr is InvocationExpressionSyntax || expr is ObjectCreationExpressionSyntax) { trace.InsertCall(statement.Summary.Method, expr); base.AnalyzeOwnershipInCall(givenUpSymbol, expr, statement, machine, model, trace); } } }
/// <summary> /// Analyzes the ownership of the given-up symbol /// in the expression. /// </summary> /// <param name="givenUpSymbol">GivenUpOwnershipSymbol</param> /// <param name="expr">ExpressionSyntax</param> /// <param name="statement">Statement</param> /// <param name="machine">StateMachine</param> /// <param name="model">SemanticModel</param> /// <param name="trace">TraceInfo</param> private void AnalyzeOwnershipInExpression(GivenUpOwnershipSymbol givenUpSymbol, ExpressionSyntax expr, Statement statement, StateMachine machine, SemanticModel model, TraceInfo trace) { if (expr is IdentifierNameSyntax || expr is MemberAccessExpressionSyntax) { IdentifierNameSyntax rightIdentifier = base.AnalysisContext.GetRootIdentifier(expr); if (rightIdentifier != null) { var rightSymbol = model.GetSymbolInfo(rightIdentifier).Symbol; this.AnalyzeGivingUpFieldOwnership(givenUpSymbol, rightSymbol, statement, machine, trace); } } else if (expr is InvocationExpressionSyntax || expr is ObjectCreationExpressionSyntax) { trace.InsertCall(statement.Summary.Method, expr); HashSet<ISymbol> returnSymbols = base.AnalyzeOwnershipInCall(givenUpSymbol, expr, statement, machine, model, trace); foreach (var returnSymbol in returnSymbols) { this.AnalyzeGivingUpFieldOwnership(givenUpSymbol, returnSymbol, statement, machine, trace); } } }