示例#1
0
 /// <summary>
 /// Returns true if the given expression flows in the target.
 /// </summary>
 /// <param name="variable">Variable</param>
 /// <param name="target">Target</param>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="cfgNode">ControlFlowGraphNode</param>
 /// <param name="targetSyntaxNode">Target syntaxNode</param>
 /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
 /// <param name="model">SemanticModel</param>
 /// <returns>Boolean</returns>
 internal static bool FlowsIntoTarget(VariableDeclaratorSyntax variable, ISymbol target,
     SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode, SyntaxNode targetSyntaxNode,
     ControlFlowGraphNode targetCfgNode, SemanticModel model)
 {
     ISymbol reference = model.GetDeclaredSymbol(variable);
     return DataFlowAnalysis.FlowsIntoTarget(reference, target, syntaxNode,
         cfgNode, targetSyntaxNode, targetCfgNode);
 }
示例#2
0
        /// <summary>
        /// Returns true if the given expression flows in the target.
        /// </summary>
        /// <param name="expr">Expression</param>
        /// <param name="target">Target</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="targetSyntaxNode">Target syntaxNode</param>
        /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean</returns>
        internal static bool FlowsIntoTarget(ExpressionSyntax expr, ISymbol target,
            SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode, SyntaxNode targetSyntaxNode,
            ControlFlowGraphNode targetCfgNode, SemanticModel model, AnalysisContext context)
        {
            ISymbol reference = null;
            if (!context.TryGetSymbolFromExpression(out reference, expr, model))
            {
                return false;
            }

            return DataFlowAnalysis.FlowsIntoTarget(reference, target, syntaxNode,
                cfgNode, targetSyntaxNode, targetCfgNode);
        }
示例#3
0
        /// <summary>
        /// Returns true if the given expression resets when flowing from the
        /// target in the given loop body control flow graph nodes. The given
        /// control flow graph nodes must be equal.
        /// </summary>
        /// <param name="expr">Expression</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="targetSyntaxNode">Target syntaxNode</param>
        /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
        /// <param name="model">SemanticModel</param>
        /// <returns>Boolean value</returns>
        internal static bool DoesResetInLoop(ExpressionSyntax expr, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, SyntaxNode targetSyntaxNode,
            ControlFlowGraphNode targetCfgNode, SemanticModel model)
        {
            ISymbol reference = null;
            if (!cfgNode.Equals(targetCfgNode) ||
                !Utilities.TryGetSymbolFromExpression(out reference, expr, model))
            {
                return false;
            }

            return DataFlowAnalysis.DoesResetInLoop(reference, syntaxNode, cfgNode,
                targetSyntaxNode, targetCfgNode);
        }
        /// <summary>
        /// Handles the given using statement.
        /// </summary>
        /// <param name="stmt">Statement</param>
        /// <param name="successor">Successor</param>
        private void HandleUsingStatement(UsingStatementSyntax stmt, ControlFlowGraphNode successor)
        {
            this.SyntaxNodes.Add(stmt.Declaration);
            this.IsJumpNode = true;

            var usingNode = new ControlFlowGraphNode(this.Summary);

            this.ISuccessors.Add(usingNode);
            usingNode.IPredecessors.Add(this);

            if (stmt.Statement is BlockSyntax)
            {
                usingNode.Construct((stmt.Statement as BlockSyntax).Statements, 0, false, successor);
            }
            else
            {
                usingNode.Construct(new SyntaxList <StatementSyntax> {
                    stmt.Statement
                }, 0, false, successor);
            }
        }
        /// <summary>
        /// Handles the given switch statement.
        /// </summary>
        /// <param name="stmt">Statement</param>
        /// <param name="successor">Successor</param>
        private void HandleSwitchStatement(SwitchStatementSyntax stmt, ControlFlowGraphNode successor)
        {
            this.SyntaxNodes.Add(stmt.Expression);
            this.IsJumpNode = true;

            if (stmt.Sections.Count == 0 &&
                successor != null)
            {
                this.ISuccessors.Add(successor);
                successor.IPredecessors.Add(this);
                return;
            }

            for (int idx = 0; idx < stmt.Sections.Count; idx++)
            {
                var  statements    = stmt.Sections[idx].Statements;
                bool containsBreak = false;
                foreach (var s in statements)
                {
                    if (s is BreakStatementSyntax)
                    {
                        containsBreak = true;
                        break;
                    }
                }

                var switchNode = new ControlFlowGraphNode(this.Summary);
                this.ISuccessors.Add(switchNode);
                switchNode.IPredecessors.Add(this);

                if (containsBreak || idx == stmt.Sections.Count - 1)
                {
                    switchNode.Construct(statements, 0, false, successor);
                }
                else
                {
                    switchNode.Construct(statements, 0, false, null);
                }
            }
        }
示例#6
0
        /// <summary>
        /// Tries to capture a potential field 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 TryCaptureFieldAccess(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;
            var definition = SymbolFinder.FindSourceDefinitionAsync(symbol,
                context.Solution).Result;
            if (!(definition is IFieldSymbol))
            {
                return;
            }
            
            var fieldDecl = definition.DeclaringSyntaxReferences.First().GetSyntax().
                AncestorsAndSelf().OfType<FieldDeclarationSyntax>().First();
            if (dataFlowMap.DoesSymbolReset(symbol, cfgNode.Summary.Node.SyntaxNodes.First(),
                cfgNode.Summary.Node, syntaxNode, cfgNode, true))
            {
                return;
            }

            if (cfgNode.Summary.FieldAccessSet.ContainsKey(symbol as IFieldSymbol))
            {
                cfgNode.Summary.FieldAccessSet[symbol as IFieldSymbol].Add(syntaxNode);
            }
            else
            {
                cfgNode.Summary.FieldAccessSet.Add(symbol as IFieldSymbol, new HashSet<SyntaxNode>());
                cfgNode.Summary.FieldAccessSet[symbol as IFieldSymbol].Add(syntaxNode);
            }
        }
示例#7
0
        /// <summary>
        /// Resolves the object type of the given symbol on the given syntax node.
        /// </summary>
        /// <param name="types">Set of object type symbols</param>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <returns>Boolean</returns>
        private static bool ResolveObjectType(out HashSet<ITypeSymbol> types, ISymbol symbol,
            SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode, DataFlowMap dataFlowMap)
        {
            types = new HashSet<ITypeSymbol>();

            Dictionary<ISymbol, HashSet<ITypeSymbol>> objectTypeMap = null;
            if (!dataFlowMap.TryGetObjectTypeMapForSyntaxNode(syntaxNode, cfgNode,
                out objectTypeMap))
            {
                return false;
            }

            if (!objectTypeMap.ContainsKey(symbol))
            {
                return false;
            }

            types = objectTypeMap[symbol];
            return true;
        }
示例#8
0
        /// <summary>
        /// Checks if the gives up call has a field symbol argument that is not
        /// already mapped and, if yes, maps it.
        /// </summary>
        /// <param name="call">Call</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        private static void CheckForNonMappedFieldSymbol(InvocationExpressionSyntax call,
            ControlFlowGraphNode cfgNode, DataFlowMap dataFlowMap, SemanticModel model,
            AnalysisContext context)
        {
            if (!cfgNode.IsGivesUpNode)
            {
                return;
            }

            List<MemberAccessExpressionSyntax> accesses;
            if (cfgNode.Summary.GivesUpSet.Count == 0 && call.Expression.DescendantNodesAndSelf().
                OfType<IdentifierNameSyntax>().Last().ToString().Equals("Send"))
            {
                accesses = call.ArgumentList.Arguments[1].DescendantNodesAndSelf().
                    OfType<MemberAccessExpressionSyntax>().ToList();
            }
            else
            {
                accesses = call.ArgumentList.DescendantNodesAndSelf().OfType<MemberAccessExpressionSyntax>().ToList();
            }

            foreach (var access in accesses)
            {
                IdentifierNameSyntax id = context.GetFirstNonMachineIdentifier(access, model);
                if (id == null)
                {
                    continue;
                }

                var accessSymbol = model.GetSymbolInfo(id).Symbol;
                dataFlowMap.MapSymbolIfNotExists(accessSymbol, cfgNode.SyntaxNodes[0], cfgNode);
            }
        }
示例#9
0
        /// <summary>
        /// Marks that the symbol has been reassigned a reference.
        /// </summary>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">CfgNode</param>
        private void MarkSymbolReassignment(ISymbol symbol, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
        {
            if (!this.ResetMap.ContainsKey(cfgNode))
            {
                this.ResetMap.Add(cfgNode, new Dictionary<SyntaxNode, HashSet<ISymbol>>());
                this.ResetMap[cfgNode].Add(syntaxNode, new HashSet<ISymbol>());
            }
            else if (!this.ResetMap[cfgNode].ContainsKey(syntaxNode))
            {
                this.ResetMap[cfgNode].Add(syntaxNode, new HashSet<ISymbol>());
            }

            this.ResetMap[cfgNode][syntaxNode].Add(symbol);
        }
示例#10
0
        /// <summary>
        /// Transfers the data flow map from the previous node to the new node.
        /// </summary>
        /// <param name="previousSyntaxNode">Previous syntaxNode</param>
        /// <param name="previousCfgNode">Previous cfgNode</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">CfgNode</param>
        internal void Transfer(SyntaxNode previousSyntaxNode, ControlFlowGraphNode previousCfgNode,
            SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
        {
            if (!this.Map.ContainsKey(cfgNode))
            {
                this.Map.Add(cfgNode, new Dictionary<SyntaxNode, Dictionary<ISymbol, HashSet<ISymbol>>>());
                this.Map[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }
            else if (!this.Map[cfgNode].ContainsKey(syntaxNode))
            {
                this.Map[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }

            Dictionary<ISymbol, HashSet<ISymbol>> previousMap = null;
            if (this.TryGetMapForSyntaxNode(previousSyntaxNode, previousCfgNode, out previousMap))
            {
                foreach (var pair in previousMap)
                {
                    if (!this.Map[cfgNode][syntaxNode].ContainsKey(pair.Key))
                    {
                        this.Map[cfgNode][syntaxNode].Add(pair.Key, new HashSet<ISymbol>());
                    }

                    foreach (var reference in pair.Value)
                    {
                        this.Map[cfgNode][syntaxNode][pair.Key].Add(reference);
                    }
                }
            }

            if (!this.ReachabilityMap.ContainsKey(cfgNode))
            {
                this.ReachabilityMap.Add(cfgNode, new Dictionary<SyntaxNode,
                    Dictionary<ISymbol, HashSet<ISymbol>>>());
                this.ReachabilityMap[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }
            else if (!this.ReachabilityMap[cfgNode].ContainsKey(syntaxNode))
            {
                this.ReachabilityMap[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }

            Dictionary<ISymbol, HashSet<ISymbol>> previousReachabilityMap = null;
            if (this.TryGetReachabilityMapForSyntaxNode(previousSyntaxNode, previousCfgNode,
                out previousReachabilityMap))
            {
                foreach (var pair in previousReachabilityMap)
                {
                    if (!this.ReachabilityMap[cfgNode][syntaxNode].ContainsKey(pair.Key))
                    {
                        this.ReachabilityMap[cfgNode][syntaxNode].Add(pair.Key, new HashSet<ISymbol>());
                    }

                    foreach (var reference in pair.Value)
                    {
                        this.ReachabilityMap[cfgNode][syntaxNode][pair.Key].Add(reference);
                    }
                }
            }

            if (!this.ObjectTypeMap.ContainsKey(cfgNode))
            {
                this.ObjectTypeMap.Add(cfgNode, new Dictionary<SyntaxNode,
                    Dictionary<ISymbol, HashSet<ITypeSymbol>>>());
                this.ObjectTypeMap[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ITypeSymbol>>());
            }
            else if (!this.ObjectTypeMap[cfgNode].ContainsKey(syntaxNode))
            {
                this.ObjectTypeMap[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ITypeSymbol>>());
            }

            Dictionary<ISymbol, HashSet<ITypeSymbol>> previousObjectTypeMap = null;
            if (this.TryGetObjectTypeMapForSyntaxNode(previousSyntaxNode, previousCfgNode,
                out previousObjectTypeMap))
            {
                foreach (var pair in previousObjectTypeMap)
                {
                    if (!this.ObjectTypeMap[cfgNode][syntaxNode].ContainsKey(pair.Key))
                    {
                        this.ObjectTypeMap[cfgNode][syntaxNode].Add(pair.Key, new HashSet<ITypeSymbol>());
                    }

                    foreach (var type in pair.Value)
                    {
                        this.ObjectTypeMap[cfgNode][syntaxNode][pair.Key].Add(type);
                    }
                }
            }
        }
示例#11
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;
        }
示例#12
0
        /// <summary>
        /// Tries to get the list of potential methods that can override the given virtual call.
        /// If it cannot find such methods then it returns false.
        /// </summary>
        /// <param name="overriders">List of overrider methods</param>
        /// <param name="virtualCall">Virtual call</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="originalMachine">Original machine</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean</returns>
        internal static bool TryGetPotentialMethodOverriders(out HashSet<MethodDeclarationSyntax> overriders,
            InvocationExpressionSyntax virtualCall, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode,
            ClassDeclarationSyntax originalMachine, SemanticModel model, AnalysisContext context)
        {
            overriders = new HashSet<MethodDeclarationSyntax>();

            ISymbol calleeSymbol = null;
            SimpleNameSyntax callee = null;
            bool isThis = false;

            if (virtualCall.Expression is MemberAccessExpressionSyntax)
            {
                var expr = virtualCall.Expression as MemberAccessExpressionSyntax;
                var identifier = expr.Expression.DescendantNodesAndSelf().
                    OfType<IdentifierNameSyntax>().Last();
                calleeSymbol = model.GetSymbolInfo(identifier).Symbol;
                
                if (expr.Expression is ThisExpressionSyntax ||
                    context.IsMachineType(identifier, model))
                {
                    callee = expr.Name;
                    isThis = true;
                }
            }
            else
            {
                callee = virtualCall.Expression as IdentifierNameSyntax;
                isThis = true;
            }

            if (isThis)
            {
                foreach (var nestedClass in originalMachine.ChildNodes().OfType<ClassDeclarationSyntax>())
                {
                    foreach (var method in nestedClass.ChildNodes().OfType<MethodDeclarationSyntax>())
                    {
                        if (method.Identifier.ToString().Equals(callee.Identifier.ToString()))
                        {
                            overriders.Add(method);
                            return true;
                        }
                    }
                }

                foreach (var method in originalMachine.ChildNodes().OfType<MethodDeclarationSyntax>())
                {
                    if (method.Identifier.ToString().Equals(callee.Identifier.ToString()))
                    {
                        overriders.Add(method);
                        return true;
                    }
                }

                return false;
            }

            if (calleeSymbol == null)
            {
                return false;
            }

            Dictionary<ISymbol, HashSet<ITypeSymbol>> objectTypeMap = null;
            if (!cfgNode.Summary.DataFlowMap.TryGetObjectTypeMapForSyntaxNode(
                syntaxNode, cfgNode, out objectTypeMap))
            {
                return false;
            }

            if (!objectTypeMap.ContainsKey(calleeSymbol))
            {
                return false;
            }

            foreach (var objectType in objectTypeMap[calleeSymbol])
            {
                MethodDeclarationSyntax m = null;
                if (InheritanceAnalysis.TryGetMethodFromType(out m, objectType, virtualCall, context))
                {
                    overriders.Add(m);
                }
            }

            return true;
        }
 /// <summary>
 /// Returns true if the node is a predecessor of the given node.
 /// Returns false if not.
 /// </summary>
 /// <param name="node">ControlFlowGraphNode</param>
 /// <returns>Boolean value</returns>
 internal bool IsPredecessorOf(ControlFlowGraphNode node)
 {
     return(this.IsPredecessorOf(node, new HashSet <ControlFlowGraphNode>()));
 }
        /// <summary>
        /// Constructs the node from the given list of statements starting
        /// at the given index.
        /// </summary>
        /// <param name="stmtList">List of statements</param>
        /// <param name="index">Index</param>
        /// <param name="isBound">Processes only one statement</param>
        /// <param name="successor">Successor</param>
        internal void Construct(SyntaxList <StatementSyntax> stmtList, int index, bool isBound,
                                ControlFlowGraphNode successor)
        {
            int boundary = stmtList.Count;

            if (isBound && index == stmtList.Count)
            {
                boundary = stmtList.Count;
            }
            else if (isBound)
            {
                boundary = index + 1;
            }

            for (int idx = index; idx < boundary; idx++)
            {
                ControlFlowGraphNode givesUpNode = null;
                ControlFlowGraphNode jumpNode    = null;
                ControlFlowGraphNode succNode    = null;

                if (stmtList[idx] is ExpressionStatementSyntax ||
                    stmtList[idx] is LocalDeclarationStatementSyntax)
                {
                    var invocations = stmtList[idx].DescendantNodesAndSelf().
                                      OfType <InvocationExpressionSyntax>();
                    if (invocations.Count() > 0)
                    {
                        var call = invocations.First();
                        if (this.IsGivesUpOperation(call))
                        {
                            if (this.SyntaxNodes.Count == 0)
                            {
                                givesUpNode = this;
                            }
                            else
                            {
                                givesUpNode = new ControlFlowGraphNode(this.Summary);
                                this.ISuccessors.Add(givesUpNode);
                                givesUpNode.IPredecessors.Add(this);
                            }

                            givesUpNode.IsGivesUpNode = true;
                            this.Summary.GivesUpNodes.Add(givesUpNode);
                            givesUpNode.SyntaxNodes.Add(stmtList[idx]);

                            if (idx < boundary - 1 &&
                                stmtList[idx + 1] is BreakStatementSyntax)
                            {
                                if (successor != null &&
                                    successor.LoopExitNode != null)
                                {
                                    givesUpNode.ISuccessors.Add(successor.LoopExitNode);
                                    successor.LoopExitNode.IPredecessors.Add(givesUpNode);
                                }
                            }
                            else if (idx < boundary - 1 &&
                                     stmtList[idx + 1] is ContinueStatementSyntax)
                            {
                                if (successor != null)
                                {
                                    givesUpNode.ISuccessors.Add(successor);
                                    successor.IPredecessors.Add(givesUpNode);
                                }
                            }
                            else if (idx < boundary - 1)
                            {
                                succNode = new ControlFlowGraphNode(this.Summary);
                                givesUpNode.ISuccessors.Add(succNode);
                                succNode.IPredecessors.Add(givesUpNode);
                                succNode.Construct(stmtList, idx + 1, false, successor);
                            }
                            else if (successor != null)
                            {
                                givesUpNode.ISuccessors.Add(successor);
                                successor.IPredecessors.Add(givesUpNode);
                            }

                            return;
                        }
                    }

                    this.SyntaxNodes.Add(stmtList[idx]);
                    continue;
                }
                else if (stmtList[idx] is BreakStatementSyntax)
                {
                    if (successor != null && successor.LoopExitNode != null)
                    {
                        this.ISuccessors.Add(successor.LoopExitNode);
                        successor.LoopExitNode.IPredecessors.Add(this);
                    }

                    return;
                }
                else if (stmtList[idx] is ContinueStatementSyntax)
                {
                    if (successor != null)
                    {
                        this.ISuccessors.Add(successor);
                        successor.IPredecessors.Add(this);
                    }

                    return;
                }
                else if (stmtList[idx] is ReturnStatementSyntax)
                {
                    this.SyntaxNodes.Add(stmtList[idx]);
                    continue;
                }

                if (this.SyntaxNodes.Count == 0)
                {
                    jumpNode = this;
                }
                else
                {
                    jumpNode = new ControlFlowGraphNode(this.Summary);
                    this.ISuccessors.Add(jumpNode);
                    jumpNode.IPredecessors.Add(this);
                }

                if (stmtList[idx] is IfStatementSyntax)
                {
                    if (idx < boundary - 1)
                    {
                        succNode = new ControlFlowGraphNode(this.Summary);
                        jumpNode.HandleIfStatement(stmtList[idx] as IfStatementSyntax, succNode);
                        succNode.Construct(stmtList, idx + 1, false, successor);
                        return;
                    }
                    else
                    {
                        jumpNode.HandleIfStatement(stmtList[idx] as IfStatementSyntax, successor);
                    }
                }
                else if (stmtList[idx] is ForStatementSyntax)
                {
                    if (idx < boundary - 1)
                    {
                        succNode = new ControlFlowGraphNode(this.Summary);
                        jumpNode.HandleForStatement(stmtList[idx] as ForStatementSyntax, succNode);
                        succNode.Construct(stmtList, idx + 1, false, successor);
                        return;
                    }
                    else
                    {
                        jumpNode.HandleForStatement(stmtList[idx] as ForStatementSyntax, successor);
                    }
                }
                else if (stmtList[idx] is WhileStatementSyntax)
                {
                    if (idx < boundary - 1)
                    {
                        succNode = new ControlFlowGraphNode(this.Summary);
                        jumpNode.HandleWhileStatement(stmtList[idx] as WhileStatementSyntax, succNode);
                        succNode.Construct(stmtList, idx + 1, false, successor);
                        return;
                    }
                    else
                    {
                        jumpNode.HandleWhileStatement(stmtList[idx] as WhileStatementSyntax, successor);
                    }
                }
                else if (stmtList[idx] is DoStatementSyntax)
                {
                    if (idx < boundary - 1)
                    {
                        succNode = new ControlFlowGraphNode(this.Summary);
                        jumpNode.HandleDoStatement(stmtList[idx] as DoStatementSyntax, succNode);
                        succNode.Construct(stmtList, idx + 1, false, successor);
                        return;
                    }
                    else
                    {
                        jumpNode.HandleDoStatement(stmtList[idx] as DoStatementSyntax, successor);
                    }
                }
                else if (stmtList[idx] is ForEachStatementSyntax)
                {
                    if (idx < boundary - 1)
                    {
                        succNode = new ControlFlowGraphNode(this.Summary);
                        jumpNode.HandleForeachStatement(stmtList[idx] as ForEachStatementSyntax, succNode);
                        succNode.Construct(stmtList, idx + 1, false, successor);
                        return;
                    }
                    else
                    {
                        jumpNode.HandleForeachStatement(stmtList[idx] as ForEachStatementSyntax, successor);
                    }
                }
                else if (stmtList[idx] is SwitchStatementSyntax)
                {
                    if (idx < boundary - 1)
                    {
                        succNode = new ControlFlowGraphNode(this.Summary);
                        jumpNode.HandleSwitchStatement(stmtList[idx] as SwitchStatementSyntax, succNode);
                        succNode.Construct(stmtList, idx + 1, false, successor);
                        return;
                    }
                    else
                    {
                        jumpNode.HandleSwitchStatement(stmtList[idx] as SwitchStatementSyntax, successor);
                    }
                }
                else if (stmtList[idx] is TryStatementSyntax)
                {
                    if (idx < boundary - 1)
                    {
                        succNode = new ControlFlowGraphNode(this.Summary);
                        jumpNode.HandleTryStatement(stmtList[idx] as TryStatementSyntax, succNode);
                        succNode.Construct(stmtList, idx + 1, false, successor);
                        return;
                    }
                    else
                    {
                        jumpNode.HandleTryStatement(stmtList[idx] as TryStatementSyntax, successor);
                    }
                }
                else if (stmtList[idx] is UsingStatementSyntax)
                {
                    if (idx < boundary - 1)
                    {
                        succNode = new ControlFlowGraphNode(this.Summary);
                        jumpNode.HandleUsingStatement(stmtList[idx] as UsingStatementSyntax, succNode);
                        succNode.Construct(stmtList, idx + 1, false, successor);
                        return;
                    }
                    else
                    {
                        jumpNode.HandleUsingStatement(stmtList[idx] as UsingStatementSyntax, successor);
                    }
                }
            }

            if (successor != null && (this.IsJumpNode ||
                                      (!this.IsJumpNode && this.ISuccessors.Count == 0)))
            {
                this.ISuccessors.Add(successor);
                successor.IPredecessors.Add(this);
            }

            if (this.SyntaxNodes.Count == 0)
            {
                foreach (var pred in this.IPredecessors)
                {
                    pred.ISuccessors.Remove(this);
                }
            }
        }
示例#15
0
        /// <summary>
        /// Returns true if the given symbol resets in successor
        /// control flow graph nodes.
        /// </summary>
        /// <param name="symbol">Symbol</param>
        /// <param name="target">Target</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
        /// <param name="visited">Already visited cfgNodes</param>
        /// <returns>Boolean</returns>
        private static bool DoesResetInSuccessors(ISymbol symbol, ISymbol target,
            SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode, ControlFlowGraphNode targetCfgNode,
            HashSet<ControlFlowGraphNode> visited, bool track = false)
        {
            visited.Add(targetCfgNode);

            foreach (var node in targetCfgNode.SyntaxNodes)
            {
                if (track)
                {
                    if (targetCfgNode.Summary.DataFlowMap.DoesSymbolReset(symbol,
                        syntaxNode, cfgNode, node, targetCfgNode) &&
                        !DataFlowAnalysis.FlowsIntoTarget(symbol, target, syntaxNode, cfgNode,
                        node, targetCfgNode))
                    {
                        return true;
                    }
                }

                if (node.Equals(syntaxNode))
                {
                    track = true;
                }
            }
            
            if (targetCfgNode.ISuccessors.Count == 0)
            {
                return false;
            }

            List<bool> results = new List<bool>();
            foreach (var successor in targetCfgNode.ISuccessors.Where(v => !visited.Contains(v)))
            {
                results.Add(DataFlowAnalysis.DoesResetInSuccessors(symbol, target,
                    syntaxNode, cfgNode, successor, visited, true));
            }

            if (results.Contains(true))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
示例#16
0
 /// <summary>
 /// Returns true if the given symbol resets in successor
 /// control flow graph nodes.
 /// </summary>
 /// <param name="symbol">Symbol</param>
 /// <param name="target">Target</param>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="cfgNode">ControlFlowGraphNode</param>
 /// <returns>Boolean</returns>
 internal static bool DoesResetInSuccessors(ISymbol symbol, ISymbol target,
     SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
 {
     return DataFlowAnalysis.DoesResetInSuccessors(symbol, target, syntaxNode,
         cfgNode, cfgNode, new HashSet<ControlFlowGraphNode>());
 }
示例#17
0
        /// <summary>
        /// Maps the given set of references to the given symbol.
        /// </summary>
        /// <param name="references">Set of references</param>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">CfgNode</param>
        /// <param name="markReset">Should mark symbol as reset</param>
        internal void MapRefsToSymbol(HashSet <ISymbol> references, ISymbol symbol, SyntaxNode syntaxNode,
                                      ControlFlowGraphNode cfgNode, bool markReset = true)
        {
            if (!this.Map.ContainsKey(cfgNode))
            {
                this.Map.Add(cfgNode, new Dictionary <SyntaxNode, Dictionary <ISymbol, HashSet <ISymbol> > >());
                this.Map[cfgNode].Add(syntaxNode, new Dictionary <ISymbol, HashSet <ISymbol> >());
            }
            else if (!this.Map[cfgNode].ContainsKey(syntaxNode))
            {
                this.Map[cfgNode].Add(syntaxNode, new Dictionary <ISymbol, HashSet <ISymbol> >());
            }

            HashSet <ISymbol> additionalRefs = new HashSet <ISymbol>();

            foreach (var reference in references)
            {
                if (this.Map[cfgNode][syntaxNode].ContainsKey(reference))
                {
                    foreach (var r in this.Map[cfgNode][syntaxNode][reference])
                    {
                        if (!reference.Equals(r))
                        {
                            additionalRefs.Add(r);
                        }
                    }
                }
            }

            if (this.Map[cfgNode][syntaxNode].ContainsKey(symbol) && additionalRefs.Count > 0)
            {
                this.Map[cfgNode][syntaxNode][symbol].Clear();
            }
            else if (additionalRefs.Count > 0)
            {
                this.Map[cfgNode][syntaxNode].Add(symbol, new HashSet <ISymbol>());
            }
            else if (this.Map[cfgNode][syntaxNode].ContainsKey(symbol))
            {
                this.Map[cfgNode][syntaxNode][symbol].Clear();
                foreach (var reference in references)
                {
                    this.Map[cfgNode][syntaxNode][symbol].Add(reference);
                }
            }
            else
            {
                this.Map[cfgNode][syntaxNode].Add(symbol, new HashSet <ISymbol>());
                foreach (var reference in references)
                {
                    this.Map[cfgNode][syntaxNode][symbol].Add(reference);
                }
            }

            foreach (var r in additionalRefs)
            {
                this.Map[cfgNode][syntaxNode][symbol].Add(r);
            }

            if (markReset)
            {
                this.MarkSymbolReassignment(symbol, syntaxNode, cfgNode);
            }
        }
示例#18
0
 /// <summary>
 /// Erases the set of object types from the given symbol.
 /// </summary>
 /// <param name="symbol">Symbol</param>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="cfgNode">CfgNode</param>
 internal void EraseObjectTypesFromSymbol(ISymbol symbol, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
 {
     if (this.ObjectTypeMap.ContainsKey(cfgNode) &&
         this.ObjectTypeMap[cfgNode].ContainsKey(syntaxNode) &&
         this.ObjectTypeMap[cfgNode][syntaxNode].ContainsKey(symbol))
     {
         this.ObjectTypeMap[cfgNode][syntaxNode].Remove(symbol);
     }
 }
示例#19
0
 /// <summary>
 /// Returns true if the given symbol resets until it reaches the
 /// target control flow graph node.
 /// </summary>
 /// <param name="symbol">Symbol</param>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="cfgNode">ControlFlowGraphNode</param>
 /// <param name="targetSyntaxNode">Target syntaxNode</param>
 /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
 /// <param name="track">Tracking</param>
 /// <returns>Boolean value</returns>
 internal bool DoesSymbolReset(ISymbol symbol, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode,
                               SyntaxNode targetSyntaxNode, ControlFlowGraphNode targetCfgNode, bool track = false)
 {
     return(this.DoesSymbolReset(symbol, syntaxNode, cfgNode, targetSyntaxNode,
                                 targetCfgNode, new HashSet <ControlFlowGraphNode>(), track));
 }
示例#20
0
        /// <summary>
        /// Tries to compute the 'gives_up' set of indexes for the given control flow graph node.
        /// If the node does not contain a generic 'gives_up' operation, then it returns false.
        /// </summary>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="summary">MethodSummary</param>
        /// <returns>Boolean value</returns>
        private static bool TryComputeGivesUpSetForGenericControlFlowGraphNode(ControlFlowGraphNode cfgNode,
                                                                               MethodSummary summary)
        {
            var callLocalDecl = cfgNode.SyntaxNodes.First() as LocalDeclarationStatementSyntax;
            var callExpr      = cfgNode.SyntaxNodes.First() as ExpressionStatementSyntax;

            InvocationExpressionSyntax call = null;

            if (callLocalDecl != null)
            {
                call = callLocalDecl.DescendantNodesAndSelf().OfType <InvocationExpressionSyntax>().First();
            }
            else if (callExpr != null)
            {
                call = callExpr.DescendantNodesAndSelf().OfType <InvocationExpressionSyntax>().First();
            }
            else if (call == null || !((call.Expression is MemberAccessExpressionSyntax) ||
                                       (call.Expression is IdentifierNameSyntax)))
            {
                return(false);
            }

            var model = AnalysisContext.Compilation.GetSemanticModel(call.SyntaxTree);

            if (call.Expression is MemberAccessExpressionSyntax)
            {
                var callStmt = call.Expression as MemberAccessExpressionSyntax;
                if (callStmt.Name.Identifier.ValueText.Equals("Send") ||
                    callStmt.Name.Identifier.ValueText.Equals("CreateMachine"))
                {
                    return(false);
                }
            }
            else if (call.Expression is IdentifierNameSyntax)
            {
                var callStmt = call.Expression as IdentifierNameSyntax;
                if (callStmt.Identifier.ValueText.Equals("Send") ||
                    callStmt.Identifier.ValueText.Equals("CreateMachine"))
                {
                    return(false);
                }
            }

            if (call.ArgumentList.Arguments.Count == 0)
            {
                return(false);
            }

            var callSymbol   = model.GetSymbolInfo(call).Symbol;
            var definition   = SymbolFinder.FindSourceDefinitionAsync(callSymbol, ProgramInfo.Solution).Result;
            var calleeMethod = definition.DeclaringSyntaxReferences.First().GetSyntax()
                               as BaseMethodDeclarationSyntax;
            var calleeSummary = MethodSummary.Factory.Summarize(calleeMethod);

            foreach (int idx in calleeSummary.GivesUpSet)
            {
                if (call.ArgumentList.Arguments[idx].Expression is ObjectCreationExpressionSyntax)
                {
                    var objCreation = call.ArgumentList.Arguments[idx].Expression
                                      as ObjectCreationExpressionSyntax;
                    foreach (var arg in objCreation.ArgumentList.Arguments)
                    {
                        MethodSummaryAnalysis.ComputeGivesUpSetForArgument(
                            arg.Expression, cfgNode, summary);
                    }
                }
                else if (call.ArgumentList.Arguments[idx].Expression is BinaryExpressionSyntax &&
                         call.ArgumentList.Arguments[idx].Expression.IsKind(SyntaxKind.AsExpression))
                {
                    var binExpr = call.ArgumentList.Arguments[idx].Expression
                                  as BinaryExpressionSyntax;
                    if ((binExpr.Left is IdentifierNameSyntax) || (binExpr.Left is MemberAccessExpressionSyntax))
                    {
                        MethodSummaryAnalysis.ComputeGivesUpSetForArgument(binExpr.Left,
                                                                           cfgNode, summary);
                    }
                    else if (binExpr.Left is InvocationExpressionSyntax)
                    {
                        var invocation = binExpr.Left as InvocationExpressionSyntax;
                        for (int i = 1; i < invocation.ArgumentList.Arguments.Count; i++)
                        {
                            MethodSummaryAnalysis.ComputeGivesUpSetForArgument(invocation.ArgumentList.
                                                                               Arguments[i].Expression, cfgNode, summary);
                        }
                    }
                }
                else if ((call.ArgumentList.Arguments[idx].Expression is IdentifierNameSyntax) ||
                         (call.ArgumentList.Arguments[idx].Expression is MemberAccessExpressionSyntax))
                {
                    MethodSummaryAnalysis.ComputeGivesUpSetForArgument(call.ArgumentList.
                                                                       Arguments[idx].Expression, cfgNode, summary);
                }
            }

            return(true);
        }
示例#21
0
        /// <summary>
        /// Transfers the data flow map from the previous node to the new node.
        /// </summary>
        /// <param name="previousSyntaxNode">Previous syntaxNode</param>
        /// <param name="previousCfgNode">Previous cfgNode</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">CfgNode</param>
        internal void Transfer(SyntaxNode previousSyntaxNode, ControlFlowGraphNode previousCfgNode,
                               SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
        {
            if (!this.Map.ContainsKey(cfgNode))
            {
                this.Map.Add(cfgNode, new Dictionary <SyntaxNode, Dictionary <ISymbol, HashSet <ISymbol> > >());
                this.Map[cfgNode].Add(syntaxNode, new Dictionary <ISymbol, HashSet <ISymbol> >());
            }
            else if (!this.Map[cfgNode].ContainsKey(syntaxNode))
            {
                this.Map[cfgNode].Add(syntaxNode, new Dictionary <ISymbol, HashSet <ISymbol> >());
            }

            Dictionary <ISymbol, HashSet <ISymbol> > previousMap = null;

            if (this.TryGetMapForSyntaxNode(previousSyntaxNode, previousCfgNode, out previousMap))
            {
                foreach (var pair in previousMap)
                {
                    if (!this.Map[cfgNode][syntaxNode].ContainsKey(pair.Key))
                    {
                        this.Map[cfgNode][syntaxNode].Add(pair.Key, new HashSet <ISymbol>());
                    }

                    foreach (var reference in pair.Value)
                    {
                        this.Map[cfgNode][syntaxNode][pair.Key].Add(reference);
                    }
                }
            }

            if (!this.ReachabilityMap.ContainsKey(cfgNode))
            {
                this.ReachabilityMap.Add(cfgNode, new Dictionary <SyntaxNode,
                                                                  Dictionary <ISymbol, HashSet <ISymbol> > >());
                this.ReachabilityMap[cfgNode].Add(syntaxNode, new Dictionary <ISymbol, HashSet <ISymbol> >());
            }
            else if (!this.ReachabilityMap[cfgNode].ContainsKey(syntaxNode))
            {
                this.ReachabilityMap[cfgNode].Add(syntaxNode, new Dictionary <ISymbol, HashSet <ISymbol> >());
            }

            Dictionary <ISymbol, HashSet <ISymbol> > previousReachabilityMap = null;

            if (this.TryGetReachabilityMapForSyntaxNode(previousSyntaxNode, previousCfgNode,
                                                        out previousReachabilityMap))
            {
                foreach (var pair in previousReachabilityMap)
                {
                    if (!this.ReachabilityMap[cfgNode][syntaxNode].ContainsKey(pair.Key))
                    {
                        this.ReachabilityMap[cfgNode][syntaxNode].Add(pair.Key, new HashSet <ISymbol>());
                    }

                    foreach (var reference in pair.Value)
                    {
                        this.ReachabilityMap[cfgNode][syntaxNode][pair.Key].Add(reference);
                    }
                }
            }

            if (!this.ObjectTypeMap.ContainsKey(cfgNode))
            {
                this.ObjectTypeMap.Add(cfgNode, new Dictionary <SyntaxNode,
                                                                Dictionary <ISymbol, HashSet <ITypeSymbol> > >());
                this.ObjectTypeMap[cfgNode].Add(syntaxNode, new Dictionary <ISymbol, HashSet <ITypeSymbol> >());
            }
            else if (!this.ObjectTypeMap[cfgNode].ContainsKey(syntaxNode))
            {
                this.ObjectTypeMap[cfgNode].Add(syntaxNode, new Dictionary <ISymbol, HashSet <ITypeSymbol> >());
            }

            Dictionary <ISymbol, HashSet <ITypeSymbol> > previousObjectTypeMap = null;

            if (this.TryGetObjectTypeMapForSyntaxNode(previousSyntaxNode, previousCfgNode,
                                                      out previousObjectTypeMap))
            {
                foreach (var pair in previousObjectTypeMap)
                {
                    if (!this.ObjectTypeMap[cfgNode][syntaxNode].ContainsKey(pair.Key))
                    {
                        this.ObjectTypeMap[cfgNode][syntaxNode].Add(pair.Key, new HashSet <ITypeSymbol>());
                    }

                    foreach (var type in pair.Value)
                    {
                        this.ObjectTypeMap[cfgNode][syntaxNode][pair.Key].Add(type);
                    }
                }
            }
        }
示例#22
0
        /// <summary>
        /// Tries to return the reachability map for the given syntax node. Returns false
        /// and a null map, if it cannot find such map.
        /// </summary>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="map">Map</param>
        /// <returns>Boolean value</returns>
        internal bool TryGetReachabilityMapForSyntaxNode(SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, out Dictionary<ISymbol, HashSet<ISymbol>> map)
        {
            if (cfgNode == null || syntaxNode == null)
            {
                map = null;
                return false;
            }

            if (this.ReachabilityMap.ContainsKey(cfgNode))
            {
                if (this.ReachabilityMap[cfgNode].ContainsKey(syntaxNode))
                {
                    map = this.ReachabilityMap[cfgNode][syntaxNode];
                    return true;
                }
                else
                {
                    map = null;
                    return false;
                }
            }
            else
            {
                map = null;
                return false;
            }
        }
示例#23
0
        /// <summary>
        /// Returns true if the given symbol resets until it reaches the
        /// target control flow graph node.
        /// </summary>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="targetSyntaxNode">Target syntaxNode</param>
        /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
        /// <param name="visited">Already visited cfgNodes</param>
        /// <param name="track">Tracking</param>
        /// <returns>Boolean value</returns>
        internal bool DoesSymbolReset(ISymbol symbol, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode,
            SyntaxNode targetSyntaxNode, ControlFlowGraphNode targetCfgNode, HashSet<ControlFlowGraphNode> visited,
            bool track)
        {
            visited.Add(cfgNode);

            bool result = false;
            if (syntaxNode.Equals(targetSyntaxNode) && cfgNode.Equals(targetCfgNode) &&
                !track)
            {
                return result;
            }

            foreach (var node in cfgNode.SyntaxNodes)
            {
                if (track && this.ResetMap.ContainsKey(cfgNode) &&
                    this.ResetMap[cfgNode].ContainsKey(node) &&
                    this.ResetMap[cfgNode][node].Contains(symbol))
                {
                    result = true;
                    break;
                }

                if (!track && node.Equals(syntaxNode))
                {
                    track = true;
                }
            }

            if (!result)
            {
                foreach (var successor in cfgNode.ISuccessors.Where(v => !visited.Contains(v)))
                {
                    if ((successor.Equals(targetCfgNode) ||
                        successor.IsPredecessorOf(targetCfgNode)) &&
                        this.DoesSymbolReset(symbol, successor.SyntaxNodes.First(),
                        successor, targetSyntaxNode, targetCfgNode, visited, true))
                    {
                        result = true;
                        break;
                    }
                }
            }

            return result;
        }
示例#24
0
 /// <summary>
 /// Returns true if the given symbol resets until it reaches the
 /// target control flow graph node.
 /// </summary>
 /// <param name="symbol">Symbol</param>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="cfgNode">ControlFlowGraphNode</param>
 /// <param name="targetSyntaxNode">Target syntaxNode</param>
 /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
 /// <param name="track">Tracking</param>
 /// <returns>Boolean value</returns>
 internal bool DoesSymbolReset(ISymbol symbol, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode,
     SyntaxNode targetSyntaxNode, ControlFlowGraphNode targetCfgNode, bool track = false)
 {
     return this.DoesSymbolReset(symbol, syntaxNode, cfgNode, targetSyntaxNode,
         targetCfgNode, new HashSet<ControlFlowGraphNode>(), track);
 }
示例#25
0
 /// <summary>
 /// Erases the set of object types from the given symbol.
 /// </summary>
 /// <param name="symbol">Symbol</param>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="cfgNode">CfgNode</param>
 internal void EraseObjectTypesFromSymbol(ISymbol symbol, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
 {
     if (this.ObjectTypeMap.ContainsKey(cfgNode) &&
         this.ObjectTypeMap[cfgNode].ContainsKey(syntaxNode) &&
         this.ObjectTypeMap[cfgNode][syntaxNode].ContainsKey(symbol))
     {
         this.ObjectTypeMap[cfgNode][syntaxNode].Remove(symbol);
     }
 }
示例#26
0
        /// <summary>
        /// Resolves the side effects from the given invocation summary.
        /// </summary>
        /// <param name="call">Call</param>
        /// <param name="summary">MethodSummary</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <returns>Set of reachable field symbols</returns>
        private static HashSet<ISymbol> ResolveSideEffectsInCall(InvocationExpressionSyntax call, MethodSummary summary,
            SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode, SemanticModel model, DataFlowMap dataFlowMap)
        {
            if (summary == null)
            {
                return new HashSet<ISymbol>();
            }

            HashSet<ISymbol> reachableFields = new HashSet<ISymbol>();
            var sideEffects = summary.GetResolvedSideEffects(call.ArgumentList, model);
            foreach (var sideEffect in sideEffects)
            {
                dataFlowMap.MapRefsToSymbol(sideEffect.Value, sideEffect.Key, syntaxNode, cfgNode);
                reachableFields.Add(sideEffect.Key);
            }

            foreach (var fieldAccess in summary.FieldAccessSet)
            {
                foreach (var access in fieldAccess.Value)
                {
                    if (cfgNode.Summary.FieldAccessSet.ContainsKey(fieldAccess.Key as IFieldSymbol))
                    {
                        cfgNode.Summary.FieldAccessSet[fieldAccess.Key as IFieldSymbol].Add(access);
                    }
                    else
                    {
                        cfgNode.Summary.FieldAccessSet.Add(fieldAccess.Key as IFieldSymbol, new HashSet<SyntaxNode>());
                        cfgNode.Summary.FieldAccessSet[fieldAccess.Key as IFieldSymbol].Add(access);
                    }
                }
            }

            return reachableFields;
        }
示例#27
0
 /// <summary>
 /// Returns true if there is a map for the given syntax node.
 /// </summary>
 /// <param name="syntaxNode">SyntaxNode</param>
 /// <param name="cfgNode">ControlFlowGraphNode</param>
 /// <returns>Boolean value</returns>
 internal bool ExistsMapForSyntaxNode(SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
 {
     if (this.Map.ContainsKey(cfgNode))
     {
         if (this.Map[cfgNode].ContainsKey(syntaxNode))
         {
             return true;
         }
         else
         {
             return false;
         }
     }
     else
     {
         return false;
     }
 }
示例#28
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);
                        }
                    }
                }
            }
        }
示例#29
0
        /// <summary>
        /// Maps the given set of object types to the given symbol.
        /// </summary>
        /// <param name="types">Set of object types</param>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">CfgNode</param>
        internal void MapObjectTypesToSymbol(HashSet<ITypeSymbol> types, ISymbol symbol,
            SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
        {
            if (!this.ObjectTypeMap.ContainsKey(cfgNode))
            {
                this.ObjectTypeMap.Add(cfgNode, new Dictionary<SyntaxNode,
                    Dictionary<ISymbol, HashSet<ITypeSymbol>>>());
                this.ObjectTypeMap[cfgNode].Add(syntaxNode, new Dictionary<ISymbol,
                    HashSet<ITypeSymbol>>());
            }
            else if (!this.ObjectTypeMap[cfgNode].ContainsKey(syntaxNode))
            {
                this.ObjectTypeMap[cfgNode].Add(syntaxNode, new Dictionary<ISymbol,
                    HashSet<ITypeSymbol>>());
            }

            if (this.ObjectTypeMap[cfgNode][syntaxNode].ContainsKey(symbol))
            {
                this.ObjectTypeMap[cfgNode][syntaxNode][symbol].Clear();
                foreach (var type in types)
                {
                    this.ObjectTypeMap[cfgNode][syntaxNode][symbol].Add(type);
                }
            }
            else
            {
                this.ObjectTypeMap[cfgNode][syntaxNode].Add(symbol, new HashSet<ITypeSymbol>());
                foreach (var type in types)
                {
                    this.ObjectTypeMap[cfgNode][syntaxNode][symbol].Add(type);
                }
            }
        }
示例#30
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);
                    }
                }
            }
        }
示例#31
0
        /// <summary>
        /// Maps the given set of reachable field symbols to the given symbol.
        /// </summary>
        /// <param name="fields">Set of field symbols</param>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">CfgNode</param>
        internal void MapReachableFieldsToSymbol(HashSet<ISymbol> fields, ISymbol symbol,
            SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
        {
            if (!this.ReachabilityMap.ContainsKey(cfgNode))
            {
                this.ReachabilityMap.Add(cfgNode, new Dictionary<SyntaxNode,
                    Dictionary<ISymbol, HashSet<ISymbol>>>());
                this.ReachabilityMap[cfgNode].Add(syntaxNode, new Dictionary<ISymbol,
                    HashSet<ISymbol>>());
            }
            else if (!this.ReachabilityMap[cfgNode].ContainsKey(syntaxNode))
            {
                this.ReachabilityMap[cfgNode].Add(syntaxNode, new Dictionary<ISymbol,
                    HashSet<ISymbol>>());
            }

            if (this.ReachabilityMap[cfgNode][syntaxNode].ContainsKey(symbol))
            {
                this.ReachabilityMap[cfgNode][syntaxNode][symbol].Clear();
                foreach (var reference in fields)
                {
                    this.ReachabilityMap[cfgNode][syntaxNode][symbol].Add(reference);
                }
            }
            else
            {
                this.ReachabilityMap[cfgNode][syntaxNode].Add(symbol, new HashSet<ISymbol>());
                foreach (var reference in fields)
                {
                    this.ReachabilityMap[cfgNode][syntaxNode][symbol].Add(reference);
                }
            }
        }
示例#32
0
        /// <summary>
        /// Returns true if the given symbol resets when flowing from the
        /// target in the given loop body control flow graph nodes. The
        /// given control flow graph nodes must be equal.
        /// </summary>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="targetSyntaxNode">Target syntaxNode</param>
        /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
        /// <returns>Boolean</returns>
        internal static bool DoesResetInLoop(ISymbol symbol, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, SyntaxNode targetSyntaxNode,
            ControlFlowGraphNode targetCfgNode)
        {
            if (cfgNode.ISuccessors.Count == 0)
            {
                return false;
            }

            var successor = cfgNode.ISuccessors.First();
            while (!successor.IsLoopHeadNode)
            {
                if (!successor.IsLoopHeadNode &&
                    successor.ISuccessors.Count == 0)
                {
                    return false;
                }
                else
                {
                    successor = successor.ISuccessors.First();
                }
            }

            var backwards = cfgNode.Summary.DataFlowMap.DoesSymbolReset(symbol,
                syntaxNode, cfgNode, successor.SyntaxNodes.First(), successor);
            var forwards = cfgNode.Summary.DataFlowMap.DoesSymbolReset(symbol,
                successor.SyntaxNodes.First(), successor, syntaxNode, cfgNode);

            return backwards || forwards;
        }
示例#33
0
        /// <summary>
        /// Maps the given reference to the given symbol.
        /// </summary>
        /// <param name="reference">Reference</param>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">CfgNode</param>
        /// <param name="markReset">Should mark symbol as reset</param>
        internal void MapRefToSymbol(ISymbol reference, ISymbol symbol, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, bool markReset = true)
        {
            if (!this.Map.ContainsKey(cfgNode))
            {
                this.Map.Add(cfgNode, new Dictionary<SyntaxNode, Dictionary<ISymbol, HashSet<ISymbol>>>());
                this.Map[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }
            else if (!this.Map[cfgNode].ContainsKey(syntaxNode))
            {
                this.Map[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }

            HashSet<ISymbol> additionalRefs = new HashSet<ISymbol>();
            if (this.Map[cfgNode][syntaxNode].ContainsKey(reference))
            {
                foreach (var r in this.Map[cfgNode][syntaxNode][reference])
                {
                    if (!reference.Equals(r))
                    {
                        additionalRefs.Add(r);
                    }
                }
            }

            if (this.Map[cfgNode][syntaxNode].ContainsKey(symbol) && additionalRefs.Count > 0)
            {
                this.Map[cfgNode][syntaxNode][symbol] = new HashSet<ISymbol>();
            }
            else if (additionalRefs.Count > 0)
            {
                this.Map[cfgNode][syntaxNode].Add(symbol, new HashSet<ISymbol>());
            }
            else if (this.Map[cfgNode][syntaxNode].ContainsKey(symbol))
            {
                this.Map[cfgNode][syntaxNode][symbol] = new HashSet<ISymbol> { reference };
            }
            else
            {
                this.Map[cfgNode][syntaxNode].Add(symbol, new HashSet<ISymbol> { reference });
            }

            foreach (var r in additionalRefs)
            {
                this.Map[cfgNode][syntaxNode][symbol].Add(r);
            }

            if (markReset)
            {
                this.MarkSymbolReassignment(symbol, syntaxNode, cfgNode);
            }
        }
示例#34
0
        /// <summary>
        /// Returns all possible aliases of the given symbol.
        /// </summary>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <returns>Set of aliases</returns>
        internal static HashSet<ISymbol> GetAliases(ISymbol symbol, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode)
        {
            HashSet<ISymbol> aliases = new HashSet<ISymbol>();

            Dictionary<ISymbol, HashSet<ISymbol>> dataFlowMap = null;
            if (!cfgNode.Summary.DataFlowMap.TryGetMapForSyntaxNode(syntaxNode,
                cfgNode, out dataFlowMap) || !dataFlowMap.ContainsKey(symbol))
            {
                return aliases;
            }

            foreach (var reference in dataFlowMap[symbol].Where(v => !v.Equals(symbol)))
            {
                aliases.Add(reference);
            }

            return aliases;
        }
示例#35
0
        /// <summary>
        /// Maps the given symbol if its not already mapped.
        /// </summary>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">CfgNode</param>
        internal void MapSymbolIfNotExists(ISymbol symbol, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
        {
            if (!this.Map.ContainsKey(cfgNode))
            {
                this.Map.Add(cfgNode, new Dictionary<SyntaxNode, Dictionary<ISymbol, HashSet<ISymbol>>>());
                this.Map[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }
            else if (!this.Map[cfgNode].ContainsKey(syntaxNode))
            {
                this.Map[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }

            if (!this.Map[cfgNode][syntaxNode].ContainsKey(symbol))
            {
                this.Map[cfgNode][syntaxNode][symbol] = new HashSet<ISymbol> { symbol };
            }
        }
示例#36
0
        /// <summary>
        /// Performs data flow analysis on the given control flow graph node.
        /// </summary>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="previousCfgNode">Previous controlFlowGraphNode</param>
        /// <param name="previousSyntaxNode">Previous syntaxNode</param>
        /// <param name="dataFlowMap">DataFlowMap</param>
        /// <param name="model">SemanticModel</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>Boolean</returns>
        private static void AnalyseControlFlowGraphNode(ControlFlowGraphNode cfgNode, ControlFlowGraphNode previousCfgNode,
            SyntaxNode previousSyntaxNode, DataFlowMap dataFlowMap, SemanticModel model, AnalysisContext context)
        {
            if (!cfgNode.IsJumpNode && !cfgNode.IsLoopHeadNode)
            {
                foreach (var syntaxNode in cfgNode.SyntaxNodes)
                {
                    dataFlowMap.Transfer(previousSyntaxNode, previousCfgNode, syntaxNode, cfgNode);

                    var stmt = syntaxNode as StatementSyntax;
                    var localDecl = stmt.DescendantNodesAndSelf().OfType<LocalDeclarationStatementSyntax>().FirstOrDefault();
                    var expr = stmt.DescendantNodesAndSelf().OfType<ExpressionStatementSyntax>().FirstOrDefault();
                    var ret = stmt.DescendantNodesAndSelf().OfType<ReturnStatementSyntax>().FirstOrDefault();

                    if (localDecl != null)
                    {
                        var varDecl = (stmt as LocalDeclarationStatementSyntax).Declaration;
                        foreach (var variable in varDecl.Variables)
                        {
                            if (variable.Initializer == null)
                            {
                                continue;
                            }

                            DataFlowAnalysis.TryCaptureParameterAccess(variable.Initializer.Value,
                                syntaxNode, cfgNode, dataFlowMap, model, context);
                            DataFlowAnalysis.TryCaptureFieldAccess(variable.Initializer.Value,
                                syntaxNode, cfgNode, dataFlowMap, model, context);

                            ITypeSymbol declType = null;
                            if (variable.Initializer.Value is LiteralExpressionSyntax &&
                                variable.Initializer.Value.IsKind(SyntaxKind.NullLiteralExpression))
                            {
                                declType = model.GetTypeInfo(varDecl.Type).Type;
                            }
                            else
                            {
                                declType = model.GetTypeInfo(variable.Initializer.Value).Type;
                            }

                            if (context.IsTypeAllowedToBeSend(declType) ||
                                context.IsMachineType(declType, model))
                            {
                                continue;
                            }

                            var declSymbol = model.GetDeclaredSymbol(variable);

                            if (variable.Initializer.Value is IdentifierNameSyntax ||
                                variable.Initializer.Value is MemberAccessExpressionSyntax)
                            {
                                ISymbol varSymbol = null;
                                if (variable.Initializer.Value is IdentifierNameSyntax)
                                {
                                    varSymbol = model.GetSymbolInfo(variable.Initializer.Value
                                        as IdentifierNameSyntax).Symbol;
                                }
                                else if (variable.Initializer.Value is MemberAccessExpressionSyntax)
                                {
                                    varSymbol = model.GetSymbolInfo((variable.Initializer.Value
                                        as MemberAccessExpressionSyntax).Name).Symbol;
                                }

                                dataFlowMap.MapRefToSymbol(varSymbol, declSymbol, syntaxNode, cfgNode);

                                HashSet<ITypeSymbol> objectTypes = null;
                                if (DataFlowAnalysis.ResolveObjectType(out objectTypes, varSymbol, syntaxNode,
                                    cfgNode, dataFlowMap))
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(objectTypes, declSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (variable.Initializer.Value is LiteralExpressionSyntax &&
                                variable.Initializer.Value.IsKind(SyntaxKind.NullLiteralExpression))
                            {
                                dataFlowMap.ResetSymbol(declSymbol, syntaxNode, cfgNode);
                            }
                            else if (variable.Initializer.Value is InvocationExpressionSyntax)
                            {
                                var invocation = variable.Initializer.Value as InvocationExpressionSyntax;
                                var summary = MethodSummary.TryGetSummary(invocation, model, context);
                                var reachableSymbols = DataFlowAnalysis.ResolveSideEffectsInCall(invocation,
                                    summary, syntaxNode, cfgNode, model, dataFlowMap);
                                var returnSymbols = DataFlowAnalysis.GetReturnSymbols(invocation, summary, model);

                                if (returnSymbols.Count == 0)
                                {
                                    dataFlowMap.ResetSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                                else if (returnSymbols.Contains(declSymbol))
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, declSymbol, syntaxNode, cfgNode, false);
                                }
                                else
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, declSymbol, syntaxNode, cfgNode);
                                }

                                if (reachableSymbols.Count > 0)
                                {
                                    dataFlowMap.MapReachableFieldsToSymbol(reachableSymbols, declSymbol,
                                        syntaxNode, cfgNode);
                                }

                                if (summary != null && summary.ReturnTypeSet.Count > 0)
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(summary.ReturnTypeSet,
                                        declSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (variable.Initializer.Value is ObjectCreationExpressionSyntax)
                            {
                                var objCreation = variable.Initializer.Value as ObjectCreationExpressionSyntax;
                                var summary = MethodSummary.TryGetSummary(objCreation, model, context);
                                var reachableSymbols = DataFlowAnalysis.ResolveSideEffectsInCall(objCreation,
                                    summary, syntaxNode, cfgNode, model, dataFlowMap);
                                var returnSymbols = DataFlowAnalysis.GetReturnSymbols(objCreation, summary, model);

                                if (returnSymbols.Count == 0)
                                {
                                    dataFlowMap.ResetSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                                else if (returnSymbols.Contains(declSymbol))
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, declSymbol, syntaxNode, cfgNode, false);
                                }
                                else
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, declSymbol, syntaxNode, cfgNode);
                                }

                                if (reachableSymbols.Count > 0)
                                {
                                    dataFlowMap.MapReachableFieldsToSymbol(reachableSymbols, declSymbol,
                                        syntaxNode, cfgNode);
                                }

                                var typeSymbol = model.GetSymbolInfo(objCreation.Type).Symbol as ITypeSymbol;
                                if (typeSymbol != null)
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(new HashSet<ITypeSymbol> { typeSymbol },
                                        declSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(declSymbol, syntaxNode, cfgNode);
                                }
                            }
                        }
                    }
                    else if (expr != null)
                    {
                        if (expr.Expression is BinaryExpressionSyntax)
                        {
                            var binaryExpr = expr.Expression as BinaryExpressionSyntax;

                            DataFlowAnalysis.TryCaptureParameterAccess(binaryExpr.Left,
                                syntaxNode, cfgNode, dataFlowMap, model, context);
                            DataFlowAnalysis.TryCaptureParameterAccess(binaryExpr.Right,
                                syntaxNode, cfgNode, dataFlowMap, model, context);
                            DataFlowAnalysis.TryCaptureFieldAccess(binaryExpr.Left,
                                syntaxNode, cfgNode, dataFlowMap, model, context);
                            DataFlowAnalysis.TryCaptureFieldAccess(binaryExpr.Right,
                                syntaxNode, cfgNode, dataFlowMap, model, context);

                            IdentifierNameSyntax lhs = null;
                            ISymbol lhsFieldSymbol = null;
                            if (binaryExpr.Left is IdentifierNameSyntax)
                            {
                                lhs = binaryExpr.Left as IdentifierNameSyntax;
                                var lhsType = model.GetTypeInfo(lhs).Type;
                                if (context.IsTypeAllowedToBeSend(lhsType) ||
                                    context.IsMachineType(lhsType, model))
                                {
                                    previousSyntaxNode = syntaxNode;
                                    previousCfgNode = cfgNode;
                                    continue;
                                }
                            }
                            else if (binaryExpr.Left is MemberAccessExpressionSyntax)
                            {
                                var name = (binaryExpr.Left as MemberAccessExpressionSyntax).Name;
                                var lhsType = model.GetTypeInfo(name).Type;
                                if (context.IsTypeAllowedToBeSend(lhsType) ||
                                    context.IsMachineType(lhsType, model))
                                {
                                    previousSyntaxNode = syntaxNode;
                                    previousCfgNode = cfgNode;
                                    continue;
                                }

                                lhs = context.GetFirstNonMachineIdentifier(binaryExpr.Left, model);
                                lhsFieldSymbol = model.GetSymbolInfo(name as IdentifierNameSyntax).Symbol;
                            }
                            else if (binaryExpr.Left is ElementAccessExpressionSyntax)
                            {
                                var memberAccess = (binaryExpr.Left as ElementAccessExpressionSyntax);
                                if (memberAccess.Expression is IdentifierNameSyntax)
                                {
                                    lhs = memberAccess.Expression as IdentifierNameSyntax;
                                    var lhsType = model.GetTypeInfo(lhs).Type;
                                    if (context.IsTypeAllowedToBeSend(lhsType) ||
                                        context.IsMachineType(lhsType, model))
                                    {
                                        previousSyntaxNode = syntaxNode;
                                        previousCfgNode = cfgNode;
                                        continue;
                                    }
                                }
                                else if (memberAccess.Expression is MemberAccessExpressionSyntax)
                                {
                                    var name = (memberAccess.Expression as MemberAccessExpressionSyntax).Name;
                                    var lhsType = model.GetTypeInfo(name).Type;
                                    if (context.IsTypeAllowedToBeSend(lhsType) ||
                                        context.IsMachineType(lhsType, model))
                                    {
                                        previousSyntaxNode = syntaxNode;
                                        previousCfgNode = cfgNode;
                                        continue;
                                    }

                                    lhs = context.GetFirstNonMachineIdentifier(memberAccess.Expression, model);
                                    lhsFieldSymbol = model.GetSymbolInfo(name as IdentifierNameSyntax).Symbol;
                                }
                            }

                            var leftSymbol = model.GetSymbolInfo(lhs).Symbol;

                            if (binaryExpr.Right is IdentifierNameSyntax ||
                                binaryExpr.Right is MemberAccessExpressionSyntax)
                            {
                                IdentifierNameSyntax rhs = null;
                                if (binaryExpr.Right is IdentifierNameSyntax)
                                {
                                    rhs = binaryExpr.Right as IdentifierNameSyntax;
                                }
                                else if (binaryExpr.Right is MemberAccessExpressionSyntax)
                                {
                                    rhs = context.GetFirstNonMachineIdentifier(binaryExpr.Right, model);
                                }

                                var rightSymbol = model.GetSymbolInfo(rhs).Symbol;
                                dataFlowMap.MapRefToSymbol(rightSymbol, leftSymbol, syntaxNode, cfgNode);
                                if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                {
                                    dataFlowMap.MapRefToSymbol(rightSymbol, lhsFieldSymbol, syntaxNode, cfgNode);
                                }

                                HashSet<ITypeSymbol> objectTypes = null;
                                if (DataFlowAnalysis.ResolveObjectType(out objectTypes, rightSymbol, syntaxNode,
                                    cfgNode, dataFlowMap))
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(objectTypes, leftSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(leftSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (binaryExpr.Right is LiteralExpressionSyntax &&
                                binaryExpr.Right.IsKind(SyntaxKind.NullLiteralExpression))
                            {
                                dataFlowMap.ResetSymbol(leftSymbol, syntaxNode, cfgNode);
                                if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                {
                                    dataFlowMap.ResetSymbol(lhsFieldSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (binaryExpr.Right is InvocationExpressionSyntax)
                            {
                                var invocation = binaryExpr.Right as InvocationExpressionSyntax;
                                var summary = MethodSummary.TryGetSummary(invocation, model, context);
                                var reachableSymbols = DataFlowAnalysis.ResolveSideEffectsInCall(invocation,
                                    summary, syntaxNode, cfgNode, model, dataFlowMap);
                                var returnSymbols = DataFlowAnalysis.GetReturnSymbols(invocation,
                                    summary, model);
                                DataFlowAnalysis.CheckForNonMappedFieldSymbol(invocation, cfgNode,
                                    dataFlowMap, model, context);

                                if (returnSymbols.Count == 0)
                                {
                                    dataFlowMap.ResetSymbol(leftSymbol, syntaxNode, cfgNode);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.ResetSymbol(lhsFieldSymbol, syntaxNode, cfgNode);
                                    }
                                }
                                else if (returnSymbols.Contains(leftSymbol))
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, leftSymbol, syntaxNode, cfgNode, false);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.MapRefsToSymbol(returnSymbols, lhsFieldSymbol,
                                            syntaxNode, cfgNode, false);
                                    }
                                }
                                else
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, leftSymbol, syntaxNode, cfgNode);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.MapRefsToSymbol(returnSymbols, lhsFieldSymbol,
                                            syntaxNode, cfgNode);
                                    }
                                }

                                if (lhsFieldSymbol != null && reachableSymbols.Count > 0)
                                {
                                    dataFlowMap.MapReachableFieldsToSymbol(reachableSymbols, lhsFieldSymbol,
                                        syntaxNode, cfgNode);
                                }

                                if (summary != null && summary.ReturnTypeSet.Count > 0)
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(summary.ReturnTypeSet,
                                        leftSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(leftSymbol, syntaxNode, cfgNode);
                                }
                            }
                            else if (binaryExpr.Right is ObjectCreationExpressionSyntax)
                            {
                                var objCreation = binaryExpr.Right as ObjectCreationExpressionSyntax;
                                var summary = MethodSummary.TryGetSummary(objCreation, model, context);
                                var reachableSymbols = DataFlowAnalysis.ResolveSideEffectsInCall(objCreation,
                                    summary, syntaxNode, cfgNode, model, dataFlowMap);
                                var returnSymbols = DataFlowAnalysis.GetReturnSymbols(objCreation, summary, model);

                                if (returnSymbols.Count == 0)
                                {
                                    dataFlowMap.ResetSymbol(leftSymbol, syntaxNode, cfgNode);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.ResetSymbol(lhsFieldSymbol, syntaxNode, cfgNode);
                                    }
                                }
                                else if (returnSymbols.Contains(leftSymbol))
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, leftSymbol, syntaxNode, cfgNode, false);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.MapRefsToSymbol(returnSymbols, lhsFieldSymbol,
                                            syntaxNode, cfgNode, false);
                                    }
                                }
                                else
                                {
                                    dataFlowMap.MapRefsToSymbol(returnSymbols, leftSymbol, syntaxNode, cfgNode);
                                    if (lhsFieldSymbol != null && !lhsFieldSymbol.Equals(leftSymbol))
                                    {
                                        dataFlowMap.MapRefsToSymbol(returnSymbols, lhsFieldSymbol,
                                            syntaxNode, cfgNode);
                                    }
                                }

                                if (lhsFieldSymbol != null && reachableSymbols.Count > 0)
                                {
                                    dataFlowMap.MapReachableFieldsToSymbol(reachableSymbols, lhsFieldSymbol,
                                        syntaxNode, cfgNode);
                                }

                                var typeSymbol = model.GetSymbolInfo(objCreation.Type).Symbol as ITypeSymbol;
                                if (typeSymbol != null)
                                {
                                    dataFlowMap.MapObjectTypesToSymbol(new HashSet<ITypeSymbol> { typeSymbol },
                                        leftSymbol, syntaxNode, cfgNode);
                                }
                                else
                                {
                                    dataFlowMap.EraseObjectTypesFromSymbol(leftSymbol, syntaxNode, cfgNode);
                                }
                            }
                        }
                        else if (expr.Expression is InvocationExpressionSyntax)
                        {
                            var invocation = expr.Expression as InvocationExpressionSyntax;
                            var summary = MethodSummary.TryGetSummary(invocation, model, context);
                            DataFlowAnalysis.ResolveSideEffectsInCall(invocation, summary,
                                syntaxNode, cfgNode, model, dataFlowMap);
                            DataFlowAnalysis.GetReturnSymbols(invocation, summary, model);
                            DataFlowAnalysis.CheckForNonMappedFieldSymbol(invocation, cfgNode,
                                dataFlowMap, model, context);
                        }
                    }
                    else if (ret != null)
                    {
                        HashSet<ISymbol> returnSymbols = null;
                        if (ret.Expression is IdentifierNameSyntax ||
                            ret.Expression is MemberAccessExpressionSyntax)
                        {
                            IdentifierNameSyntax rhs = null;
                            if (ret.Expression is IdentifierNameSyntax)
                            {
                                rhs = ret.Expression as IdentifierNameSyntax;
                            }
                            else if (ret.Expression is MemberAccessExpressionSyntax)
                            {
                                rhs = context.GetFirstNonMachineIdentifier(ret.Expression, model);
                            }

                            var rightSymbol = model.GetSymbolInfo(rhs).Symbol;
                            returnSymbols = new HashSet<ISymbol> { rightSymbol };

                            HashSet<ITypeSymbol> objectTypes = null;
                            if (DataFlowAnalysis.ResolveObjectType(out objectTypes, rightSymbol,
                                syntaxNode, cfgNode, dataFlowMap))
                            {
                                foreach (var objectType in objectTypes)
                                {
                                    cfgNode.Summary.ReturnTypeSet.Add(objectType);
                                }
                            }
                        }
                        else if (ret.Expression is InvocationExpressionSyntax)
                        {
                            var invocation = ret.Expression as InvocationExpressionSyntax;
                            var summary = MethodSummary.TryGetSummary(invocation, model, context);
                            DataFlowAnalysis.ResolveSideEffectsInCall(invocation, summary,
                                syntaxNode, cfgNode, model, dataFlowMap);
                            returnSymbols = DataFlowAnalysis.GetReturnSymbols(invocation, summary, model);

                            if (summary != null)
                            {
                                foreach (var objectType in summary.ReturnTypeSet)
                                {
                                    cfgNode.Summary.ReturnTypeSet.Add(objectType);
                                }
                            }
                        }
                        else if (ret.Expression is ObjectCreationExpressionSyntax)
                        {
                            var objCreation = ret.Expression as ObjectCreationExpressionSyntax;
                            var summary = MethodSummary.TryGetSummary(objCreation, model, context);
                            DataFlowAnalysis.ResolveSideEffectsInCall(objCreation, summary,
                                syntaxNode, cfgNode, model, dataFlowMap);
                            returnSymbols = DataFlowAnalysis.GetReturnSymbols(objCreation, summary, model);

                            var objectType = model.GetSymbolInfo(objCreation.Type).Symbol as ITypeSymbol;
                            if (objectType != null)
                            {
                                cfgNode.Summary.ReturnTypeSet.Add(objectType);
                            }
                        }

                        DataFlowAnalysis.TryCaptureReturnSymbols(returnSymbols, syntaxNode,
                            cfgNode, model, dataFlowMap);
                    }

                    previousSyntaxNode = syntaxNode;
                    previousCfgNode = cfgNode;
                }
            }
            else
            {
                dataFlowMap.Transfer(previousSyntaxNode, previousCfgNode, cfgNode.SyntaxNodes[0], cfgNode);
                previousSyntaxNode = cfgNode.SyntaxNodes[0];
                previousCfgNode = cfgNode;
            }

            foreach (var successor in cfgNode.ISuccessors)
            {
                if (DataFlowAnalysis.ReachedFixpoint(previousSyntaxNode, cfgNode, successor, dataFlowMap))
                {
                    continue;
                }

                DataFlowAnalysis.AnalyseControlFlowGraphNode(successor, cfgNode,
                    previousSyntaxNode, dataFlowMap, model, context);
            }
        }
示例#37
0
 /// <summary>
 /// Prints the data flow map of the given syntax node.
 /// </summary>
 internal void Print(ControlFlowGraphNode cfgNode)
 {
     Output.Print("\nPrinting data flow map of cfgNode {0}: ", cfgNode.Id);
     if (this.Map.ContainsKey(cfgNode))
     {
         foreach (var syntaxNode in this.Map[cfgNode])
         {
             Output.Print("    > syntaxNode: " + syntaxNode.Key);
             foreach (var pair in syntaxNode.Value)
             {
                 foreach (var symbol in pair.Value)
                 {
                     Output.Print("        " + pair.Key.Name + " ::= " + symbol.Name);
                 }
             }
         }
     }
 }
示例#38
0
        /// <summary>
        /// Returns true if the given symbol flows into the target symbol.
        /// </summary>
        /// <param name="symbol">Symbol</param>
        /// <param name="target">Target</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="targetSyntaxNode">Target syntaxNode</param>
        /// <param name="targetCfgNode">Target controlFlowGraphNode</param>
        /// <returns>Boolean</returns>
        internal static bool FlowsIntoTarget(ISymbol symbol, ISymbol target, SyntaxNode syntaxNode,
            ControlFlowGraphNode cfgNode, SyntaxNode targetSyntaxNode, ControlFlowGraphNode targetCfgNode)
        {
            Dictionary<ISymbol, HashSet<ISymbol>> dataFlowMap = null;
            if (!targetCfgNode.Summary.DataFlowMap.TryGetMapForSyntaxNode(targetSyntaxNode,
                targetCfgNode, out dataFlowMap) || !dataFlowMap.ContainsKey(symbol))
            {
                return false;
            }

            if (symbol.Equals(target) && cfgNode.Summary.DataFlowMap.DoesSymbolReset(
                symbol, syntaxNode, cfgNode, targetSyntaxNode, targetCfgNode))
            {
                return false;
            }

            Dictionary<ISymbol, HashSet<ISymbol>> reachabilityMap = null;
            if (targetCfgNode.Summary.DataFlowMap.TryGetReachabilityMapForSyntaxNode(targetSyntaxNode,
                targetCfgNode, out reachabilityMap) && reachabilityMap.ContainsKey(symbol))
            {
                foreach (var field in reachabilityMap[symbol])
                {
                    foreach (var reference in dataFlowMap[field])
                    {
                        dataFlowMap[symbol].Add(reference);
                    }
                }
            }

            foreach (var reference in dataFlowMap[symbol])
            {
                if (reference.Equals(target))
                {
                    return true;
                }
            }

            if (dataFlowMap.ContainsKey(target))
            {
                foreach (var reference in dataFlowMap[target])
                {
                    if (!cfgNode.Summary.DataFlowMap.DoesSymbolReset(symbol, syntaxNode,
                        cfgNode, targetSyntaxNode, targetCfgNode))
                    {
                        if (reference.Equals(symbol))
                        {
                            return true;
                        }

                        foreach (var symbolRef in dataFlowMap[symbol])
                        {
                            if (reference.Equals(symbolRef))
                            {
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }
示例#39
0
        /// <summary>
        /// Resets the references of the given symbol.
        /// </summary>
        /// <param name="symbol">Symbol</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">CfgNode</param>
        internal void ResetSymbol(ISymbol symbol, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode)
        {
            if (!this.Map.ContainsKey(cfgNode))
            {
                this.Map.Add(cfgNode, new Dictionary<SyntaxNode, Dictionary<ISymbol, HashSet<ISymbol>>>());
                this.Map[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }
            else if (!this.Map[cfgNode].ContainsKey(syntaxNode))
            {
                this.Map[cfgNode].Add(syntaxNode, new Dictionary<ISymbol, HashSet<ISymbol>>());
            }

            if (this.Map[cfgNode][syntaxNode].ContainsKey(symbol))
            {
                this.Map[cfgNode][syntaxNode][symbol] = new HashSet<ISymbol> { symbol };
            }
            else
            {
                this.Map[cfgNode][syntaxNode].Add(symbol, new HashSet<ISymbol> { symbol });
            }

            this.MarkSymbolReassignment(symbol, syntaxNode, cfgNode);
        }
示例#40
0
        /// <summary>
        /// Tries to get the list of potential methods that can override the given virtual call.
        /// If it cannot find such methods then it returns false.
        /// </summary>
        /// <param name="overriders">List of overrider methods</param>
        /// <param name="virtualCall">Virtual call</param>
        /// <param name="syntaxNode">SyntaxNode</param>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="originalMachine">Original machine</param>
        /// <param name="model">SemanticModel</param>
        /// <returns>Boolean value</returns>
        internal static bool TryGetPotentialMethodOverriders(out HashSet <MethodDeclarationSyntax> overriders,
                                                             InvocationExpressionSyntax virtualCall, SyntaxNode syntaxNode, ControlFlowGraphNode cfgNode,
                                                             ClassDeclarationSyntax originalMachine, SemanticModel model)
        {
            overriders = new HashSet <MethodDeclarationSyntax>();

            ISymbol          calleeSymbol = null;
            SimpleNameSyntax callee       = null;
            bool             isThis       = false;

            if (virtualCall.Expression is MemberAccessExpressionSyntax)
            {
                var expr       = virtualCall.Expression as MemberAccessExpressionSyntax;
                var identifier = expr.Expression.DescendantNodesAndSelf().
                                 OfType <IdentifierNameSyntax>().Last();
                calleeSymbol = model.GetSymbolInfo(identifier).Symbol;

                if (expr.Expression is ThisExpressionSyntax ||
                    Utilities.IsMachineType(identifier, model))
                {
                    callee = expr.Name;
                    isThis = true;
                }
            }
            else
            {
                callee = virtualCall.Expression as IdentifierNameSyntax;
                isThis = true;
            }

            if (isThis)
            {
                foreach (var nestedClass in originalMachine.ChildNodes().OfType <ClassDeclarationSyntax>())
                {
                    foreach (var method in nestedClass.ChildNodes().OfType <MethodDeclarationSyntax>())
                    {
                        if (method.Identifier.ToString().Equals(callee.Identifier.ToString()))
                        {
                            overriders.Add(method);
                            return(true);
                        }
                    }
                }

                foreach (var method in originalMachine.ChildNodes().OfType <MethodDeclarationSyntax>())
                {
                    if (method.Identifier.ToString().Equals(callee.Identifier.ToString()))
                    {
                        overriders.Add(method);
                        return(true);
                    }
                }

                return(false);
            }

            if (calleeSymbol == null)
            {
                return(false);
            }

            Dictionary <ISymbol, HashSet <ITypeSymbol> > objectTypeMap = null;

            if (!cfgNode.Summary.DataFlowMap.TryGetObjectTypeMapForSyntaxNode(
                    syntaxNode, cfgNode, out objectTypeMap))
            {
                return(false);
            }

            if (!objectTypeMap.ContainsKey(calleeSymbol))
            {
                return(false);
            }

            foreach (var objectType in objectTypeMap[calleeSymbol])
            {
                MethodDeclarationSyntax m = null;
                if (InheritanceAnalysis.TryGetMethodFromType(out m, objectType, virtualCall))
                {
                    overriders.Add(m);
                }
            }

            return(true);
        }
示例#41
0
        /// <summary>
        /// Tries to compute the 'gives_up' set of indexes for the given control flow graph node.
        /// If the node does not contain a 'Create' operation, then it returns false.
        /// </summary>
        /// <param name="cfgNode">ControlFlowGraphNode</param>
        /// <param name="summary">MethodSummary</param>
        /// <returns>Boolean value</returns>
        private static bool TryComputeGivesUpSetForCreateControlFlowGraphNode(ControlFlowGraphNode cfgNode,
                                                                              MethodSummary summary)
        {
            var createExpr = cfgNode.SyntaxNodes.First() as ExpressionStatementSyntax;

            if (createExpr == null)
            {
                return(false);
            }

            var create = createExpr.Expression as InvocationExpressionSyntax;

            if (create == null || !((create.Expression is MemberAccessExpressionSyntax) ||
                                    (create.Expression is IdentifierNameSyntax)))
            {
                return(false);
            }

            if (((create.Expression is MemberAccessExpressionSyntax) &&
                 !(create.Expression as MemberAccessExpressionSyntax).
                 Name.Identifier.ValueText.Equals("CreateMachine")) ||
                ((create.Expression is IdentifierNameSyntax) &&
                 !(create.Expression as IdentifierNameSyntax).
                 Identifier.ValueText.Equals("CreateMachine")))
            {
                return(false);
            }

            if (create.ArgumentList.Arguments.Count == 0)
            {
                return(true);
            }

            if (create.ArgumentList.Arguments[0].Expression is ObjectCreationExpressionSyntax)
            {
                var objCreation = create.ArgumentList.Arguments[0].Expression
                                  as ObjectCreationExpressionSyntax;
                foreach (var arg in objCreation.ArgumentList.Arguments)
                {
                    MethodSummaryAnalysis.ComputeGivesUpSetForArgument(arg.Expression,
                                                                       cfgNode, summary);
                }
            }
            else if (create.ArgumentList.Arguments[0].Expression is BinaryExpressionSyntax &&
                     create.ArgumentList.Arguments[0].Expression.IsKind(SyntaxKind.AsExpression))
            {
                var binExpr = create.ArgumentList.Arguments[0].Expression
                              as BinaryExpressionSyntax;
                if ((binExpr.Left is IdentifierNameSyntax) || (binExpr.Left is MemberAccessExpressionSyntax))
                {
                    MethodSummaryAnalysis.ComputeGivesUpSetForArgument(binExpr.Left,
                                                                       cfgNode, summary);
                }
                else if (binExpr.Left is InvocationExpressionSyntax)
                {
                    var invocation = binExpr.Left as InvocationExpressionSyntax;
                    for (int i = 1; i < invocation.ArgumentList.Arguments.Count; i++)
                    {
                        MethodSummaryAnalysis.ComputeGivesUpSetForArgument(invocation.ArgumentList.
                                                                           Arguments[i].Expression, cfgNode, summary);
                    }
                }
            }
            else if ((create.ArgumentList.Arguments[0].Expression is IdentifierNameSyntax) ||
                     (create.ArgumentList.Arguments[0].Expression is MemberAccessExpressionSyntax))
            {
                MethodSummaryAnalysis.ComputeGivesUpSetForArgument(create.ArgumentList.
                                                                   Arguments[0].Expression, cfgNode, summary);
            }

            return(true);
        }