private PointsToAbstractValue(PointsToAbstractValueKind kind, NullAbstractValue nullState) { Debug.Assert(kind != PointsToAbstractValueKind.Known); Debug.Assert(nullState != NullAbstractValue.Null); Locations = ImmutableHashSet <AbstractLocation> .Empty; Kind = kind; NullState = nullState; }
private PointsToAbstractValue(PointsToAbstractValueKind kind, NullAbstractValue nullState) { Debug.Assert(kind != PointsToAbstractValueKind.KnownLocations); Debug.Assert(kind != PointsToAbstractValueKind.KnownLValueCaptures); Locations = ImmutableHashSet <AbstractLocation> .Empty; LValueCapturedOperations = ImmutableHashSet <IOperation> .Empty; Kind = kind; NullState = nullState; }
private NullAbstractValue GetNullStateBasedOnInstanceOrReferenceValue(IOperation referenceOrInstance, ITypeSymbol operationType, NullAbstractValue defaultValue) { if (operationType.IsNonNullableValueType()) { return(NullAbstractValue.NotNull); } NullAbstractValue referenceOrInstanceValue = referenceOrInstance != null?GetNullAbstractValue(referenceOrInstance) : NullAbstractValue.NotNull; return(referenceOrInstanceValue == NullAbstractValue.Null ? NullAbstractValue.Null : defaultValue); }
private PointsToAbstractValue(ImmutableHashSet <AbstractLocation> locations, NullAbstractValue nullState) { Debug.Assert(!locations.IsEmpty); Debug.Assert(locations.All(location => !location.IsNull) || nullState != NullAbstractValue.NotNull); Debug.Assert(nullState != NullAbstractValue.Undefined); Debug.Assert(nullState != NullAbstractValue.Invalid); Locations = locations; Kind = PointsToAbstractValueKind.Known; NullState = nullState; }
private static bool IsValidValueForPredicateAnalysis(NullAbstractValue value) { switch (value) { case NullAbstractValue.Null: case NullAbstractValue.NotNull: return(true); default: return(false); } }
public override NullAbstractValue Merge(NullAbstractValue value1, NullAbstractValue value2) { NullAbstractValue result; if (value1 == NullAbstractValue.MaybeNull || value2 == NullAbstractValue.MaybeNull) { result = NullAbstractValue.MaybeNull; } else if (value1 is NullAbstractValue.Invalid or NullAbstractValue.Undefined) { result = value2; }
private PointsToAbstractValue(ImmutableHashSet <AbstractLocation> locations, NullAbstractValue nullState) { Debug.Assert(!locations.IsEmpty); Debug.Assert(locations.All(location => !location.IsNull) || nullState != NullAbstractValue.NotNull); Debug.Assert(nullState != NullAbstractValue.Undefined); Debug.Assert(nullState != NullAbstractValue.Invalid); Debug.Assert(!locations.Any(l => l.IsAnalysisEntityDefaultLocation && l.AnalysisEntity !.HasUnknownInstanceLocation)); Debug.Assert(locations.Count <= LocationThreshold); Locations = locations; LValueCapturedOperations = ImmutableHashSet <IOperation> .Empty; Kind = PointsToAbstractValueKind.KnownLocations; NullState = nullState; }
private PointsToAbstractValue GetValueBasedOnInstanceOrReferenceValue(IOperation referenceOrInstance, IOperation operation, PointsToAbstractValue defaultValue) { NullAbstractValue nullState = GetNullStateBasedOnInstanceOrReferenceValue(referenceOrInstance, operation.Type, defaultValue.NullState); switch (nullState) { case NullAbstractValue.NotNull: return(defaultValue.MakeNonNull(operation)); case NullAbstractValue.Null: return(defaultValue.MakeNull()); default: return(defaultValue); } }
private static NullAbstractValue NegatePredicateValue(NullAbstractValue value) { Debug.Assert(IsValidValueForPredicateAnalysis(value)); switch (value) { case NullAbstractValue.Null: return(NullAbstractValue.NotNull); case NullAbstractValue.NotNull: return(NullAbstractValue.Null); default: throw new InvalidProgramException(); } }
private bool SetValueForComparisonOperator(IOperation target, IOperation assignedValue, PointsToAnalysisData negatedCurrentAnalysisData, bool equals, ref PredicateValueKind predicateValueKind) { NullAbstractValue value = GetNullAbstractValue(assignedValue); if (IsValidValueForPredicateAnalysis(value) && AnalysisEntityFactory.TryCreate(target, out AnalysisEntity targetEntity)) { bool inferInCurrentAnalysisData = true; bool inferInNegatedCurrentAnalysisData = true; if (value == NullAbstractValue.NotNull) { // Comparison with a non-null value guarantees that we can infer result in only one of the branches. // For example, predicate "a == c", where we know 'c' is non-null, guarantees 'a' is non-null in CurrentAnalysisData, // but we cannot infer anything about nullness of 'a' in NegatedCurrentAnalysisData. if (equals) { inferInNegatedCurrentAnalysisData = false; } else { inferInCurrentAnalysisData = false; } } CopyAbstractValue copyValue = GetCopyAbstractValue(target); if (copyValue.Kind == CopyAbstractValueKind.Known) { Debug.Assert(copyValue.AnalysisEntities.Contains(targetEntity)); foreach (var analysisEntity in copyValue.AnalysisEntities) { SetValueFromPredicate(analysisEntity, value, negatedCurrentAnalysisData, equals, inferInCurrentAnalysisData, inferInNegatedCurrentAnalysisData, target, ref predicateValueKind); } } else { SetValueFromPredicate(targetEntity, value, negatedCurrentAnalysisData, equals, inferInCurrentAnalysisData, inferInNegatedCurrentAnalysisData, target, ref predicateValueKind); } return(true); } return(false); }
internal static PointsToAbstractValue Create(ImmutableHashSet <AbstractLocation> locations, NullAbstractValue nullState) { Debug.Assert(!locations.IsEmpty); if (locations.Count == 1) { var location = locations.Single(); if (location.IsNull) { return(NullLocation); } if (location.IsNoLocation) { return(NoLocation); } } else if (locations.Count > LocationThreshold) { return(nullState switch { NullAbstractValue.Null => UnknownNull, NullAbstractValue.NotNull => UnknownNotNull, _ => Unknown, });
public override int Compare(NullAbstractValue oldValue, NullAbstractValue newValue, bool assertMonotonicity) { return(Comparer <NullAbstractValue> .Default.Compare(oldValue, newValue)); }
public static PointsToAbstractValue Create(ImmutableHashSet <AbstractLocation> locations, NullAbstractValue nullState) { Debug.Assert(!locations.IsEmpty); if (locations.Count == 1) { var location = locations.Single(); if (location.IsNull) { return(NullLocation); } if (location.IsNoLocation) { return(NoLocation); } } return(new PointsToAbstractValue(locations, nullState)); }
internal static PointsToAbstractValue Create(ImmutableHashSet <AbstractLocation> locations, NullAbstractValue nullState) { Debug.Assert(!locations.IsEmpty); if (locations.Count == 1) { var location = locations.Single(); if (location.IsNull) { return(NullLocation); } if (location.IsNoLocation) { return(NoLocation); } } else if (locations.Count > LocationThreshold) { switch (nullState) { case NullAbstractValue.Null: return(UnknownNull); case NullAbstractValue.NotNull: return(UnknownNotNull); default: return(Unknown); } } return(new PointsToAbstractValue(locations, nullState)); }
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); } }
private static void SetAbstractValueFromPredicate(PointsToAnalysisData analysisData, AnalysisEntity analysisEntity, IOperation operation, NullAbstractValue nullState) { Debug.Assert(IsValidValueForPredicateAnalysis(nullState) || nullState == NullAbstractValue.Invalid); if (analysisData.TryGetValue(analysisEntity, out PointsToAbstractValue existingValue)) { PointsToAbstractValue newPointsToValue; switch (nullState) { case NullAbstractValue.Null: newPointsToValue = existingValue.MakeNull(); break; case NullAbstractValue.NotNull: newPointsToValue = existingValue.MakeNonNull(operation); break; case NullAbstractValue.Invalid: newPointsToValue = PointsToAbstractValue.Invalid; break; default: throw new InvalidProgramException(); } analysisData[analysisEntity] = newPointsToValue; } }