internal bool IsTrackedEntity(AnalysisEntity analysisEntity) => _trackedEntities.Contains(analysisEntity);
private static void AssertValidCopyAnalysisEntity(AnalysisEntity analysisEntity) { Debug.Assert(!analysisEntity.HasUnknownInstanceLocation, "Don't track entities if do not know about it's instance location"); }
protected override void SetAbstractValueForTupleElementAssignment(AnalysisEntity tupleElementEntity, IOperation assignedValueOperation, ParameterValidationAbstractValue assignedValue) { // We are only tracking default parameter locations. }
protected override CopyAbstractValue ComputeAnalysisValueForEscapedRefOrOutArgument(AnalysisEntity analysisEntity, IArgumentOperation operation, CopyAbstractValue defaultValue) { Debug.Assert(operation.Parameter.RefKind is RefKind.Ref or RefKind.Out); SetAbstractValue(analysisEntity, ValueDomain.UnknownOrMayBeValue); return(GetAbstractValue(analysisEntity)); }
protected override void StopTrackingEntity(AnalysisEntity analysisEntity, CopyAnalysisData analysisData) => StopTrackingEntity(analysisEntity, analysisData, GetDefaultCopyValue);
protected override void SetValueForParameterOnEntry(IParameterSymbol parameter, AnalysisEntity analysisEntity, ArgumentInfo <CopyAbstractValue>?assignedValue) { CopyAbstractValue copyValue; if (assignedValue != null) { var assignedEntities = assignedValue.Value.AnalysisEntities; if (assignedValue.AnalysisEntity != null && !assignedEntities.Contains(assignedValue.AnalysisEntity)) { assignedEntities = assignedEntities.Add(assignedValue.AnalysisEntity); } var newAnalysisEntities = assignedEntities; CopyAbstractValueKind newKind; if (assignedValue.Value.Kind.IsKnown()) { newKind = assignedValue.Value.Kind; } else if (assignedValue.AnalysisEntity == null || assignedValue.AnalysisEntity.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 = assignedValue.Value.AnalysisEntities.Count == newAnalysisEntities.Count ? assignedValue.Value : new CopyAbstractValue(newAnalysisEntities, newKind); } else { copyValue = GetDefaultCopyValue(analysisEntity); } SetAbstractValue(CurrentAnalysisData, analysisEntity, copyValue, TryGetAddressSharedCopyValue, initializingParameters: true); }
private CopyAbstractValue GetResetValue(AnalysisEntity analysisEntity) => GetResetValue(analysisEntity, GetAbstractValue(analysisEntity));
protected override void StopTrackingEntity(AnalysisEntity analysisEntity, TaintedDataAnalysisData analysisData) { analysisData.RemoveEntries(analysisEntity); }
protected override TaintedDataAbstractValue GetAbstractValue(AnalysisEntity analysisEntity) { return(this.CurrentAnalysisData.TryGetValue(analysisEntity, out TaintedDataAbstractValue value) ? value : TaintedDataAbstractValue.NotTainted); }
public static AbstractIndex Create(AnalysisEntity analysisEntity) => new AnalysisEntityBasedIndex(analysisEntity);
private static void SetAbstractValueCore(TaintedDataAnalysisData taintedAnalysisData, AnalysisEntity analysisEntity, TaintedDataAbstractValue value) => taintedAnalysisData.SetAbstractValue(analysisEntity, value);
protected override void SetAbstractValue(AnalysisEntity analysisEntity, NullAbstractValue value) => CurrentAnalysisData[analysisEntity] = value;
protected GlobalFlowStateDataFlowOperationVisitor(GlobalFlowStateAnalysisContext analysisContext, bool hasPredicatedGlobalState) : base(analysisContext) { _globalEntity = GetGlobalEntity(analysisContext); _hasPredicatedGlobalState = hasPredicatedGlobalState; }
public void UpdateAddressSharedEntitiesForParameter(IParameterSymbol parameter, AnalysisEntity analysisEntity, ArgumentInfo <TAbstractAnalysisValue>?assignedValue) { if (parameter.RefKind != RefKind.None && assignedValue?.AnalysisEntity != null) { var addressSharedEntities = ComputeAddressSharedEntities(); var isReferenceCopy = !addressSharedEntities.Any(a => a.Type.IsValueType); var copyValue = new CopyAbstractValue(addressSharedEntities, isReferenceCopy); foreach (var entity in copyValue.AnalysisEntities) { _addressSharedEntitiesBuilder[entity] = copyValue; } } ImmutableHashSet <AnalysisEntity> ComputeAddressSharedEntities() { RoslynDebug.Assert(assignedValue?.AnalysisEntity != null); var builder = PooledHashSet <AnalysisEntity> .GetInstance(); AddIfHasKnownInstanceLocation(analysisEntity, builder); AddIfHasKnownInstanceLocation(assignedValue.AnalysisEntity, builder); // We need to handle multiple ref/out parameters passed the same location. // For example, "M(ref a, ref a);" if (_addressSharedEntitiesBuilder.TryGetValue(assignedValue.AnalysisEntity, out var existingValue)) { foreach (var entity in existingValue.AnalysisEntities) { AddIfHasKnownInstanceLocation(entity, builder); } } // Also handle case where the passed in argument is also a ref/out parameter and has address shared entities. if (_addressSharedEntitiesBuilder.TryGetValue(analysisEntity, out existingValue)) { foreach (var entity in existingValue.AnalysisEntities) { AddIfHasKnownInstanceLocation(entity, builder); } } Debug.Assert(builder.All(e => !e.HasUnknownInstanceLocation)); return(builder.ToImmutableAndFree()); }
protected override void SetAbstractValue(AnalysisEntity analysisEntity, CopyAbstractValue value) { SetAbstractValue(CurrentAnalysisData, analysisEntity, value, TryGetAddressSharedCopyValue); }
protected override bool HasAbstractValue(AnalysisEntity analysisEntity) { return(this.CurrentAnalysisData.HasAbstractValue(analysisEntity)); }
private static void SetAbstractValue( CopyAnalysisData sourceCopyAnalysisData, CopyAnalysisData targetCopyAnalysisData, AnalysisEntity analysisEntity, CopyAbstractValue value, Func <AnalysisEntity, CopyAbstractValue?> tryGetAddressSharedCopyValue, SetCopyAbstractValuePredicateKind?fromPredicateKind, bool initializingParameters) { sourceCopyAnalysisData.AssertValidCopyAnalysisData(tryGetAddressSharedCopyValue, initializingParameters); targetCopyAnalysisData.AssertValidCopyAnalysisData(tryGetAddressSharedCopyValue, initializingParameters); Debug.Assert(ReferenceEquals(sourceCopyAnalysisData, targetCopyAnalysisData) || fromPredicateKind.HasValue); // Don't track entities if do not know about it's instance location. if (analysisEntity.HasUnknownInstanceLocation) { return; } if (!value.AnalysisEntities.IsEmpty) { var validEntities = value.AnalysisEntities.Where(entity => !entity.HasUnknownInstanceLocation).ToImmutableHashSet(); if (validEntities.Count < value.AnalysisEntities.Count) { value = !validEntities.IsEmpty ? new CopyAbstractValue(validEntities, value.Kind) : CopyAbstractValue.Unknown; } } // Handle updating the existing value if not setting the value from predicate analysis. if (!fromPredicateKind.HasValue && sourceCopyAnalysisData.TryGetValue(analysisEntity, out var existingValue)) { if (existingValue == value) { // Assigning the same value to the entity. Debug.Assert(existingValue.AnalysisEntities.Contains(analysisEntity)); return; } if (existingValue.AnalysisEntities.Count > 1) { CopyAbstractValue?addressSharedCopyValue = tryGetAddressSharedCopyValue(analysisEntity); if (addressSharedCopyValue == null || addressSharedCopyValue != existingValue) { CopyAbstractValue newValueForEntitiesInOldSet = addressSharedCopyValue != null? existingValue.WithEntitiesRemoved(addressSharedCopyValue.AnalysisEntities) : existingValue.WithEntityRemoved(analysisEntity); targetCopyAnalysisData.SetAbstactValueForEntities(newValueForEntitiesInOldSet, entityBeingAssigned: analysisEntity); } } } // Handle setting the new value. var newAnalysisEntities = value.AnalysisEntities.Add(analysisEntity); CopyAbstractValueKind newKind; if (newAnalysisEntities.Count == 1) { newKind = analysisEntity.Type.IsValueType ? CopyAbstractValueKind.KnownValueCopy : CopyAbstractValueKind.KnownReferenceCopy; } else { newKind = fromPredicateKind != SetCopyAbstractValuePredicateKind.ValueCompare && !analysisEntity.Type.IsValueType && value.Kind == CopyAbstractValueKind.KnownReferenceCopy ? CopyAbstractValueKind.KnownReferenceCopy : CopyAbstractValueKind.KnownValueCopy; } if (fromPredicateKind.HasValue) { // Also include the existing values for the analysis entity. if (sourceCopyAnalysisData.TryGetValue(analysisEntity, out existingValue)) { if (existingValue.Kind == CopyAbstractValueKind.Invalid) { return; } newAnalysisEntities = newAnalysisEntities.Union(existingValue.AnalysisEntities); newKind = newKind.MergeIfBothKnown(existingValue.Kind); } } else { // Include address shared entities, if any. CopyAbstractValue?addressSharedCopyValue = tryGetAddressSharedCopyValue(analysisEntity); if (addressSharedCopyValue != null) { newAnalysisEntities = newAnalysisEntities.Union(addressSharedCopyValue.AnalysisEntities); } } var newValue = new CopyAbstractValue(newAnalysisEntities, newKind); targetCopyAnalysisData.SetAbstactValueForEntities(newValue, entityBeingAssigned: analysisEntity); targetCopyAnalysisData.AssertValidCopyAnalysisData(tryGetAddressSharedCopyValue, initializingParameters); }
protected override void ResetAbstractValue(AnalysisEntity analysisEntity) => SetAbstractValue(analysisEntity, ValueDomain.UnknownOrMayBeValue);
protected override void EscapeValueForParameterOnExit(IParameterSymbol parameter, AnalysisEntity analysisEntity) { // Do not escape the copy value for parameter at exit. }
protected override void SetAbstractValue(AnalysisEntity analysisEntity, ValueContentAbstractValue value) => SetAbstractValue(CurrentAnalysisData, analysisEntity, value);
private CopyAbstractValue GetResetValue(AnalysisEntity analysisEntity, CopyAbstractValue currentValue) => currentValue.AnalysisEntities.Count > 1 ? GetDefaultCopyValue(analysisEntity) : currentValue;
private static void SetAbstractValue(ValueContentAnalysisData analysisData, AnalysisEntity analysisEntity, ValueContentAbstractValue value) { // PERF: Avoid creating an entry if the value is the default unknown value. if (value == ValueContentAbstractValue.MayBeContainsNonLiteralState && !analysisData.HasAbstractValue(analysisEntity)) { return; } analysisData.SetAbstractValue(analysisEntity, value); }
protected override bool HasAbstractValue(AnalysisEntity analysisEntity) => CurrentAnalysisData.HasAbstractValue(analysisEntity);
protected override void StopTrackingEntity(AnalysisEntity analysisEntity, ValueContentAnalysisData analysisData) => analysisData.RemoveEntries(analysisEntity);
protected override CopyAbstractValue GetAbstractValue(AnalysisEntity analysisEntity) => CurrentAnalysisData.TryGetValue(analysisEntity, out var value) ? value : CopyAbstractValue.Unknown;
protected override ValueContentAbstractValue GetAbstractValue(AnalysisEntity analysisEntity) => CurrentAnalysisData.TryGetValue(analysisEntity, out var value) ? value : ValueDomain.UnknownOrMayBeValue;
public override void SetAbstractValue(AnalysisEntity key, CopyAbstractValue value) { throw new NotSupportedException("Use SetAbstactValueForEntities API"); }
protected override void ResetAbstractValue(AnalysisEntity analysisEntity) => SetAbstractValue(analysisEntity, GetResetValue(analysisEntity));
protected override void EscapeValueForParameterPointsToLocationOnExit(IParameterSymbol parameter, AnalysisEntity analysisEntity, ImmutableHashSet <AbstractLocation> escapedLocations) { // Mark parameters as validated if they are non-null at all non-exception return paths and null at one of the unhandled throw operations. var notValidatedLocations = escapedLocations.Where(IsNotOrMaybeValidatedLocation); if (notValidatedLocations.Any()) { if (TryGetNullAbstractValueAtCurrentBlockEntry(analysisEntity, out NullAbstractValue nullAbstractValue) && nullAbstractValue == NullAbstractValue.NotNull && TryGetMergedNullAbstractValueAtUnhandledThrowOperationsInGraph(analysisEntity, out NullAbstractValue mergedValueAtUnhandledThrowOperations) && mergedValueAtUnhandledThrowOperations != NullAbstractValue.NotNull) { SetAbstractValue(notValidatedLocations, ParameterValidationAbstractValue.Validated); } } }
public ImmutableHashSet <AbstractLocation> GetEscapedAbstractLocations(AnalysisEntity analysisEntity) => GetEscapedAbstractLocations(analysisEntity, _escapedLocationsThroughEntitiesMap);