Beispiel #1
0
        protected DataFlowOperationVisitor(
            AbstractValueDomain <TAbstractAnalysisValue> valueDomain,
            ISymbol owningSymbol,
            bool pessimisticAnalysis,
            DataFlowAnalysisResult <NullBlockAnalysisResult, NullAbstractValue> nullAnalysisResultOpt,
            DataFlowAnalysisResult <PointsToBlockAnalysisResult, PointsToAbstractValue> pointsToAnalysisResultOpt)
        {
            Debug.Assert(owningSymbol != null);
            Debug.Assert(owningSymbol.Kind == SymbolKind.Method ||
                         owningSymbol.Kind == SymbolKind.Field ||
                         owningSymbol.Kind == SymbolKind.Property ||
                         owningSymbol.Kind == SymbolKind.Event);

            ValueDomain                   = valueDomain;
            OwningSymbol                  = owningSymbol;
            PessimisticAnalysis           = pessimisticAnalysis;
            _nullAnalysisResultOpt        = nullAnalysisResultOpt;
            _pointsToAnalysisResultOpt    = pointsToAnalysisResultOpt;
            _valueCacheBuilder            = ImmutableDictionary.CreateBuilder <IOperation, TAbstractAnalysisValue>();
            _pendingArgumentsToReset      = new List <IArgumentOperation>();
            ThisOrMePointsToAbstractValue = GetThisOrMeInstancePointsToValue(owningSymbol.ContainingType);

            AnalysisEntityFactory = new AnalysisEntityFactory(
                (pointsToAnalysisResultOpt != null || IsPointsToAnalysis) ?
                GetPointsToAbstractValue :
                (Func <IOperation, PointsToAbstractValue>)null,
                owningSymbol.ContainingType);
        }
 protected AbstractLocationDataFlowOperationVisitor(
     AbstractValueDomain <TAbstractAnalysisValue> valueDomain,
     INamedTypeSymbol containingTypeSymbol,
     DataFlowAnalysisResult <NullAnalysis.NullBlockAnalysisResult, NullAnalysis.NullAbstractValue> nullAnalysisResultOpt,
     DataFlowAnalysisResult <PointsToAnalysis.PointsToBlockAnalysisResult, PointsToAnalysis.PointsToAbstractValue> pointsToAnalysisResultOpt)
     : base(valueDomain, containingTypeSymbol, nullAnalysisResultOpt, pointsToAnalysisResultOpt)
 {
 }
Beispiel #3
0
 protected AnalysisEntityDataFlowOperationVisitor(
     AbstractValueDomain <TAbstractAnalysisValue> valueDomain,
     ISymbol owningSymbol,
     bool pessimisticAnalysis,
     DataFlowAnalysisResult <NullBlockAnalysisResult, NullAbstractValue> nullAnalysisResultOpt,
     DataFlowAnalysisResult <PointsToBlockAnalysisResult, PointsToAbstractValue> pointsToAnalysisResultOpt)
     : base(valueDomain, owningSymbol, pessimisticAnalysis, nullAnalysisResultOpt, pointsToAnalysisResultOpt)
 {
 }
 protected AnalysisEntityDataFlowOperationVisitor(
     AbstractValueDomain <TAbstractAnalysisValue> valueDomain,
     ISymbol owningSymbol,
     WellKnownTypeProvider wellKnownTypeProvider,
     bool pessimisticAnalysis,
     bool predicateAnalysis,
     DataFlowAnalysisResult <CopyBlockAnalysisResult, CopyAbstractValue> copyAnalysisResultOpt,
     DataFlowAnalysisResult <PointsToBlockAnalysisResult, PointsToAbstractValue> pointsToAnalysisResultOpt)
     : base(valueDomain, owningSymbol, wellKnownTypeProvider, pessimisticAnalysis, predicateAnalysis,
            copyAnalysisResultOpt, pointsToAnalysisResultOpt)
 {
 }
 protected DataFlowOperationVisitor(
     AbstractValueDomain <TAbstractAnalysisValue> valueDomain,
     INamedTypeSymbol containingTypeSymbol,
     DataFlowAnalysisResult <NullBlockAnalysisResult, NullAbstractValue> nullAnalysisResultOpt,
     DataFlowAnalysisResult <PointsToBlockAnalysisResult, PointsToAbstractValue> pointsToAnalysisResultOpt)
 {
     ValueDomain                   = valueDomain;
     _nullAnalysisResultOpt        = nullAnalysisResultOpt;
     _pointsToAnalysisResultOpt    = pointsToAnalysisResultOpt;
     _valueCacheBuilder            = ImmutableDictionary.CreateBuilder <IOperation, TAbstractAnalysisValue>();
     _pendingArgumentsToReset      = new List <IArgumentOperation>();
     ThisOrMePointsToAbstractValue = GetThisOrMeInstancePointsToValue(containingTypeSymbol);
 }
 protected AnalysisEntityDataFlowOperationVisitor(
     AbstractValueDomain <TAbstractAnalysisValue> valueDomain,
     INamedTypeSymbol containingTypeSymbol,
     DataFlowAnalysisResult <NullBlockAnalysisResult, NullAbstractValue> nullAnalysisResultOpt,
     DataFlowAnalysisResult <PointsToBlockAnalysisResult, PointsToAbstractValue> pointsToAnalysisResultOpt)
     : base(valueDomain, containingTypeSymbol, nullAnalysisResultOpt, pointsToAnalysisResultOpt)
 {
     AnalysisEntityFactory = new AnalysisEntityFactory(
         (pointsToAnalysisResultOpt != null || IsPointsToAnalysis) ?
         GetPointsToAbstractValue :
         (Func <IOperation, PointsToAbstractValue>)null,
         containingTypeSymbol);
 }
Beispiel #7
0
 protected AbstractLocationDataFlowOperationVisitor(
     AbstractValueDomain <TAbstractAnalysisValue> valueDomain,
     ISymbol owningSymbol,
     WellKnownTypeProvider wellKnownTypeProvider,
     bool pessimisticAnalysis,
     bool predicateAnalysis,
     DataFlowAnalysisResult <NullAnalysis.NullBlockAnalysisResult, NullAnalysis.NullAbstractValue> nullAnalysisResultOpt,
     DataFlowAnalysisResult <CopyAnalysis.CopyBlockAnalysisResult, CopyAnalysis.CopyAbstractValue> copyAnalysisResultOpt,
     DataFlowAnalysisResult <PointsToBlockAnalysisResult, PointsToAbstractValue> pointsToAnalysisResultOpt)
     : base(valueDomain, owningSymbol, wellKnownTypeProvider, pessimisticAnalysis, predicateAnalysis,
            nullAnalysisResultOpt, copyAnalysisResultOpt, pointsToAnalysisResultOpt)
 {
     Debug.Assert(pointsToAnalysisResultOpt != null);
 }
        protected DataFlowAnalysisResult <TAnalysisResult, TAbstractAnalysisValue> GetOrComputeResultCore(
            ControlFlowGraph cfg,
            bool cacheResult,
            DataFlowAnalysisResult <TAnalysisResult, TAbstractAnalysisValue> seedResultOpt = null)
        {
            if (!cacheResult)
            {
                return(Run(cfg, seedResultOpt));
            }

            var analysisResultsMap = s_resultCache.GetOrCreateValue(cfg.RootOperation);

            return(analysisResultsMap.GetOrAdd(OperationVisitor, _ => Run(cfg, seedResultOpt)));
        }
        private DataFlowAnalysisResult <TAnalysisResult, TAbstractAnalysisValue> Run(ControlFlowGraph cfg, DataFlowAnalysisResult <TAnalysisResult, TAbstractAnalysisValue> seedResultOpt)
        {
            var resultBuilder = new DataFlowAnalysisResultBuilder <TAnalysisData>();

            // Add each basic block to the result.
            foreach (var block in cfg.Blocks)
            {
                resultBuilder.Add(block);
            }

            var worklist = new Queue <BasicBlock>();
            var pendingBlocksNeedingAtLeastOnePass = new HashSet <BasicBlock>(cfg.Blocks);
            var entry = GetEntry(cfg);

            // Are we computing the analysis data from scratch?
            if (seedResultOpt == null)
            {
                // Initialize the input of the initial block
                // with the default abstract value of the domain.
                UpdateInput(resultBuilder, entry, AnalysisDomain.Bottom);
            }
            else
            {
                // Initialize the input and output of every block
                // with the previously computed value.
                foreach (var block in cfg.Blocks)
                {
                    UpdateInput(resultBuilder, block, GetInputData(seedResultOpt[block]));
                }
            }

            // Add the block to the worklist.
            worklist.Enqueue(entry);

            while (worklist.Count > 0 || pendingBlocksNeedingAtLeastOnePass.Count > 0)
            {
                // Get the next block to process
                // and its associated result.
                var block = worklist.Count > 0 ? worklist.Dequeue() : pendingBlocksNeedingAtLeastOnePass.ElementAt(0);
                var needsAtLeastOnePass = pendingBlocksNeedingAtLeastOnePass.Remove(block);

                // Get the outputs of all predecessor blocks of the current block.
                var inputs = GetPredecessors(block).Select(b => GetOutput(resultBuilder[b]));

                // Merge all the outputs to get the new input of the current block.
                var input = AnalysisDomain.Merge(inputs);

                // Merge might return one of the original input values if only one of them is a valid non-null value.
                if (inputs.Any(i => ReferenceEquals(input, i)))
                {
                    input = AnalysisDomain.Clone(input);
                }

                // Temporary workaround due to lack of *real* CFG
                // TODO: Remove the below if statement once we move to compiler's CFG
                // https://github.com/dotnet/roslyn-analyzers/issues/1567
                if (block.Kind == BasicBlockKind.Exit &&
                    OperationVisitor.MergedAnalysisDataAtReturnStatements != null)
                {
                    input = AnalysisDomain.Merge(input, OperationVisitor.MergedAnalysisDataAtReturnStatements);
                }

                // Compare the previous input with the new input.
                if (!needsAtLeastOnePass)
                {
                    int compare = AnalysisDomain.Compare(GetInput(resultBuilder[block]), input);

                    // The newly computed abstract values for each basic block
                    // must be always greater or equal than the previous value
                    // to ensure termination.
                    Debug.Assert(compare <= 0, "The newly computed abstract value must be greater or equal than the previous one.");

                    // Is old input value >= new input value
                    if (compare >= 0)
                    {
                        continue;
                    }
                }

                // The newly computed value is greater than the previous value,
                // so we need to update the current block result's
                // input values with the new ones.
                UpdateInput(resultBuilder, block, AnalysisDomain.Clone(input));

                // Flow the new input through the block to get a new output.
                var output = Flow(OperationVisitor, block, input);

                // Compare the previous output with the new output.
                if (!needsAtLeastOnePass)
                {
                    int compare = AnalysisDomain.Compare(GetOutput(resultBuilder[block]), output);

                    // The newly computed abstract values for each basic block
                    // must be always greater or equal than the previous value
                    // to ensure termination.
                    Debug.Assert(compare <= 0, "The newly computed abstract value must be greater or equal than the previous one.");

                    // Is old output value >= new output value ?
                    if (compare >= 0)
                    {
                        continue;
                    }
                }

                // The newly computed value is greater than the previous value,
                // so we need to update the current block result's
                // output values with the new ones.
                UpdateOutput(resultBuilder, block, output);

                // Since the new output value is different than the previous one,
                // we need to propagate it to all the successor blocks of the current block.
                EnqueueRange(worklist, GetSuccessors(block));
            }

            return(resultBuilder.ToResult(ToResult, OperationVisitor.GetStateMap(),
                                          OperationVisitor.GetPredicateValueKindMap(), OperationVisitor.GetMergedDataForUnhandledThrowOperations(),
                                          cfg, OperationVisitor.ValueDomain.UnknownOrMayBeValue));
        }
 protected DataFlowOperationVisitor(AbstractDomain <TAbstractAnalysisValue> valueDomain, DataFlowAnalysisResult <NullBlockAnalysisResult, NullAbstractValue> nullAnalysisResultOpt)
 {
     ValueDomain            = valueDomain;
     _nullAnalysisResultOpt = nullAnalysisResultOpt;
     _valueCacheBuilder     = ImmutableDictionary.CreateBuilder <IOperation, TAbstractAnalysisValue>();
 }