コード例 #1
0
        /// <summary>
        /// Returns the data flow map for the given control flow graph.
        /// </summary>
        /// <param name="summary">MethodSummary</param>
        /// <param name="context">AnalysisContext</param>
        /// <returns>DataFlowMap</returns>
        internal static DataFlowMap AnalyseControlFlowGraph(MethodSummary summary, AnalysisContext context)
        {
            var dataFlowMap = new DataFlowMap();
            var model = context.Compilation.GetSemanticModel(summary.Method.SyntaxTree);

            foreach (var param in summary.Method.ParameterList.Parameters)
            {
                var declType = model.GetTypeInfo(param.Type).Type;
                if (context.IsTypeAllowedToBeSend(declType) ||
                    context.IsMachineType(declType, model))
                {
                    continue;
                }

                var paramSymbol = model.GetDeclaredSymbol(param);
                dataFlowMap.MapRefToSymbol(paramSymbol, paramSymbol, summary.Method.ParameterList,
                    summary.Node, false);
            }

            DataFlowAnalysis.AnalyseControlFlowGraphNode(summary.Node, summary.Node,
                summary.Method.ParameterList, dataFlowMap, model, context);

            return dataFlowMap;
        }
コード例 #2
0
ファイル: DataFlowAnalysis.cs プロジェクト: huangpf/PSharp
        /// <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);
            }
        }
コード例 #3
0
ファイル: DataFlowAnalysis.cs プロジェクト: huangpf/PSharp
        /// <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);
            }
        }
コード例 #4
0
ファイル: DataFlowAnalysis.cs プロジェクト: huangpf/PSharp
        /// <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);
                        }
                    }
                }
            }
        }