/// <summary> /// Creates the control-flow graph nodes of the specified method summary. /// </summary> internal static IControlFlowNode Create(ControlFlowGraph cfg, MethodSummary summary) { var entryNode = new ControlFlowNode(cfg, summary); entryNode.Statements.Add(Statement.Create(summary.Method.ParameterList, entryNode, summary)); entryNode.Construct(GetStatements(summary.Method.Body), null, null); return(entryNode); }
/// <summary> /// Creates the control-flow graph nodes of the specified method summary. /// </summary> internal static IDataFlowNode Create(DataFlowGraph dfg, MethodSummary summary) { var entryNode = new DataFlowNode(dfg, summary.ControlFlowGraph.EntryNode, summary); entryNode.Construct(summary.ControlFlowGraph.EntryNode, null, new Dictionary <IControlFlowNode, DataFlowNode>()); return(entryNode); }
/// <summary> /// Resolves the side-effects in the call. /// </summary> private void ResolveSideEffectsInCall(ExpressionSyntax call, MethodSummary calleeSummary, IDataFlowNode node) { var invocation = call as InvocationExpressionSyntax; var objCreation = call as ObjectCreationExpressionSyntax; if (calleeSummary is null || (invocation is null && objCreation is null)) { return; } ArgumentListSyntax argumentList; if (invocation != null) { argumentList = invocation.ArgumentList; } else { argumentList = objCreation.ArgumentList; } var sideEffects = this.ResolveSideEffectsInCall(argumentList, calleeSummary, node); foreach (var sideEffect in sideEffects) { node.DataFlowInfo.KillDefinitions(sideEffect.Key); SymbolDefinition definition = node.DataFlowInfo.GenerateDefinition(sideEffect.Key); DataFlowInfo.AssignTypeToDefinition(sideEffect.Key.Type, definition); node.DataFlowInfo.TaintDefinition(definition, definition); foreach (var symbol in sideEffect.Value) { node.DataFlowInfo.TaintSymbol(symbol, sideEffect.Key); } } for (int index = 0; index < argumentList.Arguments.Count; index++) { if (!calleeSummary.SideEffectsInfo.ParameterAccesses.ContainsKey(index)) { continue; } var argIdentifier = AnalysisContext.GetRootIdentifier( argumentList.Arguments[index].Expression); this.ResolveMethodParameterAccesses(argIdentifier, calleeSummary.SideEffectsInfo.ParameterAccesses[index], node); } foreach (var fieldAccess in calleeSummary.SideEffectsInfo.FieldAccesses) { foreach (var access in fieldAccess.Value) { this.MapFieldAccessInStatement(fieldAccess.Key as IFieldSymbol, access); } } }
/// <summary> /// Maps the callee summary to the call symbol. /// </summary> private static void MapCalleeSummaryToCallSymbol(MethodSummary calleeSummary, ISymbol callSymbol, IDataFlowNode node) { if (!node.MethodSummaryCache.ContainsKey(callSymbol)) { node.MethodSummaryCache.Add(callSymbol, new HashSet <MethodSummary>()); } node.MethodSummaryCache[callSymbol].Add(calleeSummary); }
/// <summary> /// Resolves the gives-up ownership information in the call. /// </summary> private void ResolveGivesUpOwnershipInCall(ISymbol callSymbol, MethodSummary methodSummary, ArgumentListSyntax argumentList, IDataFlowNode node) { foreach (var paramIndex in methodSummary.SideEffectsInfo.GivesUpOwnershipParamIndexes) { var argExpr = argumentList.Arguments[paramIndex].Expression; this.ResolveGivesUpOwnershipInArgument(callSymbol, argExpr, node); } }
/// <summary> /// Initializes a new instance of the <see cref="DataFlowGraph"/> class. /// </summary> internal DataFlowGraph(MethodSummary summary) : base() { this.Summary = summary; this.SemanticModel = summary.SemanticModel; this.EntryNode = DataFlowNode.Create(this, summary); this.MergeEmptyNodes(); }
/// <summary> /// Initializes a new instance of the <see cref="ControlFlowNode"/> class. /// </summary> protected ControlFlowNode(IGraph <IControlFlowNode> cfg, MethodSummary summary) { this.Id = cfg.Nodes.Count; this.Graph = cfg; this.Summary = summary; this.Statements = new List <Statement>(); this.ISuccessors = new HashSet <IControlFlowNode>(); this.IPredecessors = new HashSet <IControlFlowNode>(); cfg.Nodes.Add(this); }
/// <summary> /// Initializes a new instance of the <see cref="MethodSideEffectsInfo"/> class. /// </summary> internal MethodSideEffectsInfo(MethodSummary summary) { this.Summary = summary; this.FieldFlowParamIndexes = new Dictionary <IFieldSymbol, ISet <int> >(); this.FieldAccesses = new Dictionary <IFieldSymbol, ISet <Statement> >(); this.ParameterAccesses = new Dictionary <int, ISet <Statement> >(); this.ReturnedFields = new HashSet <IFieldSymbol>(); this.ReturnedParameters = new HashSet <int>(); this.ReturnTypes = new HashSet <ITypeSymbol>(); this.GivesUpOwnershipParamIndexes = new HashSet <int>(); }
/// <summary> /// Creates the summary of the specified method, using the /// specified parameter types. /// </summary> public static MethodSummary Create(AnalysisContext context, BaseMethodDeclarationSyntax method, IDictionary <int, ISet <ITypeSymbol> > parameterTypes) { if (method.Body is null) { return(null); } var summary = new MethodSummary(context, method, parameterTypes); summary.BuildSummary(); summary.AnalyzeSummary(); return(summary); }
/// <summary> /// Initializes a new instance of the <see cref="DataFlowNode"/> class. /// </summary> internal DataFlowNode(IGraph <IDataFlowNode> dfg, IControlFlowNode cfgNode, MethodSummary summary) { this.Id = dfg.Nodes.Count; this.Graph = dfg; this.ControlFlowNode = cfgNode; this.Summary = summary; this.ISuccessors = new HashSet <IDataFlowNode>(); this.IPredecessors = new HashSet <IDataFlowNode>(); dfg.Nodes.Add(this); this.DataFlowInfo = new DataFlowInfo(this, summary.AnalysisContext); this.MethodSummaryCache = new Dictionary <ISymbol, ISet <MethodSummary> >(); this.GivesUpOwnershipMap = new HashSet <ISymbol>(); }
/// <summary> /// Returns all cached method summaries for the specified call. /// </summary> private static ISet <MethodSummary> ResolveMethodSummaries(ExpressionSyntax call, IDataFlowNode node) { var summaries = new HashSet <MethodSummary>(); var invocation = call as InvocationExpressionSyntax; var objCreation = call as ObjectCreationExpressionSyntax; var callSymbol = node.Summary.SemanticModel.GetSymbolInfo(call).Symbol; if (callSymbol is null || (invocation is null && objCreation is null)) { return(summaries); } if (node.MethodSummaryCache.ContainsKey(callSymbol)) { summaries.UnionWith(node.MethodSummaryCache[callSymbol]); } else if (invocation != null) { var parameterTypes = GetCandidateParameterTypes(invocation.ArgumentList, node); var candidateCalleeDeclarations = ResolveCandidateMethodsAtCallSite(invocation, node); foreach (var candidateCalleeDeclaration in candidateCalleeDeclarations) { var calleeSummary = MethodSummary.Create(node.Summary.AnalysisContext, candidateCalleeDeclaration, parameterTypes); if (calleeSummary != null) { summaries.Add(calleeSummary); } } } else { var parameterTypes = GetCandidateParameterTypes(objCreation.ArgumentList, node); var constructor = ResolveMethodDeclaration(objCreation, node) as ConstructorDeclarationSyntax; if (constructor != null) { var calleeSummary = MethodSummary.Create(node.Summary.AnalysisContext, constructor, parameterTypes); if (calleeSummary != null) { summaries.Add(calleeSummary); } } } return(summaries); }
/// <summary> /// Initializes a new instance of the <see cref="ControlFlowGraph"/> class. /// </summary> internal ControlFlowGraph(MethodSummary summary) : base() { this.EntryNode = ControlFlowNode.Create(this, summary); this.MergeEmptyNodes(); }
/// <summary> /// Creates a new statement. /// </summary> public static Statement Create(SyntaxNode syntaxNode, IControlFlowNode node, MethodSummary summary) { return(new Statement(syntaxNode, node, summary)); }
/// <summary> /// Initializes a new instance of the <see cref="Statement"/> class. /// </summary> private Statement(SyntaxNode syntaxNode, IControlFlowNode node, MethodSummary summary) { this.SyntaxNode = syntaxNode; this.ControlFlowNode = node; this.Summary = summary; }