Ejemplo n.º 1
0
 protected override void ResetCurrentAnalysisData(DisposeAnalysisData newAnalysisDataOpt = null)
 {
     // Reset the current analysis data, while ensuring that we don't violate the monotonicity, i.e. we cannot remove any existing key from currentAnalysisData.
     if (newAnalysisDataOpt == null)
     {
         // Just set the values for existing keys to ValueDomain.UnknownOrMayBeValue.
         var keys = CurrentAnalysisData.Keys.ToImmutableArray();
         foreach (var key in keys)
         {
             SetAbstractValue(key, ValueDomain.UnknownOrMayBeValue);
         }
     }
     else
     {
         // Merge the values from current and new analysis data.
         var keys = CurrentAnalysisData.Keys.Concat(newAnalysisDataOpt.Keys).ToImmutableHashSet();
         foreach (var key in keys)
         {
             var value1      = CurrentAnalysisData.TryGetValue(key, out var currentValue) ? currentValue : ValueDomain.Bottom;
             var value2      = newAnalysisDataOpt.TryGetValue(key, out var newValue) ? newValue : ValueDomain.Bottom;
             var mergedValue = ValueDomain.Merge(value1, value2);
             SetAbstractValue(key, mergedValue);
         }
     }
 }
            private void SetValueFromPredicate(
                AnalysisEntity key,
                NullAbstractValue value,
                NullAnalysisData negatedCurrentAnalysisData,
                bool equals,
                bool inferInCurrentAnalysisData,
                bool inferInNegatedCurrentAnalysisData,
                ref PredicateValueKind predicateValueKind)
            {
                var negatedValue = NegatePredicateValue(value);

                if (CurrentAnalysisData.TryGetValue(key, out NullAbstractValue existingValue) &&
                    IsValidValueForPredicateAnalysis(existingValue) &&
                    (existingValue == NullAbstractValue.Null || value == NullAbstractValue.Null))
                {
                    if (value == existingValue && equals ||
                        negatedValue == existingValue && !equals)
                    {
                        predicateValueKind         = PredicateValueKind.AlwaysTrue;
                        negatedValue               = NullAbstractValue.Invalid;
                        inferInCurrentAnalysisData = false;
                    }

                    if (negatedValue == existingValue && equals ||
                        value == existingValue && !equals)
                    {
                        predicateValueKind = PredicateValueKind.AlwaysFalse;
                        value = NullAbstractValue.Invalid;
                        inferInNegatedCurrentAnalysisData = false;
                    }
                }

                if (!equals)
                {
                    if (value != NullAbstractValue.Invalid && negatedValue != NullAbstractValue.Invalid)
                    {
                        var temp = value;
                        value        = negatedValue;
                        negatedValue = temp;
                    }
                }

                if (inferInCurrentAnalysisData)
                {
                    // Set value for the CurrentAnalysisData.
                    SetAbstractValue(CurrentAnalysisData, key, value);
                }

                if (inferInNegatedCurrentAnalysisData)
                {
                    // Set negated value for the NegatedCurrentAnalysisData.
                    SetAbstractValue(negatedCurrentAnalysisData, key, negatedValue);
                }
            }
Ejemplo n.º 3
0
 protected override CopyAbstractValue ComputeAnalysisValueForReferenceOperation(IOperation operation, CopyAbstractValue defaultValue)
 {
     if (AnalysisEntityFactory.TryCreate(operation, out AnalysisEntity analysisEntity))
     {
         return(CurrentAnalysisData.TryGetValue(analysisEntity, out CopyAbstractValue value) ? value : GetDefaultCopyValue(analysisEntity));
     }
     else
     {
         return(defaultValue);
     }
 }
 private void HandlePossibleEscapingOperation(IOperation escapingOperation, ImmutableHashSet <AbstractLocation> escapedLocations)
 {
     foreach (AbstractLocation escapedLocation in escapedLocations)
     {
         if (CurrentAnalysisData.TryGetValue(escapedLocation, out DisposeAbstractValue currentDisposeValue) &&
             currentDisposeValue.Kind != DisposeAbstractValueKind.Unknown)
         {
             DisposeAbstractValue newDisposeValue = currentDisposeValue.WithNewEscapingOperation(escapingOperation);
             SetAbstractValue(escapedLocation, newDisposeValue);
         }
     }
 }
Ejemplo n.º 5
0
            protected override void UpdateValuesForAnalysisData(CopyAnalysisData targetAnalysisData)
            {
                // We need to trim the copy values to only include the entities that are existing keys in targetAnalysisData.
                var processedEntities = PooledHashSet <AnalysisEntity> .GetInstance();

                var builder = ArrayBuilder <AnalysisEntity> .GetInstance(targetAnalysisData.CoreAnalysisData.Count);

                try
                {
                    builder.AddRange(targetAnalysisData.CoreAnalysisData.Keys);
                    for (int i = 0; i < builder.Count; i++)
                    {
                        var key = builder[i];
                        if (!processedEntities.Add(key))
                        {
                            continue;
                        }

                        if (CurrentAnalysisData.TryGetValue(key, out var newValue))
                        {
                            var existingValue = targetAnalysisData[key];
                            if (newValue.AnalysisEntities.Count == 1)
                            {
                                if (existingValue.AnalysisEntities.Count == 1)
                                {
                                    continue;
                                }
                            }
                            else if (newValue.AnalysisEntities.Count > 1)
                            {
                                var entitiesToExclude = newValue.AnalysisEntities.Where(e => !targetAnalysisData.HasAbstractValue(e));
                                if (entitiesToExclude.Any())
                                {
                                    newValue = newValue.WithEntitiesRemoved(entitiesToExclude);
                                }
                            }

                            if (newValue != existingValue)
                            {
                                targetAnalysisData.SetAbstactValueForEntities(newValue, entityBeingAssignedOpt: null);
                            }

                            processedEntities.AddRange(newValue.AnalysisEntities);
                        }
                    }
                }
                finally
                {
                    processedEntities.Free();
                    builder.Free();
                }
            }
            private void HandlePossibleInvalidatingOperation(IOperation invalidatedInstance)
            {
                PointsToAbstractValue instanceLocation = GetPointsToAbstractValue(invalidatedInstance);

                foreach (AbstractLocation location in instanceLocation.Locations)
                {
                    if (CurrentAnalysisData.TryGetValue(location, out DisposeAbstractValue currentDisposeValue) &&
                        currentDisposeValue.Kind != DisposeAbstractValueKind.NotDisposable)
                    {
                        SetAbstractValue(location, DisposeAbstractValue.Invalid);
                    }
                }
            }
Ejemplo n.º 7
0
            private void HandlePossibleEscapingOperation(IOperation escapingOperation, IOperation escapedInstance)
            {
                PointsToAbstractValue pointsToValue = GetPointsToAbstractValue(escapedInstance);

                foreach (AbstractLocation location in pointsToValue.Locations)
                {
                    if (CurrentAnalysisData.TryGetValue(location, out DisposeAbstractValue currentDisposeValue))
                    {
                        DisposeAbstractValue newDisposeValue = currentDisposeValue.WithNewEscapingOperation(escapingOperation);
                        SetAbstractValue(location, newDisposeValue);
                    }
                }
            }
Ejemplo n.º 8
0
            protected override PointsToAbstractValue GetAbstractValue(AnalysisEntity analysisEntity)
            {
                if (!ShouldBeTracked(analysisEntity.Type))
                {
                    return(PointsToAbstractValue.NoLocation);
                }

                if (!CurrentAnalysisData.TryGetValue(analysisEntity, out var value))
                {
                    value = _defaultPointsToValueGenerator.GetOrCreateDefaultValue(analysisEntity);
                }

                return(value);
            }
            protected override PredicateValueKind SetValueForEqualsOrNotEqualsComparisonOperator(IBinaryOperation operation, CopyAnalysisData negatedCurrentAnalysisData, bool equals)
            {
                Debug.Assert(operation.IsComparisonOperator());

                if (GetCopyAbstractValue(operation.LeftOperand).Kind != CopyAbstractValueKind.Unknown &&
                    GetCopyAbstractValue(operation.RightOperand).Kind != CopyAbstractValueKind.Unknown &&
                    AnalysisEntityFactory.TryCreate(operation.LeftOperand, out AnalysisEntity leftEntity) &&
                    AnalysisEntityFactory.TryCreate(operation.RightOperand, out AnalysisEntity rightEntity))
                {
                    var predicateKind = PredicateValueKind.Unknown;
                    if (!CurrentAnalysisData.TryGetValue(rightEntity, out CopyAbstractValue rightValue))
                    {
                        rightValue = new CopyAbstractValue(rightEntity);
                    }
                    else if (rightValue.AnalysisEntities.Contains(leftEntity))
                    {
                        // We have "a == b && a == b" or "a == b && a != b"
                        // For both cases, condition on right is always true or always false and redundant.
                        predicateKind = equals ? PredicateValueKind.AlwaysTrue : PredicateValueKind.AlwaysFalse;
                    }
                    else if (negatedCurrentAnalysisData.TryGetValue(rightEntity, out var negatedRightValue) &&
                             negatedRightValue.AnalysisEntities.Contains(leftEntity))
                    {
                        // We have "a == b || a == b" or "a == b || a != b"
                        // For both cases, condition on right is always true or always false and redundant.
                        predicateKind = equals ? PredicateValueKind.AlwaysFalse : PredicateValueKind.AlwaysTrue;
                    }

                    if (predicateKind != PredicateValueKind.Unknown)
                    {
                        if (!equals)
                        {
                            // "a == b && a != b" or "a == b || a != b"
                            // CurrentAnalysisData and negatedCurrentAnalysisData are both unknown values.
                            foreach (var entity in rightValue.AnalysisEntities)
                            {
                                SetAbstractValue(CurrentAnalysisData, entity, CopyAbstractValue.Invalid, fromPredicate: true);
                                SetAbstractValue(negatedCurrentAnalysisData, entity, CopyAbstractValue.Invalid, fromPredicate: true);
                            }
                        }

                        return(predicateKind);
                    }

                    var analysisData = equals ? CurrentAnalysisData : negatedCurrentAnalysisData;
                    SetAbstractValue(analysisData, leftEntity, rightValue, fromPredicate: true);
                }

                return(PredicateValueKind.Unknown);
            }
Ejemplo n.º 10
0
            protected override PointsToAbstractValue GetAbstractValue(AnalysisEntity analysisEntity)
            {
                if (analysisEntity.Type.HasValueCopySemantics())
                {
                    return(PointsToAbstractValue.NoLocation);
                }

                if (!CurrentAnalysisData.TryGetValue(analysisEntity, out var value))
                {
                    value = analysisEntity.SymbolOpt?.Kind == SymbolKind.Local ?
                            ValueDomain.Bottom :
                            ValueDomain.UnknownOrMayBeValue;
                }

                return(value);
            }
Ejemplo n.º 11
0
            protected override void SetValueForParameterOnEntry(IParameterSymbol parameter, AnalysisEntity analysisEntity, ArgumentInfo <CopyAbstractValue> assignedValueOpt)
            {
                CopyAbstractValue copyValue;

                if (assignedValueOpt != null)
                {
                    var assignedEntities = assignedValueOpt.Value.AnalysisEntities;
                    if (assignedValueOpt.AnalysisEntityOpt != null && !assignedEntities.Contains(assignedValueOpt.AnalysisEntityOpt))
                    {
                        assignedEntities = assignedEntities.Add(assignedValueOpt.AnalysisEntityOpt);
                    }

                    var newAnalysisEntities = assignedEntities;
                    CopyAbstractValueKind newKind;
                    if (assignedValueOpt.Value.Kind.IsKnown())
                    {
                        newKind = assignedValueOpt.Value.Kind;
                    }
                    else if (assignedValueOpt.AnalysisEntityOpt == null || assignedValueOpt.AnalysisEntityOpt.Type.IsValueType)
                    {
                        newKind = CopyAbstractValueKind.KnownValueCopy;
                    }
                    else
                    {
                        newKind = CopyAbstractValueKind.KnownReferenceCopy;
                    }

                    foreach (var entity in assignedEntities)
                    {
                        if (CurrentAnalysisData.TryGetValue(entity, out var existingValue))
                        {
                            newAnalysisEntities = newAnalysisEntities.Union(existingValue.AnalysisEntities);
                            newKind             = newKind.MergeIfBothKnown(existingValue.Kind);
                        }
                    }

                    copyValue = assignedValueOpt.Value.AnalysisEntities.Count == newAnalysisEntities.Count ?
                                assignedValueOpt.Value :
                                new CopyAbstractValue(newAnalysisEntities, newKind);
                }
                else
                {
                    copyValue = GetDefaultCopyValue(analysisEntity);
                }

                SetAbstractValue(CurrentAnalysisData, analysisEntity, copyValue, TryGetAddressSharedCopyValue, initializingParameters: true);
            }
            private void SetValueForComparisonOperator(IOperation target, IOperation assignedValue, bool equals, ref PredicateValueKind predicateValueKind, ValueContentAnalysisData targetAnalysisData)
            {
                ValueContentAbstractValue currentAssignedValue = GetCachedAbstractValue(assignedValue);

                if (currentAssignedValue.IsLiteralState &&
                    AnalysisEntityFactory.TryCreate(target, out AnalysisEntity targetEntity))
                {
                    if (CurrentAnalysisData.TryGetValue(targetEntity, out ValueContentAbstractValue existingTargetValue) &&
                        existingTargetValue.IsLiteralState)
                    {
                        var newValue = currentAssignedValue.IntersectLiteralValues(existingTargetValue);
                        if (newValue.NonLiteralState == ValueContainsNonLiteralState.Invalid)
                        {
                            predicateValueKind = equals ? PredicateValueKind.AlwaysFalse : PredicateValueKind.AlwaysTrue;
                        }
                        else if (predicateValueKind != PredicateValueKind.AlwaysFalse &&
                                 newValue.IsLiteralState &&
                                 newValue.LiteralValues.Count == 1 &&
                                 currentAssignedValue.LiteralValues.Count == 1 &&
                                 existingTargetValue.LiteralValues.Count == 1)
                        {
                            predicateValueKind = equals ? PredicateValueKind.AlwaysTrue : PredicateValueKind.AlwaysFalse;
                        }

                        currentAssignedValue = newValue;
                    }

                    if (equals)
                    {
                        CopyAbstractValue copyValue = GetCopyAbstractValue(target);
                        if (copyValue.Kind.IsKnown())
                        {
                            // https://github.com/dotnet/roslyn-analyzers/issues/2106 tracks enabling the below assert.
                            //Debug.Assert(copyValue.AnalysisEntities.Contains(targetEntity));
                            foreach (var analysisEntity in copyValue.AnalysisEntities)
                            {
                                SetAbstractValue(targetAnalysisData, analysisEntity, currentAssignedValue);
                            }
                        }
                        else
                        {
                            SetAbstractValue(targetAnalysisData, targetEntity, currentAssignedValue);
                        }
                    }
                }
            }
            private void HandleDisposingOperation(IOperation disposingOperation, IOperation disposedInstance)
            {
                if (disposedInstance.Type?.IsDisposable(IDisposableNamedType) == false)
                {
                    return;
                }

                PointsToAbstractValue instanceLocation = GetPointsToAbstractValue(disposedInstance);

                foreach (AbstractLocation location in instanceLocation.Locations)
                {
                    if (CurrentAnalysisData.TryGetValue(location, out DisposeAbstractValue currentDisposeValue))
                    {
                        DisposeAbstractValue disposeValue = currentDisposeValue.WithNewDisposingOperation(disposingOperation);
                        SetAbstractValue(location, disposeValue);
                    }
                }
            }
Ejemplo n.º 14
0
            private void HandlePossibleEscapingOperation(IOperation escapingOperation, IOperation escapedInstance)
            {
                if (escapedInstance?.Type == null ||
                    !escapedInstance.Type.IsDisposable(_iDisposable))
                {
                    return;
                }

                PointsToAbstractValue instanceLocation = GetPointsToAbstractValue(escapedInstance);

                foreach (AbstractLocation location in instanceLocation.Locations)
                {
                    if (CurrentAnalysisData.TryGetValue(location, out DisposeAbstractValue currentDisposeValue))
                    {
                        DisposeAbstractValue newDisposeValue = currentDisposeValue.WithNewEscapingOperation(escapingOperation);
                        SetAbstractValue(location, newDisposeValue);
                    }
                }
            }
 protected override ValueContentAbstractValue GetAbstractValue(AnalysisEntity analysisEntity)
 => CurrentAnalysisData.TryGetValue(analysisEntity, out var value) ? value : ValueDomain.UnknownOrMayBeValue;
 private bool IsNotOrMaybeValidatedLocation(AbstractLocation location) =>
 CurrentAnalysisData.TryGetValue(location, out var value) &&
 (value == ParameterValidationAbstractValue.NotValidated || value == ParameterValidationAbstractValue.MayBeValidated);
 protected override ParameterValidationAbstractValue GetAbstractValue(AbstractLocation location)
 => CurrentAnalysisData.TryGetValue(location, out var value) ? value : ValueDomain.Bottom;
 protected override DisposeAbstractValue GetAbstractValue(AbstractLocation location) => CurrentAnalysisData.TryGetValue(location, out var value) ? value : ValueDomain.UnknownOrMayBeValue;
Ejemplo n.º 19
0
 protected override NullAbstractValue GetAbstractValue(ISymbol symbol) =>
 CurrentAnalysisData.TryGetValue(symbol, out var value) ? value : UnknownOrMayBeValue;
Ejemplo n.º 20
0
 protected override CopyAbstractValue GetAbstractValue(AnalysisEntity analysisEntity) => CurrentAnalysisData.TryGetValue(analysisEntity, out var value) ? value : CopyAbstractValue.Unknown;
Ejemplo n.º 21
0
            private void SetValueFromPredicate(
                AnalysisEntity key,
                NullAbstractValue value,
                PointsToAnalysisData negatedCurrentAnalysisData,
                bool equals,
                bool inferInCurrentAnalysisData,
                bool inferInNegatedCurrentAnalysisData,
                IOperation target,
                ref PredicateValueKind predicateValueKind)
            {
                // Compute the negated value.
                NullAbstractValue negatedValue = NegatePredicateValue(value);

                // Check if the key already has an existing "Null" or "NotNull" NullState that would make the condition always true or false.
                // If so, set the predicateValueKind to always true/false, set the value in branch that can never be taken to NullAbstractValue.Invalid
                // and turn off value inference in one of the branch.
                if (CurrentAnalysisData.TryGetValue(key, out PointsToAbstractValue existingPointsToValue))
                {
                    NullAbstractValue existingNullValue = existingPointsToValue.NullState;
                    if (IsValidValueForPredicateAnalysis(existingNullValue) &&
                        (existingNullValue == NullAbstractValue.Null || value == NullAbstractValue.Null))
                    {
                        if (value == existingNullValue && equals ||
                            negatedValue == existingNullValue && !equals)
                        {
                            predicateValueKind         = PredicateValueKind.AlwaysTrue;
                            negatedValue               = NullAbstractValue.Invalid;
                            inferInCurrentAnalysisData = false;
                        }

                        if (negatedValue == existingNullValue && equals ||
                            value == existingNullValue && !equals)
                        {
                            predicateValueKind = PredicateValueKind.AlwaysFalse;
                            value = NullAbstractValue.Invalid;
                            inferInNegatedCurrentAnalysisData = false;
                        }
                    }
                }

                // Swap value and negatedValue if we are processing not-equals operator.
                if (!equals)
                {
                    if (value != NullAbstractValue.Invalid && negatedValue != NullAbstractValue.Invalid)
                    {
                        var temp = value;
                        value        = negatedValue;
                        negatedValue = temp;
                    }
                }

                if (inferInCurrentAnalysisData)
                {
                    // Set value for the CurrentAnalysisData.
                    SetAbstractValueFromPredicate(CurrentAnalysisData, key, target, value);
                }

                if (inferInNegatedCurrentAnalysisData)
                {
                    // Set negated value for the NegatedCurrentAnalysisData.
                    SetAbstractValueFromPredicate(negatedCurrentAnalysisData, key, target, negatedValue);
                }
            }