private static void Analyze(CSharpSyntaxNode declarationBody, ISymbol symbol,
                                    Action <CSharpExplodedGraph, SyntaxNodeAnalysisContext> analyze, SyntaxNodeAnalysisContext context)
        {
            if (declarationBody == null ||
                declarationBody.ContainsDiagnostics)
            {
                return;
            }

            if (!CSharpControlFlowGraph.TryGet(declarationBody, context.SemanticModel, out var cfg))
            {
                return;
            }

            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, symbol, context.SemanticModel);

            try
            {
                var explodedGraph = new CSharpExplodedGraph(cfg, symbol, context.SemanticModel, lva);
                analyze(explodedGraph, context);
            }
            catch (Exception e)
            {
                // Roslyn/MSBuild is currently cutting exception message at the end of the line instead
                // of displaying the full message. As a workaround, we replace the line ending with ' ## '.
                // See https://github.com/dotnet/roslyn/issues/1455 and https://github.com/dotnet/roslyn/issues/24346
                var sb = new StringBuilder();
                sb.AppendLine($"Error processing method: {symbol?.Name ?? "{unknown}"}");
                sb.AppendLine($"Method file: {declarationBody.GetLocation()?.GetLineSpan().Path ?? "{unknown}"}");
                sb.AppendLine($"Method line: {declarationBody.GetLocation()?.GetLineSpan().StartLinePosition.ToString() ?? "{unknown}"}");
                sb.AppendLine($"Inner exception: {e.ToString()}");

                throw new SymbolicExecutionException(sb.ToString().Replace(Environment.NewLine, " ## "), e);
            }
        }
Beispiel #2
0
        private static void CheckForNullDereference(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var methodSymbol = context.SemanticModel.GetSymbolInfo(context.Node).Symbol
                               ?? context.SemanticModel.GetDeclaredSymbol(context.Node);

            if (!methodSymbol.IsPubliclyAccessible())
            {
                return;
            }

            var nullPointerCheck = new NullPointerDereference.NullPointerCheck(explodedGraph);

            explodedGraph.AddExplodedGraphCheck(nullPointerCheck);

            var identifiers = new HashSet <IdentifierNameSyntax>();

            void memberAccessingHandler(object sender, MemberAccessingEventArgs args) => CollectMemberAccesses(args, identifiers, context.SemanticModel);

            nullPointerCheck.MemberAccessing += memberAccessingHandler;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                nullPointerCheck.MemberAccessing -= memberAccessingHandler;
            }

            foreach (var identifier in identifiers)
            {
                context.ReportDiagnosticWhenActive(Diagnostic.Create(rule, identifier.GetLocation(), identifier.Identifier.ValueText));
            }
        }
        private static void CheckForRedundantConditions(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var conditionTrue  = new HashSet <SyntaxNode>();
            var conditionFalse = new HashSet <SyntaxNode>();

            void collectConditions(object sender, ConditionEvaluatedEventArgs args) =>
            CollectConditions(args, conditionTrue, conditionFalse, context.SemanticModel);

            void explorationEnded(object sender, EventArgs args) => Enumerable.Empty <Diagnostic>()
            .Union(conditionTrue
                   .Except(conditionFalse)
                   .Where(c => !IsConditionOfLoopWithBreak((ExpressionSyntax)c))
                   .Where(c => !IsInsideCatchOrFinallyBlock(c))
                   .Select(node => GetDiagnostics(node, true)))
            .Union(conditionFalse
                   .Except(conditionTrue)
                   .Where(c => !IsInsideCatchOrFinallyBlock(c))
                   .Select(node => GetDiagnostics(node, false)))
            .ToList()
            .ForEach(d => context.ReportDiagnosticWhenActive(d));

            explodedGraph.ExplorationEnded   += explorationEnded;
            explodedGraph.ConditionEvaluated += collectConditions;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                explodedGraph.ExplorationEnded   -= explorationEnded;
                explodedGraph.ConditionEvaluated -= collectConditions;
            }
        }
            public AnalysisContext(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
            {
                this.explodedGraph = explodedGraph;
                this.context       = context;

                explodedGraph.InstructionProcessed += InstructionProcessed;
                explodedGraph.ConditionEvaluated   += ConditionEvaluatedHandler;
            }
Beispiel #5
0
            public AnalysisContext(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
            {
                if (!GetMethodSymbol(context).IsPubliclyAccessible())
                {
                    return;
                }

                syntaxNodeAnalysisContext         = context;
                nullPointerCheck                  = explodedGraph.NullPointerCheck;
                nullPointerCheck.MemberAccessing += MemberAccessingHandler;
            }
            public AnalysisContext(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
            {
                if (!GetMethodSymbol(context).IsPubliclyAccessible())
                {
                    return;
                }

                this.syntaxNodeAnalysisContext = context;

                this.nullPointerCheck = new NullPointerDereference.NullPointerCheck(explodedGraph);
                this.nullPointerCheck.MemberAccessing += MemberAccessingHandler;
                explodedGraph.AddExplodedGraphCheck(this.nullPointerCheck);
            }
        private static void CheckForRedundantConditions(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context)
        {
            var conditionTrue     = new HashSet <SyntaxNode>();
            var conditionFalse    = new HashSet <SyntaxNode>();
            var hasYieldStatement = false;

            void instructionProcessed(object sender, InstructionProcessedEventArgs args)
            {
                hasYieldStatement = hasYieldStatement || IsYieldNode(args.ProgramPoint.Block);
            }

            void collectConditions(object sender, ConditionEvaluatedEventArgs args) =>
            CollectConditions(args, conditionTrue, conditionFalse, context.SemanticModel);

            void explorationEnded(object sender, EventArgs args)
            {
                // Do not raise issue in generator functions (See #1295)
                if (hasYieldStatement)
                {
                    return;
                }
                Enumerable.Empty <Diagnostic>()
                .Union(conditionTrue
                       .Except(conditionFalse)
                       .Where(c => !IsConditionOfLoopWithBreak((ExpressionSyntax)c))
                       .Where(c => !IsInsideCatchOrFinallyBlock(c))
                       .Select(node => GetDiagnostics(node, true)))
                .Union(conditionFalse
                       .Except(conditionTrue)
                       .Where(c => !IsInsideCatchOrFinallyBlock(c))
                       .Select(node => GetDiagnostics(node, false)))
                .ToList()
                .ForEach(d => context.ReportDiagnosticWhenActive(d));
            }

            explodedGraph.InstructionProcessed += instructionProcessed;
            explodedGraph.ExplorationEnded     += explorationEnded;
            explodedGraph.ConditionEvaluated   += collectConditions;

            try
            {
                explodedGraph.Walk();
            }
            finally
            {
                explodedGraph.InstructionProcessed -= instructionProcessed;
                explodedGraph.ExplorationEnded     -= explorationEnded;
                explodedGraph.ConditionEvaluated   -= collectConditions;
            }
        }
Beispiel #8
0
        private static void Analyze(CSharpSyntaxNode declarationBody, ISymbol symbol,
                                    Action <CSharpExplodedGraph, SyntaxNodeAnalysisContext> analyze, SyntaxNodeAnalysisContext context)
        {
            if (declarationBody == null ||
                declarationBody.ContainsDiagnostics)
            {
                return;
            }

            if (!CSharpControlFlowGraph.TryGet(declarationBody, context.SemanticModel, out var cfg))
            {
                return;
            }

            var lva = CSharpLiveVariableAnalysis.Analyze(cfg, symbol, context.SemanticModel);

            var explodedGraph = new CSharpExplodedGraph(cfg, symbol, context.SemanticModel, lva);

            analyze(explodedGraph, context);
        }
 public ISymbolicExecutionAnalysisContext AddChecks(CSharpExplodedGraph explodedGraph, SyntaxNodeAnalysisContext context) =>
 new AnalysisContext(explodedGraph, context);