/// <summary> /// Tries to capture potential return symbols. /// </summary> /// <param name="returnSymbols">Set of return symbols</param> /// <param name="syntaxNode">SyntaxNode</param> /// <param name="cfgNode">ControlFlowGraphNode</param> /// <param name="model">SemanticModel</param> /// <param name="dataFlowMap">DataFlowMap</param> private static void TryCaptureReturnSymbols(HashSet<ISymbol> returnSymbols, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode, SemanticModel model, DataFlowMap dataFlowMap) { Dictionary<ISymbol, HashSet<ISymbol>> map = null; if (returnSymbols == null || !dataFlowMap.TryGetMapForSyntaxNode(syntaxNode, cfgNode, out map)) { return; } Dictionary<ISymbol, int> indexMap = new Dictionary<ISymbol, int>(); var parameterList = cfgNode.Summary.Method.ParameterList.Parameters; for (int idx = 0; idx < parameterList.Count; idx++) { var paramSymbol = model.GetDeclaredSymbol(parameterList[idx]); indexMap.Add(paramSymbol, idx); } foreach (var symbol in returnSymbols) { if (symbol.Kind == SymbolKind.Parameter) { if (dataFlowMap.DoesSymbolReset(symbol, cfgNode.Summary.Node.SyntaxNodes. First(), cfgNode.Summary.Node, syntaxNode, cfgNode, true)) { continue; } cfgNode.Summary.ReturnSet.Item1.Add(indexMap[symbol]); } else if (symbol.Kind == SymbolKind.Field) { cfgNode.Summary.ReturnSet.Item2.Add(symbol as IFieldSymbol); } else if (map.ContainsKey(symbol)) { foreach (var reference in map[symbol].Where(v => v.Kind == SymbolKind.Field)) { cfgNode.Summary.ReturnSet.Item2.Add(reference as IFieldSymbol); } } } }
/// <summary> /// Checks if the data flow analysis reached a fixpoint regarding the given successor. /// </summary> /// <param name="syntaxNode">SyntaxNode</param> /// <param name="cfgNode">ControlFlowGraphNode</param> /// <param name="successorCfgNode">Successor controlFlowGraphNode</param> /// <param name="dataFlowMap">DataFlowMap</param> /// <returns>Boolean</returns> private static bool ReachedFixpoint(SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode, ControlFlowGraphNode successorCfgNode, DataFlowMap dataFlowMap) { Dictionary<ISymbol, HashSet<ISymbol>> currentMap = null; if (!dataFlowMap.TryGetMapForSyntaxNode(syntaxNode, cfgNode, out currentMap)) { return false; } Dictionary<ISymbol, HashSet<ISymbol>> successorMap = null; if (!dataFlowMap.TryGetMapForSyntaxNode(successorCfgNode.SyntaxNodes.First(), successorCfgNode, out successorMap)) { return false; } foreach (var pair in currentMap) { if (!successorMap.ContainsKey(pair.Key) || !successorMap[pair.Key].SetEquals(pair.Value)) { return false; } } return true; }
/// <summary> /// Tries to capture a potential parameter acccess in the given expression. /// </summary> /// <param name="expr">Expression</param> /// <param name="syntaxNode">SyntaxNode</param> /// <param name="cfgNode">ControlFlowGraphNode</param> /// <param name="dataFlowMap">DataFlowMap</param> /// <param name="model">SemanticModel</param> /// <param name="context">AnalysisContext</param> private static void TryCaptureParameterAccess(ExpressionSyntax expr, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode, DataFlowMap dataFlowMap, SemanticModel model, AnalysisContext context) { if (!(expr is MemberAccessExpressionSyntax)) { return; } var name = (expr as MemberAccessExpressionSyntax).Name; var identifier = context.GetFirstNonMachineIdentifier(expr, model); if (identifier == null || name == null) { return; } var type = model.GetTypeInfo(identifier).Type; if (context.IsTypeAllowedToBeSend(type) || context.IsMachineType(type, model) || name.Equals(identifier)) { return; } var symbol = model.GetSymbolInfo(identifier).Symbol; if (symbol == null) { return; } Dictionary<ISymbol, HashSet<ISymbol>> map = null; if (!dataFlowMap.TryGetMapForSyntaxNode(syntaxNode, cfgNode, out map)) { return; } Dictionary<ISymbol, int> indexMap = new Dictionary<ISymbol, int>(); var parameterList = cfgNode.Summary.Method.ParameterList.Parameters; for (int idx = 0; idx < parameterList.Count; idx++) { var paramSymbol = model.GetDeclaredSymbol(parameterList[idx]); indexMap.Add(paramSymbol, idx); } if (map.ContainsKey(symbol)) { foreach (var reference in map[symbol]) { if (reference.Kind == SymbolKind.Parameter) { if (reference.Equals(symbol) && dataFlowMap.DoesSymbolReset( reference, cfgNode.Summary.Node.SyntaxNodes.First(), cfgNode.Summary.Node, syntaxNode, cfgNode, true)) { continue; } int index = indexMap[reference]; if (cfgNode.Summary.AccessSet.ContainsKey(index)) { cfgNode.Summary.AccessSet[index].Add(syntaxNode); } else { cfgNode.Summary.AccessSet.Add(index, new HashSet<SyntaxNode>()); cfgNode.Summary.AccessSet[index].Add(syntaxNode); } } } } }