예제 #1
0
        /// <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);
                    }
                }
            }
        }
예제 #2
0
        /// <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;
        }
예제 #3
0
        /// <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);
                        }
                    }
                }
            }
        }