private void StopTrackingDataForEntity(AnalysisEntity analysisEntity, PooledHashSet <AnalysisEntity> allEntities)
 => StopTrackingDataForEntity(analysisEntity, CurrentAnalysisData, allEntities);
コード例 #2
0
 protected override void SetValueForParameterOnEntry(IParameterSymbol parameter, AnalysisEntity analysisEntity, ArgumentInfo <TAbstractAnalysisValue>?assignedValue)
 {
     // Only set the value for non-interprocedural case.
     // For interprocedural case, we have already initialized values for the underlying locations
     // of arguments from the input analysis data.
     Debug.Assert(Equals(analysisEntity.Symbol, parameter));
     if (DataFlowAnalysisContext.InterproceduralAnalysisData == null &&
         TryGetPointsToAbstractValueAtEntryBlockEnd(analysisEntity, out PointsToAbstractValue pointsToAbstractValue))
     {
         SetValueForParameterPointsToLocationOnEntry(parameter, pointsToAbstractValue);
     }
 }
コード例 #3
0
 public bool TryGetValue(AnalysisEntity key, out TValue value) => CoreAnalysisData.TryGetValue(key, out value);
コード例 #4
0
        protected override void EscapeValueForParameterOnExit(IParameterSymbol parameter, AnalysisEntity analysisEntity)
        {
            Debug.Assert(Equals(analysisEntity.Symbol, parameter));
            var escapedLocationsForParameter = GetEscapedLocations(analysisEntity);

            if (!escapedLocationsForParameter.IsEmpty)
            {
                EscapeValueForParameterPointsToLocationOnExit(parameter, analysisEntity, escapedLocationsForParameter);
            }
        }
コード例 #5
0
 protected override void ResetValueTypeInstanceAnalysisData(AnalysisEntity analysisEntity)
 {
 }
 protected sealed override bool HasPredicatedDataForEntity(TAnalysisData analysisData, AnalysisEntity predicatedEntity)
 => (analysisData as AnalysisEntityBasedPredicateAnalysisData <TAbstractAnalysisValue>)?.HasPredicatedDataForEntity(predicatedEntity) == true;
 protected sealed override PredicateValueKind ApplyPredicatedDataForEntity(TAnalysisData analysisData, AnalysisEntity predicatedEntity, bool trueData)
 => (analysisData as AnalysisEntityBasedPredicateAnalysisData <TAbstractAnalysisValue>)?.ApplyPredicatedDataForEntity(predicatedEntity, trueData) ?? PredicateValueKind.Unknown;
 protected abstract void SetAbstractValue(AnalysisEntity analysisEntity, TAbstractAnalysisValue value);
        /// <summary>
        /// Transfers the analysis data rooted from <paramref name="valueAnalysisEntityOpt"/> or <paramref name="assignedValueOperationOpt"/> to <paramref name="targetAnalysisEntity"/>, for a value type assignment operation.
        /// This involves transfer of data for of all <see cref="AnalysisEntity"/> instances that share the same <see cref="AnalysisEntity.InstanceLocation"/> as <paramref name="valueAnalysisEntityOpt"/> or allocation for the <paramref name="assignedValueOperationOpt"/>
        /// to all <see cref="AnalysisEntity"/> instances that share the same <see cref="AnalysisEntity.InstanceLocation"/> as <paramref name="targetAnalysisEntity"/>.
        /// </summary>
        private void TransferValueTypeInstanceAnalysisDataForAssignment(AnalysisEntity targetAnalysisEntity, AnalysisEntity valueAnalysisEntityOpt, IOperation assignedValueOperationOpt)
        {
            Debug.Assert(HasPointsToAnalysisResult);
            Debug.Assert(targetAnalysisEntity.Type.HasValueCopySemantics());

            IEnumerable <AnalysisEntity> dependentAnalysisEntities;

            if (valueAnalysisEntityOpt != null)
            {
                if (!valueAnalysisEntityOpt.Type.HasValueCopySemantics())
                {
                    // Unboxing conversion from assigned value (reference type) to target (value copy semantics).
                    // We do not need to transfer any data for such a case as there is no entity for unboxed value.
                    return;
                }

                dependentAnalysisEntities = GetChildAnalysisEntities(valueAnalysisEntityOpt);
            }
            else if (assignedValueOperationOpt != null)
            {
                // For allocations.
                PointsToAbstractValue newValueLocation = GetPointsToAbstractValue(assignedValueOperationOpt);
                dependentAnalysisEntities = GetChildAnalysisEntities(newValueLocation);
            }
            else
            {
                return;
            }

            foreach (AnalysisEntity dependentInstance in dependentAnalysisEntities)
            {
                // Clone the dependent instance but with with target as the root.
                AnalysisEntity newAnalysisEntity = AnalysisEntityFactory.CreateWithNewInstanceRoot(dependentInstance, targetAnalysisEntity);
                var            dependentValue    = GetAbstractValue(dependentInstance);
                SetAbstractValue(newAnalysisEntity, dependentValue);
            }
        }
 protected override void EscapeValueForParameterOnExit(IParameterSymbol parameter, AnalysisEntity analysisEntity)
 {
     Debug.Assert(Equals(analysisEntity.SymbolOpt, parameter));
     if (parameter.RefKind != RefKind.None)
     {
         SetAbstractValue(analysisEntity, GetDefaultValueForParameterOnExit(analysisEntity.Type));
     }
 }
 protected virtual TAbstractAnalysisValue GetDefaultValueForParameterOnEntry(IParameterSymbol parameter, AnalysisEntity analysisEntity) => ValueDomain.UnknownOrMayBeValue;
 protected override void SetValueForParameterOnEntry(IParameterSymbol parameter, AnalysisEntity analysisEntity, ArgumentInfo <TAbstractAnalysisValue> assignedValueOpt)
 {
     Debug.Assert(Equals(analysisEntity.SymbolOpt, parameter));
     if (assignedValueOpt != null)
     {
         SetAbstractValueForAssignment(analysisEntity, assignedValueOpt.Operation, assignedValueOpt.Value);
     }
     else
     {
         SetAbstractValue(analysisEntity, GetDefaultValueForParameterOnEntry(parameter, analysisEntity));
     }
 }
        private void SetAbstractValueForAssignment(AnalysisEntity targetAnalysisEntity, AnalysisEntity assignedValueEntityOpt, IOperation assignedValueOperationOpt, TAbstractAnalysisValue assignedValue)
        {
            // Value type and string type assignment has copy semantics.
            if (HasPointsToAnalysisResult &&
                targetAnalysisEntity.Type.HasValueCopySemantics())
            {
                // Reset the analysis values for analysis entities within the target instance.
                ResetValueTypeInstanceAnalysisData(targetAnalysisEntity);

                // Transfer the values of symbols from the assigned instance to the analysis entities in the target instance.
                TransferValueTypeInstanceAnalysisDataForAssignment(targetAnalysisEntity, assignedValueEntityOpt, assignedValueOperationOpt);
            }

            var addressSharedCopyValue = TryGetAddressSharedCopyValue(targetAnalysisEntity);

            if (addressSharedCopyValue != null)
            {
                Debug.Assert(addressSharedCopyValue.AnalysisEntities.Contains(targetAnalysisEntity));
                foreach (var entity in addressSharedCopyValue.AnalysisEntities)
                {
                    SetAbstractValue(entity, assignedValue);
                }
            }
            else
            {
                SetAbstractValue(targetAnalysisEntity, assignedValue);
            }
        }
 protected sealed override void StopTrackingDataForParameter(IParameterSymbol parameter, AnalysisEntity analysisEntity)
 => throw new InvalidOperationException("Unreachable");
 protected sealed override void StartTrackingPredicatedData(AnalysisEntity predicatedEntity, TAnalysisData truePredicateData, TAnalysisData falsePredicateData)
 => (CurrentAnalysisData as AnalysisEntityBasedPredicateAnalysisData <TAbstractAnalysisValue>)?.StartTrackingPredicatedData(
     predicatedEntity,
     truePredicateData as AnalysisEntityBasedPredicateAnalysisData <TAbstractAnalysisValue>,
     falsePredicateData as AnalysisEntityBasedPredicateAnalysisData <TAbstractAnalysisValue>);
 protected abstract void ResetAbstractValue(AnalysisEntity analysisEntity);
 protected sealed override void StopTrackingPredicatedData(AnalysisEntity predicatedEntity)
 => (CurrentAnalysisData as AnalysisEntityBasedPredicateAnalysisData <TAbstractAnalysisValue>)?.StopTrackingPredicatedData(predicatedEntity);
 protected abstract TAbstractAnalysisValue GetAbstractValue(AnalysisEntity analysisEntity);
 protected sealed override void TransferPredicatedData(AnalysisEntity fromEntity, AnalysisEntity toEntity)
 => (CurrentAnalysisData as AnalysisEntityBasedPredicateAnalysisData <TAbstractAnalysisValue>)?.TransferPredicatedData(fromEntity, toEntity);
 protected abstract bool HasAbstractValue(AnalysisEntity analysisEntity);
        protected virtual TAbstractAnalysisValue ComputeAnalysisValueForEscapedRefOrOutArgument(AnalysisEntity analysisEntity, IArgumentOperation operation, TAbstractAnalysisValue defaultValue)
        {
            Debug.Assert(operation.Parameter.RefKind == RefKind.Ref || operation.Parameter.RefKind == RefKind.Out);

            return(defaultValue);
        }
 protected abstract void StopTrackingEntity(AnalysisEntity analysisEntity, TAnalysisData analysisData);
コード例 #23
0
 protected override void StopTrackingDataForParameter(IParameterSymbol parameter, AnalysisEntity analysisEntity)
 {
     Debug.Assert(DataFlowAnalysisContext.InterproceduralAnalysisData != null);
     if (parameter.RefKind == RefKind.None)
     {
         foreach (var location in analysisEntity.InstanceLocation.Locations)
         {
             StopTrackingAbstractValue(location);
         }
     }
 }
 private ImmutableHashSet <AnalysisEntity> GetChildAnalysisEntities(AnalysisEntity analysisEntity)
 {
     return(GetChildAnalysisEntities(analysisEntity.InstanceLocation, entity => IsChildAnalysisEntity(entity, analysisEntity)));
 }
コード例 #25
0
 protected abstract void EscapeValueForParameterPointsToLocationOnExit(IParameterSymbol parameter, AnalysisEntity analysisEntity, ImmutableHashSet <AbstractLocation> escapedLocations);
 protected static bool IsChildAnalysisEntity(AnalysisEntity entity, AnalysisEntity ancestorEntity)
 {
     return((!ancestorEntity.Type.HasValueCopySemantics() || entity.HasAncestor(ancestorEntity)) &&
            IsChildAnalysisEntity(entity, ancestorEntity.InstanceLocation));
 }
コード例 #27
0
 public bool HasAbstractValue(AnalysisEntity analysisEntity) => CoreAnalysisData.ContainsKey(analysisEntity);
 protected static bool IsChildAnalysisEntity(AnalysisEntity entity, PointsToAbstractValue instanceLocation)
 {
     return(entity.InstanceLocation.Equals(instanceLocation) && entity.IsChildOrInstanceMember);
 }
コード例 #29
0
#pragma warning disable CA1043 // Use Integral Or String Argument For Indexers
        public TValue this[AnalysisEntity key] => CoreAnalysisData[key];
コード例 #30
0
        public override DictionaryAnalysisData <AnalysisEntity, TValue> Merge(DictionaryAnalysisData <AnalysisEntity, TValue> map1, DictionaryAnalysisData <AnalysisEntity, TValue> map2)
        {
            AssertValidAnalysisData(map1);
            AssertValidAnalysisData(map2);

            var resultMap = new DictionaryAnalysisData <AnalysisEntity, TValue>();

            using var newKeys = PooledHashSet <AnalysisEntity> .GetInstance();

            using var valuesToMergeBuilder = ArrayBuilder <TValue> .GetInstance(5);

            var map2LookupIgnoringInstanceLocation = map2.Keys.Where(IsAnalysisEntityForFieldOrProperty)
                                                     .ToLookup(entity => entity.EqualsIgnoringInstanceLocationId);

            foreach (var entry1 in map1)
            {
                AnalysisEntity key1   = entry1.Key;
                TValue         value1 = entry1.Value;

                if (map2LookupIgnoringInstanceLocation.Count > 0 && IsAnalysisEntityForFieldOrProperty(key1))
                {
                    var equivalentKeys2 = map2LookupIgnoringInstanceLocation[key1.EqualsIgnoringInstanceLocationId];
                    if (!equivalentKeys2.Any())
                    {
                        TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1);
                        Debug.Assert(!map2.ContainsKey(key1));
                        Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0);
                        AddNewEntryToResultMap(key1, mergedValue);
                        continue;
                    }

                    foreach (AnalysisEntity key2 in equivalentKeys2)
                    {
                        // Confirm that key2 and key1 are indeed EqualsIgnoringInstanceLocation
                        // This ensures that we handle hash code clashes of EqualsIgnoringInstanceLocationId.
                        if (!key1.EqualsIgnoringInstanceLocation(key2))
                        {
                            continue;
                        }

                        TValue value2 = map2[key2];

                        valuesToMergeBuilder.Clear();
                        valuesToMergeBuilder.Add(value1);
                        valuesToMergeBuilder.Add(value2);

                        if (key1.InstanceLocation.Equals(key2.InstanceLocation))
                        {
                            var mergedValue = GetMergedValue(valuesToMergeBuilder);
                            AddNewEntryToResultMap(key1, mergedValue);
                        }
                        else
                        {
                            if (key1.Symbol == null || !Equals(key1.Symbol, key2.Symbol))
                            {
                                // PERF: Do not add a new key-value pair to the resultMap for unrelated entities or non-symbol based entities.
                                continue;
                            }

                            AnalysisEntity mergedKey = key1.WithMergedInstanceLocation(key2);

                            var isExistingKeyInInput  = false;
                            var isExistingKeyInResult = false;
                            if (resultMap.TryGetValue(mergedKey, out var existingValue))
                            {
                                valuesToMergeBuilder.Add(existingValue);
                                isExistingKeyInResult = true;
                            }

                            if (map1.TryGetValue(mergedKey, out existingValue))
                            {
                                valuesToMergeBuilder.Add(existingValue);
                                isExistingKeyInInput = true;
                            }

                            if (map2.TryGetValue(mergedKey, out existingValue))
                            {
                                valuesToMergeBuilder.Add(existingValue);
                                isExistingKeyInInput = true;
                            }

                            var isCandidateToBeSkipped = !isExistingKeyInInput && !isExistingKeyInResult;
                            if (isCandidateToBeSkipped && CanSkipNewEntity(mergedKey))
                            {
                                // PERF: Do not add a new key-value pair to the resultMap if the key is not reachable from tracked entities and PointsTo values.
                                continue;
                            }

                            var mergedValue = GetMergedValue(valuesToMergeBuilder);

                            Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0);
                            Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0);

                            if (isCandidateToBeSkipped && CanSkipNewEntry(mergedKey, mergedValue))
                            {
                                // PERF: Do not add a new key-value pair to the resultMap if the value can be skipped.
                                continue;
                            }

                            if (!isExistingKeyInInput)
                            {
                                newKeys.Add(mergedKey);
                            }

                            AddNewEntryToResultMap(mergedKey, mergedValue, isNewKey: !isExistingKeyInInput);
                        }
                    }
                }
                else if (map2.TryGetValue(key1, out var value2))
                {
                    TValue mergedValue = ValueDomain.Merge(value1, value2);
                    Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0);
                    Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0);
                    AddNewEntryToResultMap(key1, mergedValue);
                    continue;
                }

                if (!resultMap.ContainsKey(key1))
                {
                    TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key1, value1);
                    Debug.Assert(ValueDomain.Compare(value1, mergedValue) <= 0);
                    AddNewEntryToResultMap(key1, mergedValue);
                }
            }

            foreach (var kvp in map2)
            {
                var key2   = kvp.Key;
                var value2 = kvp.Value;
                if (!resultMap.ContainsKey(key2))
                {
                    TValue mergedValue = GetMergedValueForEntityPresentInOneMap(key2, value2);
                    Debug.Assert(ValueDomain.Compare(value2, mergedValue) <= 0);
                    AddNewEntryToResultMap(key2, mergedValue);
                }
            }

            foreach (var newKey in newKeys)
            {
                Debug.Assert(!map1.ContainsKey(newKey));
                Debug.Assert(!map2.ContainsKey(newKey));
                var value = resultMap[newKey];
                if (ReferenceEquals(value, GetDefaultValue(newKey)))
                {
                    resultMap.Remove(newKey);
                }
                else
                {
                    OnNewMergedValue(value);
                }
            }

            Debug.Assert(Compare(map1, resultMap) <= 0);
            Debug.Assert(Compare(map2, resultMap) <= 0);
            AssertValidAnalysisData(resultMap);

            return(resultMap);